UNPKG

structjs

Version:

**Structjs** allows mapping of contiguously allocated binary data to JavaScript objects for both Node.js and the Browser.

77 lines (71 loc) 2.66 kB
var utils = require('../utils') , StructReference = require('./reference') , StructArray = require('./array') var StructStorage = module.exports = function(path, opts) { this.path = path if (opts instanceof StructReference) opts = { offset: opts } opts = opts || {} Object.defineProperties(this, { _offset: { value: opts.offset, writable: true } }) } StructStorage.prototype.read = function read(view, offset) { var parent = read.caller.parent , shift = this.offsetFor(parent) || offset !function traverse(path, definition, target) { var step = path.shift(), type = definition[step] traverse.parent = target if (!path.length) { target[step] = type.read(view, shift) } else if (type instanceof StructArray) { target[step].forEach(function(target) { traverse(path.concat([]), type.struct._definition, target) }) } else { traverse(path, type, target[step]) } }(this.path.split('.'), parent._definition, parent) } StructStorage.prototype.write = function write(view, offset, _, relativeOffset) { var parent = write.caller.parent, shift = 0 this.setOffset(relativeOffset, parent) !function traverse(path, definition, target) { var step = path.shift(), type = definition[step] traverse.parent = target if (!path.length) { type.setOffset(shift, target) var value = target[step], target = type.prototype ? target[step] : target type.write(view, offset, value, relativeOffset) shift += type.lengthFor(target, true) * type.sizeFor(target, true) } else if (type instanceof StructArray) { target[step].forEach(function(target) { traverse(path.concat([]), type.struct._definition, target) }) } else { traverse(path, type, target[step]) } }(this.path.split('.'), parent._definition, parent) } StructStorage.prototype.lengthFor = function() { return 1 } StructStorage.prototype.sizeFor = function(parent, writing) { var size = 0 !function traverse(path, definition, target) { var step = path.shift(), type = definition[step] traverse.parent = target if (!path.length) { if (type.prototype) target = target[step] size += type.lengthFor(target, writing) * type.sizeFor(target, writing) } else if (type instanceof StructArray) { target[step].forEach(function(target) { traverse(path.concat([]), type.struct._definition, target) }) } else { traverse(path, type, target[step]) } }(this.path.split('.'), parent._definition, parent) return size } utils.methodsFor(StructStorage.prototype, '_offset', 'offsetFor', 'setOffset')