UNPKG

structjs

Version:

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

2 lines 15.9 kB
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.Struct=e():"undefined"!=typeof global?global.Struct=e():"undefined"!=typeof self&&(self.Struct=e())}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var StructNumber=require("./types/number"),StructString=require("./types/string"),StructHash=require("./types/hash"),StructArray=require("./types/array"),StructReference=require("./types/reference"),StructStorage=require("./types/storage"),utils=require("./utils");var Struct=module.exports=function(definition,opts){if(!opts)opts={};var StructType=function(values){Object.defineProperties(this,{_view:{writable:true,value:null},_offset:{writable:true,value:null},_definition:{writable:false,value:definition}});for(var key in values){if(key in definition)this[key]=cloneValue(values[key])}var self=this;extensions.forEach(function(extension){for(var key in values){if(key in extension.extension)self[key]=cloneValue(values[key])}})};Object.defineProperties(StructType,{_offset:{writable:true,value:null},_definition:{writable:false,value:definition}});StructType.storage=opts.storage;StructType._offset=opts.offset;utils.methodsFor(StructType,"_offset","offsetFor","setOffset");var extensions=[];StructType.conditional=function(condition,extension){extensions.push({condition:condition,extension:extension});return this};StructType.prototype.unpack=function(view,offset){if(!(view instanceof DataView))throw new Error("DataView expected");if(!offset)offset=0;this._view=view;var self=this;function apply(definition){for(var prop in definition){var type=definition[prop];definition[prop].prop=prop;if(type.storage)continue;self[prop]=type.read(view,offset);if(typeof type.$unpacked==="function")self[prop]=type.$unpacked.call(self,self[prop]);if(self[prop]===undefined)delete self[prop];if(!type.external)offset+=type.lengthFor(self)*type.sizeFor(self)}}apply.parent=this;apply(definition);extensions.forEach(function(extension){if(!extension.condition.call(self))return;apply(extension.extension)});if(typeof this.$unpacked==="function")this.$unpacked();return this};StructType.prototype.pack=function(view,offset){if(typeof this.$packing==="function")this.$packing();if(!view)view=new DataView(new ArrayBuffer(this.lengthFor(this,true)*this.sizeFor(this,true)));if(!offset)offset=0;var self=this;function apply(definition){var start=offset;for(var prop in definition){var type=definition[prop];if(type.external||type.storage)continue;if(type instanceof StructStorage)type.write(view,offset,self[prop],offset-start);offset+=type.lengthFor(self,true)*type.sizeFor(self,true)}offset=start;for(var prop in definition){var type=definition[prop];if(type.external||type.storage)continue;if(!(type instanceof StructNumber)&&!(type instanceof StructStorage))type.write(view,offset,self[prop]);offset+=type.lengthFor(self,true)*type.sizeFor(self,true)}offset=start;for(var prop in definition){var type=definition[prop];if(type.external||type.storage)continue;var value=self[prop];if(typeof type.$packing==="function")value=type.$packing.call(self,value);if(type instanceof StructNumber)type.write(view,offset,value);offset+=type.lengthFor(self,true)*type.sizeFor(self,true)}}apply.parent=this;apply(definition);extensions.forEach(function(extension){if(!extension.condition.call(self))return;apply(extension.extension)});return view.buffer};StructType.read=function read(buffer,offset){var self=new this,parent=read.caller.parent,shift=this.storage?this.offsetFor(parent):offset;self.unpack(buffer,shift);return self};StructType.write=function write(buffer,offset,value,relativeOffset){var parent=write.caller.parent,shift=this.storage?offset+this.offsetFor(parent):offset;this.setOffset(this.storage?relativeOffset+this.offsetFor(parent):offset,parent);value.pack(buffer,shift)};StructType.prototype.lengthFor=StructType.lengthFor=function(){return 1};StructType.prototype.sizeFor=StructType.sizeFor=function(parent,writing){var self=this;function sizeOf(definition){return Object.keys(definition).filter(function(prop){return!definition[prop].external&&!definition[prop].storage}).map(function(prop){return definition[prop].lengthFor(parent,!!writing)*definition[prop].sizeFor(parent,!!writing)}).reduce(function(lhs,rhs){return lhs+rhs},0)}var size=sizeOf(definition);extensions.forEach(function(extension){if(!extension.condition.call(parent))return;size+=sizeOf(extension.extension)});return size};StructType.prototype.clone=function(){var clone=new StructType(this);if(typeof clone.$unpacked==="function")clone.$unpacked();return clone};return StructType};Struct.Int8=new StructNumber("getInt8","setInt8",1);Struct.Uint8=new StructNumber("getUint8","setUint8",1);Struct.Int16=new StructNumber("getInt16","setInt16",2);Struct.Uint16=new StructNumber("getUint16","setUint16",2);Struct.Int32=new StructNumber("getInt32","setInt32",4);Struct.Uint32=new StructNumber("getUint32","setUint32",4);Struct.Float32=new StructNumber("getFloat32","setFloat32",4);Struct.Float64=new StructNumber("getFloat64","setFloat64",8);Struct.String=function(length){return new StructString(length)};Struct.Hash=function(struct,key,length){return new StructHash(struct,key,length)};Struct.Array=function(struct,length){return new StructArray(struct,length)};Struct.Reference=Struct.Ref=function(prop){return new StructReference(prop)};Struct.Storage=function(path,opts){return new StructStorage(path,opts)};function cloneValue(val){if(val===undefined){return undefined}else if(typeof val.clone==="function"){return val.clone()}else if(Array.isArray(val)){return[].concat(val)}else if(typeof val==="object"){var clone={};for(key in val)clone[key]=cloneValue(val[key]);return clone}else{return val}}},{"./types/array":2,"./types/hash":3,"./types/number":4,"./types/reference":5,"./types/storage":6,"./types/string":7,"./utils":8}],2:[function(require,module,exports){var utils=require("../utils"),StructReference=require("./reference");var StructArray=module.exports=function(struct,length){this.struct=struct;Object.defineProperties(this,{_length:{value:length,writable:true}})};StructArray.prototype.read=function read(buffer,offset){var arr=[],parent=read.caller.parent;for(var i=0,len=this.lengthFor(parent);i<len;++i){var child;if(typeof this.struct==="function"){child=new this.struct;child.unpack(buffer,offset);offset+=child.lengthFor(parent)*child.sizeFor(parent)}else{child=this.struct.read(buffer,offset);offset+=this.struct.lengthFor(parent)*this.struct.sizeFor(parent)}arr.push(child)}return arr};StructArray.prototype.write=function write(buffer,offset,arr){var parent=write.caller.parent,child;this.setLength(this.lengthFor(parent,true),parent);for(var i=0,len=this.lengthFor(parent,true);i<len;++i){if((child=arr[i])===undefined)break;if(typeof this.struct==="function"){child.pack(buffer,offset);offset+=child.lengthFor(parent)*child.sizeFor(parent)}else{this.struct.write(buffer,offset,child);offset+=this.struct.lengthFor(parent)*this.struct.sizeFor(parent)}}};StructArray.prototype.sizeFor=function(parent){return(this.struct.sizeFor?this.struct.sizeFor(parent):this.struct.prototype.sizeFor(parent))*(this.struct.lengthFor?this.struct.lengthFor(parent):this.struct.prototype.lengthFor(parent))};StructArray.prototype.lengthFor=function(parent,writing){if(!this._length)return 0;if(this._length instanceof StructReference){if(writing)return parent[this.prop].length;return parent[this._length.prop]}else if(typeof this._length==="function"){return this._length.call(parent)}return this._length};StructArray.prototype.setLength=function(value,parent){if(this._length instanceof StructReference)parent[this._length.prop]=value;else if(typeof this._length==="function"){return}else this._length=value}},{"../utils":8,"./reference":5}],3:[function(require,module,exports){var utils=require("../utils"),StructReference=require("./reference");var StructHash=module.exports=function(struct,key,length){this.struct=struct;this.key=key;Object.defineProperties(this,{_length:{value:length,writable:true}})};StructHash.prototype.read=function read(buffer,offset){var hash={},parent=read.caller.parent;for(var i=0,len=this.lengthFor(parent);i<len;++i){var child=new this.struct;child.unpack(buffer,offset);offset+=child.lengthFor(parent)*child.sizeFor(parent);hash[child[this.key]]=child}return hash};StructHash.prototype.write=function write(buffer,offset,hash){var keys=Object.keys(hash),parent=write.caller.parent,child;this.setLength(this.lengthFor(parent,true),parent);for(var i=0,len=this.lengthFor(parent);i<len;++i){if(!(child=hash[keys[i]]))continue;child.pack(buffer,offset);offset+=child.lengthFor(parent)*child.sizeFor(parent)}};StructHash.prototype.sizeFor=function(parent){return(this.struct.sizeFor?this.struct.sizeFor(parent):this.struct.prototype.sizeFor(parent))*(this.struct.lengthFor?this.struct.lengthFor(parent):this.struct.prototype.lengthFor(parent))};StructHash.prototype.lengthFor=function(parent,writing){if(!this._length)return 0;if(this._length instanceof StructReference){if(writing)return Object.keys(parent[this.prop]).length;return parent[this._length.prop]}return this._length};StructHash.prototype.setLength=function(value,parent){if(this._length instanceof StructReference)parent[this._length.prop]=value;else this._length=value}},{"../utils":8,"./reference":5}],4:[function(require,module,exports){var utils=require("../utils");var StructNumber=module.exports=function(read,write,length){this.methods={read:read,write:write};Object.defineProperties(this,{_offset:{value:null,writable:true},_length:{value:null,writable:true}});utils.options.call(this,length)};StructNumber.prototype.with=function(opts){if(!opts.length)opts.length=this._length;return new StructNumber(this.methods.read,this.methods.write,opts)};StructNumber.prototype.from=function(offset){return this.with({external:true,offset:offset})};StructNumber.prototype.read=function read(buffer,offset){var parent=read.caller.parent;return buffer[this.methods.read](this.external?this.offsetFor(parent):offset)};StructNumber.prototype.write=function write(buffer,offset,value){var parent=write.caller.parent;buffer[this.methods.write](this.external?this.offsetFor(parent):offset,value)};StructNumber.prototype.lengthFor=function(){return 1};StructNumber.prototype.sizeFor=function(){return this._length};utils.methodsFor(StructNumber.prototype,"_offset","offsetFor","setOffset")},{"../utils":8}],5:[function(require,module,exports){var StructReference=module.exports=function(prop){this.prop=prop}},{}],6:[function(require,module,exports){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")},{"../utils":8,"./array":2,"./reference":5}],7:[function(require,module,exports){var utils=require("../utils"),StructReference=require("./reference");var StructString=module.exports=function(length){Object.defineProperties(this,{_offset:{value:null,writable:true},_length:{value:null,writable:true},_size:{value:null,writable:true}});utils.options.call(this,length)};StructString.prototype.read=function read(buffer,offset){var str=[],storage,parent=read.caller.parent,shift=this.external?this.offsetFor(parent):this.storage?offset+this.offsetFor(parent):offset;for(var i=0,len=this.lengthFor(parent),step=this.sizeFor()===2?2:1;i<len;++i){str.push(buffer[this.sizeFor()===2?"getUint16":"getUint8"](shift+i*step,this.littleEndian))}return String.fromCharCode.apply(null,str)};StructString.prototype.write=function write(buffer,offset,value){var str=[],storage,parent=write.caller.parent,shift=this.external?this.offsetFor(parent):this.storage?offset+this.offsetFor(parent):offset;this.setLength(this.lengthFor(parent,true),parent);for(var i=0,len=this.lengthFor(parent),step=this.sizeFor()===2?2:1;i<len;++i){var code=value.charCodeAt(i)||0;buffer[this.sizeFor()===2?"setUint16":"setUint8"](shift+i*step,code,this.littleEndian)}};StructString.prototype.sizeFor=function(){return this._size||1};StructString.prototype.lengthFor=function(parent,writing){if(this._length instanceof StructReference){if(writing)return parent[this.prop].length;return parent[this._length.prop]}return this._length||0};StructString.prototype.setLength=function(value,parent){if(this._length instanceof StructReference)parent[this._length.prop]=value;else this._length=value};utils.methodsFor(StructString.prototype,"_offset","offsetFor","setOffset")},{"../utils":8,"./reference":5}],8:[function(require,module,exports){var StructReference=require("./types/reference");exports.methodsFor=function(obj,prop,get,set){obj[get]=function(parent){if(!this[prop])return 0;if(this[prop]instanceof StructReference)return parent[this[prop].prop];else if(typeof this[prop]==="function")return this[prop].call(parent);return this[prop]};if(!set)return;obj[set]=function(value,parent){if(this[prop]instanceof StructReference)parent[this[prop].prop]=value;else this[prop]=value}};exports.options=function(opts){if(typeof opts==="object"){this._offset=opts.offset;this._length=opts.length;this._size=opts.size;this.$unpacked=opts.$unpacked;this.$packing=opts.$packing;this.external=opts.external===true;this.storage=opts.storage;this.littleEndian=opts.littleEndian===true}else{this._length=opts}}},{"./types/reference":5}]},{},[1])(1)}); //# sourceMappingURL=structjs.min.map