push all website files

This commit is contained in:
Jacob Levine
2019-01-06 13:14:45 -06:00
parent d7301e26c3
commit d2d5d4c04e
15662 changed files with 2166516 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
/**
* Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
* data's length.
//? if (NODE) {
* @param {!ByteBuffer|!Buffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its
* offsets will be modified according to the performed read operation.
//? } else {
* @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. 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 append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
* written if omitted.
* @returns {!ByteBuffer} this
* @expose
* @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
* @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
*/
ByteBufferPrototype.append = function(source, encoding, offset) {
if (typeof encoding === 'number' || typeof encoding !== 'string') {
offset = encoding;
encoding = undefined;
}
//? RELATIVE();
if (!this.noAssert) {
//? ASSERT_OFFSET();
}
if (!(source instanceof ByteBuffer))
source = ByteBuffer.wrap(source, encoding);
var length = source.limit - source.offset;
if (length <= 0) return this; // Nothing to append
//? ENSURE_CAPACITY('length');
//? if (NODE)
source.buffer.copy(this.buffer, offset, source.offset, source.limit);
//? else if (DATAVIEW)
new Uint8Array(this.buffer, offset).set(new Uint8Array(source.buffer).subarray(source.offset, source.limit));
//? else
this.view.set(source.view.subarray(source.offset, source.limit), offset);
source.offset += length;
//? RELATIVE('length');
return this;
};
/**
* Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
specified offset up to the length of this ByteBuffer's data.
* @param {!ByteBuffer} target Target ByteBuffer
* @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
* read if omitted.
* @returns {!ByteBuffer} this
* @expose
* @see ByteBuffer#append
*/
ByteBufferPrototype.appendTo = function(target, offset) {
target.append(this, offset);
return this;
};

View File

@@ -0,0 +1,12 @@
/**
* Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
* disable them if your code already makes sure that everything is valid.
* @param {boolean} assert `true` to enable assertions, otherwise `false`
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.assert = function(assert) {
this.noAssert = !assert;
return this;
};

View File

@@ -0,0 +1,8 @@
/**
* Gets the capacity of this ByteBuffer's backing buffer.
* @returns {number} Capacity of the backing buffer
* @expose
*/
ByteBufferPrototype.capacity = function() {
return /*?= CAPACITY */;
};

View File

@@ -0,0 +1,13 @@
/**
* Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
* backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.clear = function() {
this.offset = 0;
this.limit = /*?= CAPACITY */;
this.markedOffset = -1;
return this;
};

View File

@@ -0,0 +1,34 @@
/**
* Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
* {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
* @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
* @returns {!ByteBuffer} Cloned instance
* @expose
*/
ByteBufferPrototype.clone = function(copy) {
var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
if (copy) {
//? if (NODE) {
var buffer = new Buffer(this.buffer.length);
this.buffer.copy(buffer);
bb.buffer = buffer;
//? } else {
bb.buffer = new ArrayBuffer(this.buffer.byteLength);
//? if (DATAVIEW) {
new Uint8Array(bb.buffer).set(this.buffer);
bb.view = new DataView(bb.buffer);
//? } else {
bb.view = new Uint8Array(bb.buffer);
//? }
//? }
} else {
bb.buffer = this.buffer;
//? if (!NODE)
bb.view = this.view;
}
bb.offset = this.offset;
bb.markedOffset = this.markedOffset;
bb.limit = this.limit;
return bb;
};

View File

@@ -0,0 +1,49 @@
/**
* Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
* between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
* adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
* @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
* @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.compact = function(begin, end) {
if (typeof begin === 'undefined') begin = this.offset;
if (typeof end === 'undefined') end = this.limit;
if (!this.noAssert) {
//? ASSERT_RANGE();
}
if (begin === 0 && end === /*?= CAPACITY */)
return this; // Already compacted
var len = end - begin;
if (len === 0) {
this.buffer = EMPTY_BUFFER;
//? if (!NODE)
this.view = null;
if (this.markedOffset >= 0) this.markedOffset -= begin;
this.offset = 0;
this.limit = 0;
return this;
}
//? if (NODE) {
var buffer = new Buffer(len);
this.buffer.copy(buffer, 0, begin, end);
this.buffer = buffer;
//? } else if (DATAVIEW) {
var buffer = new ArrayBuffer(len);
new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(begin, end));
this.buffer = buffer;
this.view = new DataView(buffer);
//? } else {
var buffer = new ArrayBuffer(len);
var view = new Uint8Array(buffer);
view.set(this.view.subarray(begin, end));
this.buffer = buffer;
this.view = view;
//? }
if (this.markedOffset >= 0) this.markedOffset -= begin;
this.offset = 0;
this.limit = len;
return this;
};

