// 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);