Current File : //home/tradevaly/www/node_modules/restructure/src/Pointer.js |
// Generated by CoffeeScript 1.7.1
(function() {
var Pointer, VoidPointer, utils;
utils = require('./utils');
Pointer = (function() {
function Pointer(offsetType, type, options) {
var _base, _base1, _base2, _base3;
this.offsetType = offsetType;
this.type = type;
this.options = options != null ? options : {};
if (this.type === 'void') {
this.type = null;
}
if ((_base = this.options).type == null) {
_base.type = 'local';
}
if ((_base1 = this.options).allowNull == null) {
_base1.allowNull = true;
}
if ((_base2 = this.options).nullValue == null) {
_base2.nullValue = 0;
}
if ((_base3 = this.options).lazy == null) {
_base3.lazy = false;
}
if (this.options.relativeTo) {
this.relativeToGetter = new Function('ctx', "return ctx." + this.options.relativeTo);
}
}
Pointer.prototype.decode = function(stream, ctx) {
var c, decodeValue, offset, ptr, relative, val;
offset = this.offsetType.decode(stream, ctx);
if (offset === this.options.nullValue && this.options.allowNull) {
return null;
}
relative = (function() {
switch (this.options.type) {
case 'local':
return ctx._startOffset;
case 'immediate':
return stream.pos - this.offsetType.size();
case 'parent':
return ctx.parent._startOffset;
default:
c = ctx;
while (c.parent) {
c = c.parent;
}
return c._startOffset || 0;
}
}).call(this);
if (this.options.relativeTo) {
relative += this.relativeToGetter(ctx);
}
ptr = offset + relative;
if (this.type != null) {
val = null;
decodeValue = (function(_this) {
return function() {
var pos;
if (val != null) {
return val;
}
pos = stream.pos;
stream.pos = ptr;
val = _this.type.decode(stream, ctx);
stream.pos = pos;
return val;
};
})(this);
if (this.options.lazy) {
return new utils.PropertyDescriptor({
get: decodeValue
});
}
return decodeValue();
} else {
return ptr;
}
};
Pointer.prototype.size = function(val, ctx) {
var parent, type;
parent = ctx;
switch (this.options.type) {
case 'local':
case 'immediate':
break;
case 'parent':
ctx = ctx.parent;
break;
default:
while (ctx.parent) {
ctx = ctx.parent;
}
}
type = this.type;
if (type == null) {
if (!(val instanceof VoidPointer)) {
throw new Error("Must be a VoidPointer");
}
type = val.type;
val = val.value;
}
if (val && ctx) {
ctx.pointerSize += type.size(val, parent);
}
return this.offsetType.size();
};
Pointer.prototype.encode = function(stream, val, ctx) {
var parent, relative, type;
parent = ctx;
if (val == null) {
this.offsetType.encode(stream, this.options.nullValue);
return;
}
switch (this.options.type) {
case 'local':
relative = ctx.startOffset;
break;
case 'immediate':
relative = stream.pos + this.offsetType.size(val, parent);
break;
case 'parent':
ctx = ctx.parent;
relative = ctx.startOffset;
break;
default:
relative = 0;
while (ctx.parent) {
ctx = ctx.parent;
}
}
if (this.options.relativeTo) {
relative += this.relativeToGetter(parent.val);
}
this.offsetType.encode(stream, ctx.pointerOffset - relative);
type = this.type;
if (type == null) {
if (!(val instanceof VoidPointer)) {
throw new Error("Must be a VoidPointer");
}
type = val.type;
val = val.value;
}
ctx.pointers.push({
type: type,
val: val,
parent: parent
});
return ctx.pointerOffset += type.size(val, parent);
};
return Pointer;
})();
VoidPointer = (function() {
function VoidPointer(type, value) {
this.type = type;
this.value = value;
}
return VoidPointer;
})();
exports.Pointer = Pointer;
exports.VoidPointer = VoidPointer;
}).call(this);