View File

@@ -0,0 +1,73 @@
/**
* Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
* {@link ByteBuffer#limit}.
* @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
* @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
* @returns {!ByteBuffer} Copy
* @expose
*/
ByteBufferPrototype.copy = function(begin, end) {
if (typeof begin === 'undefined') begin = this.offset;
if (typeof end === 'undefined') end = this.limit;
if (!this.noAssert) {
//? ASSERT_RANGE();
}
if (begin === end)
return new ByteBuffer(0, this.littleEndian, this.noAssert);
var capacity = end - begin,
bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
bb.offset = 0;
bb.limit = capacity;
if (bb.markedOffset >= 0) bb.markedOffset -= begin;
this.copyTo(bb, 0, begin, end);
return bb;
};
/**
* Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
* {@link ByteBuffer#limit}.
* @param {!ByteBuffer} target Target ByteBuffer
* @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
* by the number of bytes copied if omitted.
* @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
* number of bytes copied if omitted.
* @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
var relative,
targetRelative;
if (!this.noAssert) {
if (!ByteBuffer.isByteBuffer(target))
throw TypeError("Illegal target: Not a ByteBuffer");
}
targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
//? var TARGET_CAPACITY = NODE ? 'target.buffer.length' : 'target.buffer.byteLength';
if (targetOffset < 0 || targetOffset > /*?= TARGET_CAPACITY */)
throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+/*?= TARGET_CAPACITY */);
if (sourceOffset < 0 || sourceLimit > /*?= CAPACITY */)
throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+/*?= CAPACITY */);
var len = sourceLimit - sourceOffset;
if (len === 0)
return target; // Nothing to copy
target.ensureCapacity(targetOffset + len);
//? if (NODE)
this.buffer.copy(target.buffer, targetOffset, sourceOffset, sourceLimit);
//? else if (DATAVIEW)
new Uint8Array(target.buffer).set(new Uint8Array(this.buffer).subarray(sourceOffset, sourceLimit), targetOffset);
//? else
target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
if (relative) this.offset += len;
if (targetRelative) target.offset += len;
return this;
};

View File

@@ -0,0 +1,15 @@
/**
* Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
* current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
* the required capacity will be used instead.
* @param {number} capacity Required capacity
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.ensureCapacity = function(capacity) {
var current = /*?= CAPACITY */;
if (current < capacity)
return this.resize((current *= 2) > capacity ? current : capacity);
return this;
};

View File

@@ -0,0 +1,35 @@
/**
* Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
* {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
* @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
* @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
* written if omitted. defaults to {@link ByteBuffer#offset}.
* @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
* @returns {!ByteBuffer} this
* @expose
* @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
*/
ByteBufferPrototype.fill = function(value, begin, end) {
//? RELATIVE(undefined, 'begin');
if (typeof value === 'string' && value.length > 0)
value = value.charCodeAt(0);
if (typeof begin === 'undefined') begin = this.offset;
if (typeof end === 'undefined') end = this.limit;
if (!this.noAssert) {
//? ASSERT_INTEGER('value');
//? ASSERT_RANGE();
}
if (begin >= end)
return this; // Nothing to fill
//? if (NODE) {
this.buffer.fill(value, begin, end);
begin = end;
//? } else if (DATAVIEW) {
while (begin < end) this.view.setUint8(begin++, value);
//? } else {
while (begin < end) this.view[begin++] = value;
//? }
if (relative) this.offset = begin;
return this;
};

View File

@@ -0,0 +1,11 @@
/**
* Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
* `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.flip = function() {
this.limit = this.offset;
this.offset = 0;
return this;
};

View File

@@ -0,0 +1,17 @@
/**
* Marks an offset on this ByteBuffer to be used later.
* @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
* @returns {!ByteBuffer} this
* @throws {TypeError} If `offset` is not a valid number
* @throws {RangeError} If `offset` is out of bounds
* @see ByteBuffer#reset
* @expose
*/
ByteBufferPrototype.mark = function(offset) {
offset = typeof offset === 'undefined' ? this.offset : offset;
if (!this.noAssert) {
//? ASSERT_OFFSET();
}
this.markedOffset = offset;
return this;
};

View File

