UNPKG

binary-format

Version:

Two-way custom binary seralization

189 lines (166 loc) 5.33 kB
(function () { if (typeof jDataView === 'undefined' && typeof require !== 'undefined') { jDataView = require('jDataView'); } // Extend code from underscorejs (modified for fast inheritance using prototypes) function inherit(obj) { if ('create' in Object) { obj = Object.create(obj); } else { function ClonedObject() {} ClonedObject.prototype = obj; obj = new ClonedObject(); } for (var i = 1; i < arguments.length; ++i) { var source = arguments[i]; for (var prop in source) { if (source[prop] !== undefined) { obj[prop] = source[prop]; } } } return obj; } function jPrinter(view, structure) { if (!(this instanceof arguments.callee)) { throw new Error("Constructor may not be called as a function"); } if (!(view instanceof jDataView)) { view = new jDataView(view, undefined, undefined, true); } this.view = view; this.view.seek(0); this._bitShift = 0; this.structure = inherit(jPrinter.prototype.structure, structure); } function toInt(val) { return val instanceof Function ? val.call(this) : val; } jPrinter.prototype.structure = { uint8: function (data) { this.view.writeUint8(data); }, uint16: function (data) { this.view.writeUint16(data); }, uint32: function (data) { this.view.writeUint32(data); }, int8: function (data) { this.view.writeInt8(data); }, int16: function (data) { this.view.writeInt16(data); }, int32: function (data) { this.view.writeInt32(data); }, float32: function (data) { this.view.writeFloat32(data); }, float64: function (data) { this.view.writeFloat64(data); }, char: function (data) { this.view.writeChar(data); }, string: function (length, data) { this.view.writeString(data); }, array: function (type, length, data) { var arr = Array.prototype.slice.call(arguments, 2); for (var i = 0; i < arr.length; ++i) { this.parse(type, arr[i]); } }, seek: function (position, block) { position = toInt.call(this, position); if (block instanceof Function) { var old_position = this.view.tell(); this.view.seek(position); var result = block.call(this); this.view.seek(old_position); return result; } else { return this.view.seek(position); } }, tell: function () { return this.view.tell(); }, skip: function (offset) { offset = toInt.call(this, offset); this.view.seek(this.view.tell() + offset); return offset; }, if: function (predicate) { if (predicate instanceof Function ? predicate.call(this) : predicate) { return this.parse.apply(this, Array.prototype.slice.call(arguments, 1)); } } }; jPrinter.prototype.seek = jPrinter.prototype.structure.seek; jPrinter.prototype.tell = jPrinter.prototype.structure.tell; jPrinter.prototype.skip = jPrinter.prototype.structure.skip; jPrinter.prototype.parse = function (structure, currentValue) { /*if (typeof structure === 'number') { var fieldValue = 0, bitSize = structure; if (this._bitShift < 0) { var byteShift = this._bitShift >> 3; // Math.floor(_bitShift / 8) this.skip(byteShift); this._bitShift &= 7; // _bitShift + 8 * Math.floor(_bitShift / 8) } if (this._bitShift > 0 && bitSize >= 8 - this._bitShift) { fieldValue = this.view.getUint8() & ~(-1 << (8 - this._bitShift)); bitSize -= 8 - this._bitShift; this._bitShift = 0; } while (bitSize >= 8) { fieldValue = this.view.getUint8() | (fieldValue << 8); bitSize -= 8; } if (bitSize > 0) { fieldValue = ((this.view.getUint8() >>> (8 - (this._bitShift + bitSize))) & ~(-1 << bitSize)) | (fieldValue << bitSize); this._bitShift += bitSize - 8; // passing negative value for next pass } }*/ // ['string', 256] means structure['string'](256) if (structure instanceof Array) { var key = structure[0]; if (!(key in this.structure)) { throw new Error("Missing structure for `" + key + "`"); } return this.parse.apply(this, [this.structure[key]].concat(structure.slice(1), currentValue)); return fieldValue; } // f, 1, 2 means f(1, 2) if (structure instanceof Function) { return structure.apply(this, Array.prototype.slice.call(arguments, 1)); } // 'int32', ... is a shortcut for ['int32', ...] if (typeof structure === 'string') { structure = Array.prototype.slice.call(arguments); } // ['string', 256] means structure['string'](256) if (structure instanceof Array) { var key = structure[0]; if (!(key in this.structure)) { throw new Error("Missing structure for `" + key + "`"); } return this.parse.apply(this, [this.structure[key]].concat(structure.slice(1), currentValue)); } // {key: val} means {key: parse(val)} if (typeof structure === 'object') { var output = {}, current = this.current; this.current = output; for (var key in structure) { var value = this.parse(structure[key], currentValue[key]); // skipping undefined call results (useful for 'if' statement) //if (value !== undefined) { // output[key] = value; //} } this.current = current; return output; } throw new Error("Unknown structure type `" + structure + "`"); }; var all; if (typeof self !== 'undefined') { all = self; } else if (typeof window !== 'undefined') { all = window; } else if (typeof global !== 'undefined') { all = global; } // Browser + Web Worker all.jPrinter = jPrinter; // NodeJS + NPM if (typeof module !== 'undefined') { module.exports = jPrinter; } })();