shadow-function
Version:
ioing lib - shadow Function, worker Function
1,225 lines (1,143 loc) • 158 kB
JavaScript
/*
Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
* Backing buffer: ArrayBuffer, Accessor: Uint8Array
* Released under the Apache License, Version 2.0
* see: https://github.com/dcodeIO/bytebuffer.js for details
*/
(function(global, factory) {
/* AMD */ if (typeof define === 'function' && define["amd"])
define(["long"], factory);
/* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
module['exports'] = (function() {
var Long; try { Long = require("long"); } catch (e) {}
return factory(Long);
})();
/* Global */ else
(global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
})(this, function(Long) {
"use strict";
/**
* Constructs a new ByteBuffer.
* @class The swiss army knife for binary data in JavaScript.
* @exports ByteBuffer
* @constructor
* @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
* @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
* {@link ByteBuffer.DEFAULT_ENDIAN}.
* @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
* {@link ByteBuffer.DEFAULT_NOASSERT}.
* @expose
*/
var ByteBuffer = function(capacity, littleEndian, noAssert) {
if (typeof capacity === 'undefined')
capacity = ByteBuffer.DEFAULT_CAPACITY;
if (typeof littleEndian === 'undefined')
littleEndian = ByteBuffer.DEFAULT_ENDIAN;
if (typeof noAssert === 'undefined')
noAssert = ByteBuffer.DEFAULT_NOASSERT;
if (!noAssert) {
capacity = capacity | 0;
if (capacity < 0)
throw RangeError("Illegal capacity");
littleEndian = !!littleEndian;
noAssert = !!noAssert;
}
/**
* Backing ArrayBuffer.
* @type {!ArrayBuffer}
* @expose
*/
this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
/**
* Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
* @type {?Uint8Array}
* @expose
*/
this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
/**
* Absolute read/write offset.
* @type {number}
* @expose
* @see ByteBuffer#flip
* @see ByteBuffer#clear
*/
this.offset = 0;
/**
* Marked offset.
* @type {number}
* @expose
* @see ByteBuffer#mark
* @see ByteBuffer#reset
*/
this.markedOffset = -1;
/**
* Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
* @type {number}
* @expose
* @see ByteBuffer#flip
* @see ByteBuffer#clear
*/
this.limit = capacity;
/**
* Whether to use little endian byte order, defaults to `false` for big endian.
* @type {boolean}
* @expose
*/
this.littleEndian = littleEndian;
/**
* Whether to skip assertions of offsets and values, defaults to `false`.
* @type {boolean}
* @expose
*/
this.noAssert = noAssert;
};
/**
* ByteBuffer version.
* @type {string}
* @const
* @expose
*/
ByteBuffer.VERSION = "5.0.1";
/**
* Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
* @type {boolean}
* @const
* @expose
*/
ByteBuffer.LITTLE_ENDIAN = true;
/**
* Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
* @type {boolean}
* @const
* @expose
*/
ByteBuffer.BIG_ENDIAN = false;
/**
* Default initial capacity of `16`.
* @type {number}
* @expose
*/
ByteBuffer.DEFAULT_CAPACITY = 16;
/**
* Default endianess of `false` for big endian.
* @type {boolean}
* @expose
*/
ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
/**
* Default no assertions flag of `false`.
* @type {boolean}
* @expose
*/
ByteBuffer.DEFAULT_NOASSERT = false;
/**
* A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
* and int64 support is not available.
* @type {?Long}
* @const
* @see https://github.com/dcodeIO/long.js
* @expose
*/
ByteBuffer.Long = Long || null;
/**
* @alias ByteBuffer.prototype
* @inner
*/
var ByteBufferPrototype = ByteBuffer.prototype;
/**
* An indicator used to reliably determine if an object is a ByteBuffer or not.
* @type {boolean}
* @const
* @expose
* @private
*/
ByteBufferPrototype.__isByteBuffer__;
Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
value: true,
enumerable: false,
configurable: false
});
// helpers
/**
* @type {!ArrayBuffer}
* @inner
*/
var EMPTY_BUFFER = new ArrayBuffer(0);
/**
* String.fromCharCode reference for compile-time renaming.
* @type {function(...number):string}
* @inner
*/
var stringFromCharCode = String.fromCharCode;
/**
* Creates a source function for a string.
* @param {string} s String to read from
* @returns {function():number|null} Source function returning the next char code respectively `null` if there are
* no more characters left.
* @throws {TypeError} If the argument is invalid
* @inner
*/
function stringSource(s) {
var i=0; return function() {
return i < s.length ? s.charCodeAt(i++) : null;
};
}
/**
* Creates a destination function for a string.
* @returns {function(number=):undefined|string} Destination function successively called with the next char code.
* Returns the final string when called without arguments.
* @inner
*/
function stringDestination() {
var cs = [], ps = []; return function() {
if (arguments.length === 0)
return ps.join('')+stringFromCharCode.apply(String, cs);
if (cs.length + arguments.length > 1024)
ps.push(stringFromCharCode.apply(String, cs)),
cs.length = 0;
Array.prototype.push.apply(cs, arguments);
};
}
/**
* Gets the accessor type.
* @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
* @expose
*/
ByteBuffer.accessor = function() {
return Uint8Array;
};
/**
* Allocates a new ByteBuffer backed by a buffer of the specified capacity.
* @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
* @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
* {@link ByteBuffer.DEFAULT_ENDIAN}.
* @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
* {@link ByteBuffer.DEFAULT_NOASSERT}.
* @returns {!ByteBuffer}
* @expose
*/
ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
return new ByteBuffer(capacity, littleEndian, noAssert);
};
/**
* Concatenates multiple ByteBuffers into one.
* @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
* @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
* defaults to "utf8")
* @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
* to {@link ByteBuffer.DEFAULT_ENDIAN}.
* @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
* {@link ByteBuffer.DEFAULT_NOASSERT}.
* @returns {!ByteBuffer} Concatenated ByteBuffer
* @expose
*/
ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
noAssert = littleEndian;
littleEndian = encoding;
encoding = undefined;
}
var capacity = 0;
for (var i=0, k=buffers.length, length; i<k; ++i) {
if (!ByteBuffer.isByteBuffer(buffers[i]))
buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
length = buffers[i].limit - buffers[i].offset;
if (length > 0) capacity += length;
}
if (capacity === 0)
return new ByteBuffer(0, littleEndian, noAssert);
var bb = new ByteBuffer(capacity, littleEndian, noAssert),
bi;
i=0; while (i<k) {
bi = buffers[i++];
length = bi.limit - bi.offset;
if (length <= 0) continue;
bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
bb.offset += length;
}
bb.limit = bb.offset;
bb.offset = 0;
return bb;
};
/**
* Tests if the specified type is a ByteBuffer.
* @param {*} bb ByteBuffer to test
* @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
* @expose
*/
ByteBuffer.isByteBuffer = function(bb) {
return (bb && bb["__isByteBuffer__"]) === true;
};
/**
* Gets the backing buffer type.
* @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
* @expose
*/
ByteBuffer.type = function() {
return ArrayBuffer;
};
/**
* Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
* {@link ByteBuffer#limit} to the length of the wrapped data.
* @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
* @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
* "utf8")
* @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
* {@link ByteBuffer.DEFAULT_ENDIAN}.
* @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
* {@link ByteBuffer.DEFAULT_NOASSERT}.
* @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
* @expose
*/
ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
if (typeof encoding !== 'string') {
noAssert = littleEndian;
littleEndian = encoding;
encoding = undefined;
}
if (typeof buffer === 'string') {
if (typeof encoding === 'undefined')
encoding = "utf8";
switch (encoding) {
case "base64":
return ByteBuffer.fromBase64(buffer, littleEndian);
case "hex":
return ByteBuffer.fromHex(buffer, littleEndian);
case "binary":
return ByteBuffer.fromBinary(buffer, littleEndian);
case "utf8":
return ByteBuffer.fromUTF8(buffer, littleEndian);
case "debug":
return ByteBuffer.fromDebug(buffer, littleEndian);
default:
throw Error("Unsupported encoding: "+encoding);
}
}
if (buffer === null || typeof buffer !== 'object')
throw TypeError("Illegal buffer");
var bb;
if (ByteBuffer.isByteBuffer(buffer)) {
bb = ByteBufferPrototype.clone.call(buffer);
bb.markedOffset = -1;
return bb;
}
if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
bb = new ByteBuffer(0, littleEndian, noAssert);
if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
bb.buffer = buffer.buffer;
bb.offset = buffer.byteOffset;
bb.limit = buffer.byteOffset + buffer.byteLength;
bb.view = new Uint8Array(buffer.buffer);
}
} else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
bb = new ByteBuffer(0, littleEndian, noAssert);
if (buffer.byteLength > 0) {
bb.buffer = buffer;
bb.offset = 0;
bb.limit = buffer.byteLength;
bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
}
} else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
bb.limit = buffer.length;
for (var i=0; i<buffer.length; ++i)
bb.view[i] = buffer[i];
} else
throw TypeError("Illegal buffer"); // Otherwise fail
return bb;
};
/**
* Writes the array as a bitset.
* @param {Array<boolean>} value Array of booleans to write
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
* @returns {!ByteBuffer}
* @expose
*/
ByteBufferPrototype.writeBitSet = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (!(value instanceof Array))
throw TypeError("Illegal BitSet: Not an array");
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
var start = offset,
bits = value.length,
bytes = (bits >> 3),
bit = 0,
k;
offset += this.writeVarint32(bits,offset);
while(bytes--) {
k = (!!value[bit++] & 1) |
((!!value[bit++] & 1) << 1) |
((!!value[bit++] & 1) << 2) |
((!!value[bit++] & 1) << 3) |
((!!value[bit++] & 1) << 4) |
((!!value[bit++] & 1) << 5) |
((!!value[bit++] & 1) << 6) |
((!!value[bit++] & 1) << 7);
this.writeByte(k,offset++);
}
if(bit < bits) {
var m = 0; k = 0;
while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
this.writeByte(k,offset++);
}
if (relative) {
this.offset = offset;
return this;
}
return offset - start;
}
/**
* Reads a BitSet as an array of booleans.
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
* @returns {Array<boolean>
* @expose
*/
ByteBufferPrototype.readBitSet = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
var ret = this.readVarint32(offset),
bits = ret.value,
bytes = (bits >> 3),
bit = 0,
value = [],
k;
offset += ret.length;
while(bytes--) {
k = this.readByte(offset++);
value[bit++] = !!(k & 0x01);
value[bit++] = !!(k & 0x02);
value[bit++] = !!(k & 0x04);
value[bit++] = !!(k & 0x08);
value[bit++] = !!(k & 0x10);
value[bit++] = !!(k & 0x20);
value[bit++] = !!(k & 0x40);
value[bit++] = !!(k & 0x80);
}
if(bit < bits) {
var m = 0;
k = this.readByte(offset++);
while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
}
if (relative) {
this.offset = offset;
}
return value;
}
/**
* Reads the specified number of bytes.
* @param {number} length Number of bytes to read
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
* @returns {!ByteBuffer}
* @expose
*/
ByteBufferPrototype.readBytes = function(length, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + length > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
}
var slice = this.slice(offset, offset + length);
if (relative) this.offset += length;
return slice;
};
/**
* Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
* @function
* @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
* will be modified according to the performed read operation.
* @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
* written if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
// types/ints/int8
/**
* Writes an 8bit signed integer.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeInt8 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value !== 'number' || value % 1 !== 0)
throw TypeError("Illegal value: "+value+" (not an integer)");
value |= 0;
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
offset += 1;
var capacity0 = this.buffer.byteLength;
if (offset > capacity0)
this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
offset -= 1;
this.view[offset] = value;
if (relative) this.offset += 1;
return this;
};
/**
* Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
* @function
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
/**
* Reads an 8bit signed integer.
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readInt8 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 1 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
}
var value = this.view[offset];
if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
if (relative) this.offset += 1;
return value;
};
/**
* Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
* @function
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
/**
* Writes an 8bit unsigned integer.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeUint8 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value !== 'number' || value % 1 !== 0)
throw TypeError("Illegal value: "+value+" (not an integer)");
value >>>= 0;
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
offset += 1;
var capacity1 = this.buffer.byteLength;
if (offset > capacity1)
this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
offset -= 1;
this.view[offset] = value;
if (relative) this.offset += 1;
return this;
};
/**
* Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
* @function
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
/**
* Reads an 8bit unsigned integer.
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readUint8 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 1 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
}
var value = this.view[offset];
if (relative) this.offset += 1;
return value;
};
/**
* Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
* @function
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
// types/ints/int16
/**
* Writes a 16bit signed integer.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @throws {TypeError} If `offset` or `value` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.writeInt16 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value !== 'number' || value % 1 !== 0)
throw TypeError("Illegal value: "+value+" (not an integer)");
value |= 0;
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
offset += 2;
var capacity2 = this.buffer.byteLength;
if (offset > capacity2)
this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
offset -= 2;
if (this.littleEndian) {
this.view[offset+1] = (value & 0xFF00) >>> 8;
this.view[offset ] = value & 0x00FF;
} else {
this.view[offset] = (value & 0xFF00) >>> 8;
this.view[offset+1] = value & 0x00FF;
}
if (relative) this.offset += 2;
return this;
};
/**
* Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
* @function
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @throws {TypeError} If `offset` or `value` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
/**
* Reads a 16bit signed integer.
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @returns {number} Value read
* @throws {TypeError} If `offset` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.readInt16 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 2 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
}
var value = 0;
if (this.littleEndian) {
value = this.view[offset ];
value |= this.view[offset+1] << 8;
} else {
value = this.view[offset ] << 8;
value |= this.view[offset+1];
}
if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
if (relative) this.offset += 2;
return value;
};
/**
* Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
* @function
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @returns {number} Value read
* @throws {TypeError} If `offset` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
/**
* Writes a 16bit unsigned integer.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @throws {TypeError} If `offset` or `value` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.writeUint16 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value !== 'number' || value % 1 !== 0)
throw TypeError("Illegal value: "+value+" (not an integer)");
value >>>= 0;
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
offset += 2;
var capacity3 = this.buffer.byteLength;
if (offset > capacity3)
this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
offset -= 2;
if (this.littleEndian) {
this.view[offset+1] = (value & 0xFF00) >>> 8;
this.view[offset ] = value & 0x00FF;
} else {
this.view[offset] = (value & 0xFF00) >>> 8;
this.view[offset+1] = value & 0x00FF;
}
if (relative) this.offset += 2;
return this;
};
/**
* Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
* @function
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @throws {TypeError} If `offset` or `value` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
/**
* Reads a 16bit unsigned integer.
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @returns {number} Value read
* @throws {TypeError} If `offset` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.readUint16 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 2 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
}
var value = 0;
if (this.littleEndian) {
value = this.view[offset ];
value |= this.view[offset+1] << 8;
} else {
value = this.view[offset ] << 8;
value |= this.view[offset+1];
}
if (relative) this.offset += 2;
return value;
};
/**
* Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
* @function
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
* @returns {number} Value read
* @throws {TypeError} If `offset` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @expose
*/
ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
// types/ints/int32
/**
* Writes a 32bit signed integer.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @expose
*/
ByteBufferPrototype.writeInt32 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value !== 'number' || value % 1 !== 0)
throw TypeError("Illegal value: "+value+" (not an integer)");
value |= 0;
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
offset += 4;
var capacity4 = this.buffer.byteLength;
if (offset > capacity4)
this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
offset -= 4;
if (this.littleEndian) {
this.view[offset+3] = (value >>> 24) & 0xFF;
this.view[offset+2] = (value >>> 16) & 0xFF;
this.view[offset+1] = (value >>> 8) & 0xFF;
this.view[offset ] = value & 0xFF;
} else {
this.view[offset ] = (value >>> 24) & 0xFF;
this.view[offset+1] = (value >>> 16) & 0xFF;
this.view[offset+2] = (value >>> 8) & 0xFF;
this.view[offset+3] = value & 0xFF;
}
if (relative) this.offset += 4;
return this;
};
/**
* Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @expose
*/
ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
/**
* Reads a 32bit signed integer.
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readInt32 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 4 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
}
var value = 0;
if (this.littleEndian) {
value = this.view[offset+2] << 16;
value |= this.view[offset+1] << 8;
value |= this.view[offset ];
value += this.view[offset+3] << 24 >>> 0;
} else {
value = this.view[offset+1] << 16;
value |= this.view[offset+2] << 8;
value |= this.view[offset+3];
value += this.view[offset ] << 24 >>> 0;
}
value |= 0; // Cast to signed
if (relative) this.offset += 4;
return value;
};
/**
* Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
* @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
/**
* Writes a 32bit unsigned integer.
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @expose
*/
ByteBufferPrototype.writeUint32 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value !== 'number' || value % 1 !== 0)
throw TypeError("Illegal value: "+value+" (not an integer)");
value >>>= 0;
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
offset += 4;
var capacity5 = this.buffer.byteLength;
if (offset > capacity5)
this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
offset -= 4;
if (this.littleEndian) {
this.view[offset+3] = (value >>> 24) & 0xFF;
this.view[offset+2] = (value >>> 16) & 0xFF;
this.view[offset+1] = (value >>> 8) & 0xFF;
this.view[offset ] = value & 0xFF;
} else {
this.view[offset ] = (value >>> 24) & 0xFF;
this.view[offset+1] = (value >>> 16) & 0xFF;
this.view[offset+2] = (value >>> 8) & 0xFF;
this.view[offset+3] = value & 0xFF;
}
if (relative) this.offset += 4;
return this;
};
/**
* Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
* @function
* @param {number} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @expose
*/
ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
/**
* Reads a 32bit unsigned integer.
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readUint32 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 4 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
}
var value = 0;
if (this.littleEndian) {
value = this.view[offset+2] << 16;
value |= this.view[offset+1] << 8;
value |= this.view[offset ];
value += this.view[offset+3] << 24 >>> 0;
} else {
value = this.view[offset+1] << 16;
value |= this.view[offset+2] << 8;
value |= this.view[offset+3];
value += this.view[offset ] << 24 >>> 0;
}
if (relative) this.offset += 4;
return value;
};
/**
* Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
* @function
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
* @returns {number} Value read
* @expose
*/
ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
// types/ints/int64
if (Long) {
/**
* Writes a 64bit signed integer.
* @param {number|!Long} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeInt64 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value === 'number')
value = Long.fromNumber(value);
else if (typeof value === 'string')
value = Long.fromString(value);
else if (!(value && value instanceof Long))
throw TypeError("Illegal value: "+value+" (not an integer or Long)");
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
if (typeof value === 'number')
value = Long.fromNumber(value);
else if (typeof value === 'string')
value = Long.fromString(value);
offset += 8;
var capacity6 = this.buffer.byteLength;
if (offset > capacity6)
this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
offset -= 8;
var lo = value.low,
hi = value.high;
if (this.littleEndian) {
this.view[offset+3] = (lo >>> 24) & 0xFF;
this.view[offset+2] = (lo >>> 16) & 0xFF;
this.view[offset+1] = (lo >>> 8) & 0xFF;
this.view[offset ] = lo & 0xFF;
offset += 4;
this.view[offset+3] = (hi >>> 24) & 0xFF;
this.view[offset+2] = (hi >>> 16) & 0xFF;
this.view[offset+1] = (hi >>> 8) & 0xFF;
this.view[offset ] = hi & 0xFF;
} else {
this.view[offset ] = (hi >>> 24) & 0xFF;
this.view[offset+1] = (hi >>> 16) & 0xFF;
this.view[offset+2] = (hi >>> 8) & 0xFF;
this.view[offset+3] = hi & 0xFF;
offset += 4;
this.view[offset ] = (lo >>> 24) & 0xFF;
this.view[offset+1] = (lo >>> 16) & 0xFF;
this.view[offset+2] = (lo >>> 8) & 0xFF;
this.view[offset+3] = lo & 0xFF;
}
if (relative) this.offset += 8;
return this;
};
/**
* Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
* @param {number|!Long} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
/**
* Reads a 64bit signed integer.
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!Long}
* @expose
*/
ByteBufferPrototype.readInt64 = function(offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 8 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
}
var lo = 0,
hi = 0;
if (this.littleEndian) {
lo = this.view[offset+2] << 16;
lo |= this.view[offset+1] << 8;
lo |= this.view[offset ];
lo += this.view[offset+3] << 24 >>> 0;
offset += 4;
hi = this.view[offset+2] << 16;
hi |= this.view[offset+1] << 8;
hi |= this.view[offset ];
hi += this.view[offset+3] << 24 >>> 0;
} else {
hi = this.view[offset+1] << 16;
hi |= this.view[offset+2] << 8;
hi |= this.view[offset+3];
hi += this.view[offset ] << 24 >>> 0;
offset += 4;
lo = this.view[offset+1] << 16;
lo |= this.view[offset+2] << 8;
lo |= this.view[offset+3];
lo += this.view[offset ] << 24 >>> 0;
}
var value = new Long(lo, hi, false);
if (relative) this.offset += 8;
return value;
};
/**
* Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!Long}
* @expose
*/
ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
/**
* Writes a 64bit unsigned integer.
* @param {number|!Long} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeUint64 = function(value, offset) {
var relative = typeof offset === 'undefined';
if (relative) offset = this.offset;
if (!this.noAssert) {
if (typeof value === 'number')
value = Long.fromNumber(value);
else if (typeof value === 'string')
value = Long.fromString(value);
else if (!(value && value instanceof Long))
throw TypeError("Illegal value: "+value+" (not an integer or Long)");
if (typeof offset !== 'number' || offset % 1 !== 0)
throw TypeError("Illegal offset: "+offset+" (not an integer)");
offset >>>= 0;
if (offset < 0 || offset + 0 > this.buffer.byteLength)
throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
}
if (typeof value === 'number')
value = Long.fromNumber(value);
else if (typeof value === 'string')
value = Long.fromString(value);
offset += 8;
var capacity7 = this.buffer.byteLength;
if (offset > capacity7)
this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
offset -= 8;
var lo = value.low,
hi = value.high;
if (this.littleEndian) {
this.view[offset+3] = (lo >>> 24) & 0xFF;
this.view[offset+2] = (lo >>> 16) & 0xFF;
this.view[offset+1] = (lo >>> 8) & 0xFF;
this.view[offset ] = lo & 0xFF;
offset += 4;
this.view[offset+3] = (hi >>> 24) & 0xFF;
this.view[offset+2] = (hi >>> 16) & 0xFF;
this.view[offset+1] = (hi >>> 8) & 0xFF;
this.view[offset ] = hi & 0xFF;
} else {
this.view[offset ] = (hi >>> 24) & 0xFF;
this.view[offset+1] = (hi >>> 16) & 0xFF;
this.view[offset+2] = (hi >>> 8) & 0xFF;
this.view[offset+3] = hi & 0xFF;
offset += 4;
this.view[offset ] = (lo >>> 24) & 0xFF;
this.view[offset+1] = (lo >>> 16) & 0xFF;
this.view[offset+2] = (lo >>> 8) & 0xFF;
this.view[offset+3] = lo & 0xFF;
}
if (relative) this.offset += 8;
return this;
};
/**
* Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
* @function
* @param {number|!Long} value Value to write
* @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
/**
* Reads a 64bit unsigned integer.
* @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
* @returns {!Long}
* @expose