@@ -0,0 +1,36 @@
/**
* Sets the byte order.
* @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.order = function(littleEndian) {
if (!this.noAssert) {
if (typeof littleEndian !== 'boolean')
throw TypeError("Illegal littleEndian: Not a boolean");
}
this.littleEndian = !!littleEndian;
return this;
};
/**
* Switches (to) little endian byte order.
* @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.LE = function(littleEndian) {
this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
return this;
};
/**
* Switches (to) big endian byte order.
* @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.BE = function(bigEndian) {
this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
return this;
};

View File

@@ -0,0 +1,87 @@
/**
* Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
* prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
* will be resized and its contents moved accordingly.
//? if (NODE) {
* @param {!ByteBuffer|string||!Buffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be modified
* according to the performed read operation.
//? } else {
* @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset 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 prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
* prepended if omitted.
* @returns {!ByteBuffer} this
* @expose
* @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
* @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
*/
ByteBufferPrototype.prepend = function(source, encoding, offset) {
if (typeof encoding === 'number' || typeof encoding !== 'string') {
offset = encoding;
encoding = undefined;
}
//? RELATIVE();
if (!this.noAssert) {
//? ASSERT_OFFSET();
}
if (!(source instanceof ByteBuffer))
source = ByteBuffer.wrap(source, encoding);
var len = source.limit - source.offset;
if (len <= 0) return this; // Nothing to prepend
var diff = len - offset;
if (diff > 0) { // Not enough space before offset, so resize + move
//? if (NODE) {
var buffer = new Buffer(this.buffer.length + diff);
this.buffer.copy(buffer, len, offset, this.buffer.length);
this.buffer = buffer;
//? } else if (DATAVIEW) {
var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
var arrayView = new Uint8Array(buffer);
arrayView.set(new Uint8Array(this.buffer).subarray(offset, this.buffer.byteLength), len);
this.buffer = buffer;
this.view = new DataView(buffer);
//? } else {
var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
var view = new Uint8Array(buffer);
view.set(this.view.subarray(offset, this.buffer.byteLength), len);
this.buffer = buffer;
this.view = view;
//? }
this.offset += diff;
if (this.markedOffset >= 0) this.markedOffset += diff;
this.limit += diff;
offset += diff;
}/*? if (!NODE) { */ else {
var arrayView = new Uint8Array(this.buffer);
}
//? }
//? if (NODE)
source.buffer.copy(this.buffer, offset - len, source.offset, source.limit);
//? else if (DATAVIEW)
arrayView.set(new Uint8Array(source.buffer).subarray(source.offset, source.limit), offset - len);
//? else
this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
source.offset = source.limit;
if (relative)
this.offset -= len;
return this;
};
/**
* Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
* prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
* will be resized and its contents moved accordingly.
* @param {!ByteBuffer} target Target ByteBuffer
* @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
* prepended if omitted.
* @returns {!ByteBuffer} this
* @expose
* @see ByteBuffer#prepend
*/
ByteBufferPrototype.prependTo = function(target, offset) {
target.prepend(this, offset);
return this;
};

View File

@@ -0,0 +1,16 @@
//? if (DEBUG) {
/**
* Prints debug information about this ByteBuffer's contents.
* @param {function(string)=} out Output function to call, defaults to console.log
* @expose
*/
ByteBufferPrototype.printDebug = function(out) {
if (typeof out !== 'function') out = console.log.bind(console);
out(
this.toString()+"\n"+
"-------------------------------------------------------------------\n"+
this.toDebug(/* columns */ true)
);
};
//? }

View File

@@ -0,0 +1,9 @@
/**
* Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
* {@link ByteBuffer#limit}, so this returns `limit - offset`.
* @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
* @expose
*/
ByteBufferPrototype.remaining = function() {
return this.limit - this.offset;
};

View File

@@ -0,0 +1,17 @@
/**
* Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
* before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
* marked, sets `offset = 0`.
* @returns {!ByteBuffer} this
* @see ByteBuffer#mark
* @expose
*/
ByteBufferPrototype.reset = function() {
if (this.markedOffset >= 0) {
this.offset = this.markedOffset;
this.markedOffset = -1;
} else {
this.offset = 0;
}
return this;
};

View File

@@ -0,0 +1,39 @@
/**
* Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
* large or larger.
* @param {number} capacity Capacity required
* @returns {!ByteBuffer} this
* @throws {TypeError} If `capacity` is not a number
* @throws {RangeError} If `capacity < 0`
* @expose
*/
ByteBufferPrototype.resize = function(capacity) {
if (!this.noAssert) {
//? ASSERT_INTEGER('capacity');
if (capacity < 0)
throw RangeError("Illegal capacity: 0 <= "+capacity);
}
//? if (NODE) {
if (this.buffer.length < capacity) {
var buffer = new Buffer(capacity);
this.buffer.copy(buffer);
this.buffer = buffer;
}
//? } else {
if (this.buffer.byteLength < capacity) {
//? if (DATAVIEW) {
var buffer = new ArrayBuffer(capacity);
new Uint8Array(buffer).set(new Uint8Array(this.buffer));
this.buffer = buffer;
this.view = new DataView(buffer);
//? } else {
var buffer = new ArrayBuffer(capacity);
var view = new Uint8Array(buffer);
view.set(this.view);
this.buffer = buffer;
this.view = view;
//? }
}
//? }
return this;
};

