UNPKG

reified

Version:

JS Binary Data API. Structs, arrays, bitfields, and numbers. Reify and Reference like nobody's business.

138 lines (116 loc) 3.5 kB
"use strict"; var genesis = require('./genesis'); var numeric = require('./numeric'); var ArrayType = require('./array'); var CharSubtype = genesis.Subtype.bind(CharType); module.exports = CharType; var char = String.fromCharCode; var code = Function.call.bind(''.charCodeAt); var ucs2 = function(){ var a = 0x3ff, o = 0x10000, x = o - 0x800, y = o - 0x2400, z = o - 0x2800; return function ucs2(v) { if (typeof v === 'string') { var r = code(v, 0); return r & x === z ? o + ((r & a) << 10) + (code(v, 1) & a) : r; } else if (isFinite(v)) { return v >= o ? char((v -= o) >>> 10 & a | z) + char(y | v & a) : char(v); } } }(); var cache = []; function CharType(data, offset, value){ var length; if (typeof data === 'number') { length = data; data = null; } else if (typeof data === 'string') { length = data.length; value = data; data = null; } else if (data.bytes || data.byteLength) { length = data.bytes || data.byteLength; } var bytes = length; if (!(bytes in cache)) { var CharArray = cache[bytes] = CharSubtype('CharArray'+bytes, bytes, function CharArray(data, offset, value){ if (!data) data = new genesis.DataBuffer(this.bytes); this.rebase(data); genesis.api(this, '_offset', offset || 0); value && this.write(value); return this; }); CharArray.bytes = bytes; CharArray.prototype.bytes = bytes; CharArray.prototype.length = bytes; } else { var CharArray = cache[bytes]; } if (data || value) { if (!data) data = new genesis.DataBuffer(bytes || value); return new CharArray(data, offset, value); } else { return CharArray; } } genesis.Type(CharType, { DataType: 'string', Subtype: 'CharArray', bits: 8, join: Array.prototype.join, map: Array.prototype.map, fill: function fill(v){ this.write(0, v || 0) }, reify: function reify(){ return this._data.subarray(this._offset, this.bytes).map(function(str){ return ucs2(str); }).join(''); }, write: function write(value, index){ var isString = typeof value === 'string'; if (isFinite(index)) { if (isString) value = ucs2(value); this._data['writeUint'+this.bits](index, value); } else if (typeof value === 'string' || value && 'length' in value) { var bytesPer = this.bits / 8; for (var i=0; i<value.length && i<this.length; i++) { this._data['writeUint'+this.bits](this._offset+i*bytesPer, ucs2(value[i])); } } }, }); function Char(data, offset, value){ if (typeof data === 'string' || typeof data === 'number' || !data) { value = data; data = null; } this.rebase(data); genesis.api(this, '_offset', +offset || 0); if (value != null) { this.write(value); } return this; } Char.prototype = { length: 1, Subtype: 'CharArray', bytes: 1, write: function write(v, i){ this._data['writeUint'+this.bits](this._offset, typeof v === 'string' ? ucs2(v[i || 0]) : v); return this; }, reify: function reify(deallocate){ return ucs2(this._data['readUint'+this.bits](this._offset, 1)); }, toNumber: function toNumber(v){ return this._data['readUint'+this.bits](this._offset); } }; Char.__proto__ = CharType.prototype; Char.constructor = CharType; Char.prototype.__proto__ = CharType.prototype.prototype; Char.bytes = Char.prototype.bytes = Char.prototype.length = 1 Char.prototype.constructor = Char; cache[1] = Char;