View File

@@ -0,0 +1,25 @@
/**
* Reverses this ByteBuffer's contents.
* @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
* @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.reverse = function(begin, end) {
if (typeof begin === 'undefined') begin = this.offset;
if (typeof end === 'undefined') end = this.limit;
if (!this.noAssert) {
//? ASSERT_RANGE();
}
if (begin === end)
return this; // Nothing to reverse
//? if (NODE)
Array.prototype.reverse.call(this.buffer.slice(begin, end));
//? else if (DATAVIEW) {
Array.prototype.reverse.call(new Uint8Array(this.buffer).subarray(begin, end));
this.view = new DataView(this.buffer); // FIXME: Why exactly is this necessary?
//? } else {
Array.prototype.reverse.call(this.view.subarray(begin, end));
//? }
return this;
};

View File

@@ -0,0 +1,19 @@
/**
* Skips the next `length` bytes. This will just advance
* @param {number} length Number of bytes to skip. May also be negative to move the offset back.
* @returns {!ByteBuffer} this
* @expose
*/
ByteBufferPrototype.skip = function(length) {
if (!this.noAssert) {
//? ASSERT_INTEGER('length');
}
var offset = this.offset + length;
if (!this.noAssert) {
if (offset < 0 || offset > /*?= CAPACITY */)
throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+/*?= CAPACITY */);
}
this.offset = offset;
return this;
};

View File

@@ -0,0 +1,18 @@
/**
* Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
* @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
* @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
* @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
* @expose
*/
ByteBufferPrototype.slice = function(begin, end) {
if (typeof begin === 'undefined') begin = this.offset;
if (typeof end === 'undefined') end = this.limit;
if (!this.noAssert) {
//? ASSERT_RANGE();
}
var bb = this.clone();
bb.offset = begin;
bb.limit = end;
return bb;
};

View File

@@ -0,0 +1,13 @@
/**
* Gets the accessor type.
* @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
* @expose
*/
ByteBuffer.accessor = function() {
//? if (NODE)
return Buffer;
//? else if (DATAVIEW)
return DataView;
//? else
return Uint8Array;
};

View File

@@ -0,0 +1,14 @@
/**
* 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);
};

View File

@@ -0,0 +1,55 @@
/**
* Concatenates multiple ByteBuffers into one.
//? if (NODE) {
* @param {!Array.<!ByteBuffer|!Buffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
//? } else {
* @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;
//? if (!NODE && DATAVIEW)
var view = new Uint8Array(bb.buffer);
i=0; while (i<k) {
bi = buffers[i++];
length = bi.limit - bi.offset;
if (length <= 0) continue;
//? if (NODE) {
bi.buffer.copy(bb.buffer, bb.offset, bi.offset, bi.limit);
bb.offset += length;
//? } else {
//? if (DATAVIEW)
view.set(new Uint8Array(bi.buffer).subarray(bi.offset, bi.limit), bb.offset);
//? else
bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
bb.offset += length;
//? }
}
bb.limit = bb.offset;
bb.offset = 0;
return bb;
};

View File

@@ -0,0 +1,9 @@
/**
* 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;
};

View File

@@ -0,0 +1,11 @@
/**
* Gets the backing buffer type.
* @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
* @expose
*/
ByteBuffer.type = function() {
//? if (NODE)
return Buffer;
//? else
return ArrayBuffer;
};

View File

@@ -0,0 +1,125 @@
/**
* 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.
//? if (NODE) {
* @param {!ByteBuffer|!Buffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
//? } else {
* @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) {
//? if (BASE64) {
case "base64":
return ByteBuffer.fromBase64(buffer, littleEndian);
//? } if (HEX) {
case "hex":
return ByteBuffer.fromHex(buffer, littleEndian);
//? } if (BINARY) {
case "binary":
return ByteBuffer.fromBinary(buffer, littleEndian);
//? } if (UTF8) {
case "utf8":
return ByteBuffer.fromUTF8(buffer, littleEndian);
//? } if (DEBUG) {
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 (NODE) {
var i = 0,
k = 0,
b;
if (buffer instanceof Uint8Array) { // Extract bytes from Uint8Array
b = new Buffer(buffer.length);
if (memcpy) { // Fast
memcpy(b, 0, buffer.buffer, buffer.byteOffset, buffer.byteOffset + buffer.length);
} else { // Slow
for (i=0, k=buffer.length; i<k; ++i)
b[i] = buffer[i];
}
buffer = b;
} else if (buffer instanceof ArrayBuffer) { // Convert ArrayBuffer to Buffer
b = new Buffer(buffer.byteLength);
if (memcpy) { // Fast
memcpy(b, 0, buffer, 0, buffer.byteLength);
} else { // Slow
buffer = new Uint8Array(buffer);
for (i=0, k=buffer.length; i<k; ++i) {
b[i] = buffer[i];
}
}
buffer = b;
} else if (!(buffer instanceof Buffer)) { // Create from octets if it is an error, otherwise fail
if (Object.prototype.toString.call(buffer) !== "[object Array]")
throw TypeError("Illegal buffer");
buffer = new Buffer(buffer);
}
bb = new ByteBuffer(0, littleEndian, noAssert);
if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
bb.buffer = buffer;
bb.limit = buffer.length;
}
//? } else {
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;
//? if (DATAVIEW)
bb.view = new DataView(buffer.buffer);
//? else
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;
//? if (DATAVIEW)
bb.view = buffer.byteLength > 0 ? new DataView(buffer) : null;
//? else
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)
//? if (DATAVIEW)
bb.view.setUint8(i, buffer[i]);
//? else
bb.view[i] = buffer[i];
} else
throw TypeError("Illegal buffer"); // Otherwise fail
//? }
return bb;
};

View File

@@ -0,0 +1,77 @@
/**
* Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
* {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
* @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
* possible. Defaults to `false`
//? if (NODE) {
* @returns {!Buffer} Contents as a Buffer
//? } else {
* @returns {!ArrayBuffer} Contents as an ArrayBuffer
//? }
* @expose
*/
ByteBufferPrototype.toBuffer = function(forceCopy) {
var offset = this.offset,
limit = this.limit;
if (!this.noAssert) {
//? ASSERT_RANGE('offset', 'limit');
}
//? if (NODE) {
if (forceCopy) {
var buffer = new Buffer(limit - offset);
this.buffer.copy(buffer, 0, offset, limit);
return buffer;
} else {
if (offset === 0 && limit === this.buffer.length)
return this.buffer;
else
return this.buffer.slice(offset, limit);
}
//? } else {
// NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
// possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
return this.buffer;
if (offset === limit)
return EMPTY_BUFFER;
var buffer = new ArrayBuffer(limit - offset);
new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
return buffer;
//? }
};
//? if (NODE) {
/**
* Returns a copy of the backing buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
* {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
* @returns {!ArrayBuffer} Contents as an ArrayBuffer
*/
ByteBufferPrototype.toArrayBuffer = function() {
var offset = this.offset,
limit = this.limit;
if (!this.noAssert) {
//? ASSERT_RANGE('offset', 'limit');
}
var ab = new ArrayBuffer(limit - offset);
if (memcpy) { // Fast
memcpy(ab, 0, this.buffer, offset, limit);
} else { // Slow
var dst = new Uint8Array(ab);
for (var i=offset; i<limit; ++i)
dst[i-offset] = this.buffer[i];
}
return ab;
};
//? } else {
/**
* Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
* {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
* @function
* @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
* Defaults to `false`
* @returns {!ArrayBuffer} Contents as an ArrayBuffer
* @expose
*/
ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
//? }

View File

@@ -0,0 +1,43 @@
/**
* Converts the ByteBuffer's contents to a string.
* @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
* direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
* highlighted offsets.
* @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
* @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
* @returns {string} String representation
* @throws {Error} If `encoding` is invalid
* @expose
*/
ByteBufferPrototype.toString = function(encoding, begin, end) {
if (typeof encoding === 'undefined')
return "ByteBuffer/*?= NODE ? 'NB' : 'AB'+(DATAVIEW ? '_DataView' : '') */(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
if (typeof encoding === 'number')
encoding = "utf8",
begin = encoding,
end = begin;
switch (encoding) {
//? if (ENCODINGS) {
//? if (UTF8) {
case "utf8":
return this.toUTF8(begin, end);
//? } if (BASE64) {
case "base64":
return this.toBase64(begin, end);
//? } if (HEX) {
case "hex":
return this.toHex(begin, end);
//? } if (BINARY) {
case "binary":
return this.toBinary(begin, end);
//? } if (DEBUG) {
case "debug":
return this.toDebug();
case "columns":
return this.toColumns();
//? }
//? } // ENCODINGS
default:
throw Error("Unsupported encoding: "+encoding);
}
};