123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005 |
- /*
- Copyright 2013 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.
- */
- var ByteBuffer = require("../dist/bytebuffer-node.js");
- var ByteBufferNode = ByteBuffer;
- var ByteBufferBrowser = require("../dist/bytebuffer.min.js");
- var ByteBufferBrowser_DataView = require("../dist/bytebuffer-dataview.min.js");
- var pkg = require("../package.json");
- /**
- * Constructs a new Sandbox for module loaders and shim testing.
- * @param {Object.<string,*>} properties Additional properties to set
- * @constructor
- */
- var Sandbox = function(properties) {
- this.Int8Array = function() {};
- this.Uint8Array = function() {};
- this.Int16Array = function() {};
- this.Uint16Array = function() {};
- this.Int32Array = function() {};
- this.Uint32Array = function() {};
- this.Float32Array = function() {};
- this.Float64Array = function() {};
- this.DataView = function() {};
- for (var i in properties) {
- this[i] = properties[i];
- }
- this.console = {
- log: function(s) {
- console.log(s);
- }
- };
- };
- function makeSuite(ByteBuffer) {
- var type = ByteBuffer.type(), // Buffer or ArrayBuffer
- accessor = ByteBuffer.accessor(),
- Long = ByteBuffer.Long;
- var suite = {};
-
- suite.init = function(test) {
- test.ok(require("../index.js"));
- if (ByteBuffer == ByteBufferNode)
- test.log("\n\n --- ByteBufferNB ---\n".bold.white),
- test.log("[optional] node-memcpy is "+(ByteBuffer.memcpy ? "present" : "not present"));
- else if (ByteBuffer == ByteBufferBrowser)
- test.log("\n\n --- ByteBufferAB ---\n".bold.white);
- else if (ByteBuffer == ByteBufferBrowser_DataView)
- test.log("\n\n --- ByteBufferAB_DataView ---\n".bold.white);
- test.ok(type === Buffer || type === ArrayBuffer);
- test.ok(typeof ByteBuffer == "function");
- test.strictEqual(pkg.version, ByteBuffer.VERSION);
- test.done();
- };
-
- suite.base = {};
-
- suite.base.allocate = function(test) {
- var bb = new ByteBuffer();
- test.ok(bb.buffer instanceof type);
- test.equal(bb.offset, 0);
- test.equal(bb.limit, ByteBuffer.DEFAULT_CAPACITY);
- test.equal(bb.littleEndian, ByteBuffer.DEFAULT_ENDIAN);
- test.equal(bb.noAssert, ByteBuffer.DEFAULT_NOASSERT);
- if (type === Buffer)
- test.equal(bb.buffer.length, bb.capacity());
- else
- test.equal(bb.buffer.byteLength, bb.capacity());
- test.equal(bb.capacity(), ByteBuffer.DEFAULT_CAPACITY);
- bb = ByteBuffer.allocate(undefined, !ByteBuffer.DEFAULT_ENDIAN, !ByteBuffer.DEFAULT_NOASSERT);
- test.equal(bb.capacity(), ByteBuffer.DEFAULT_CAPACITY);
- test.equal(bb.littleEndian, !ByteBuffer.DEFAULT_ENDIAN);
- test.equal(bb.noAssert, !ByteBuffer.DEFAULT_NOASSERT);
- // __isByteBuffer__
- test.strictEqual(bb.__isByteBuffer__, true);
- bb.__isByteBuffer__ = false;
- test.strictEqual(bb.__isByteBuffer__, true);
- test.equal(ByteBuffer.isByteBuffer(bb), true);
- // Fixed set of properties
- for (var i in bb)
- if (bb.hasOwnProperty(i) && ["offset", "markedOffset", "limit", "littleEndian", "noAssert", "buffer", "view"].indexOf(i) < 0)
- test.fail("Illegal enumerable property: "+i);
- test.done();
- };
- suite.base.clone = function(test) {
- var bb = new ByteBuffer(1, true, false);
- var bb2 = bb.clone();
- test.strictEqual(bb.buffer, bb2.buffer);
- test.equal(bb.offset, bb2.offset);
- test.equal(bb.limit, bb2.limit);
- test.equal(bb.markedOffset, bb2.markedOffset);
- test.equal(bb.littleEndian, bb2.littleEndian);
- test.equal(bb.noAssert, bb2.noAssert);
- test.notStrictEqual(bb, bb2);
- test.done();
- };
-
- suite.base.assert = function(test) {
- var bb = new ByteBuffer();
- test.strictEqual(bb.noAssert, false);
- test.strictEqual(bb.assert(false), bb);
- test.strictEqual(bb.noAssert, true);
- test.strictEqual(bb.assert(true), bb);
- test.strictEqual(bb.noAssert, false);
- test.done();
- };
-
- suite.wrap = {};
-
- if (type === Buffer) {
- suite.wrap.Buffer = function(test) {
- var buf = new Buffer(1);
- buf[0] = 0x01;
- var bb = ByteBuffer.wrap(buf);
- test.strictEqual(bb.capacity(), 1);
- test.strictEqual(bb.buffer, buf);
- test.strictEqual(bb.toDebug(), "<01>");
- test.done();
- };
- }
-
- suite.wrap.ArrayBuffer = function(test) {
- var buf = new ArrayBuffer(1);
- var bb = ByteBuffer.wrap(buf);
- test.strictEqual(bb.capacity(), 1);
- if (type === ArrayBuffer)
- test.strictEqual(bb.buffer, buf);
- else
- test.ok(bb.buffer instanceof Buffer);
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 1);
- test.done();
- };
-
- suite.wrap.Uint8Array = function(test) {
- // Full view
- var buf = new Uint8Array(1);
- buf[0] = 0x01;
- var bb = ByteBuffer.wrap(buf);
- test.strictEqual(bb.capacity(), 1);
- if (type === ArrayBuffer)
- test.strictEqual(bb.buffer, buf.buffer);
- else
- test.ok(bb.buffer instanceof Buffer);
- test.strictEqual(bb.toDebug(), "<01>");
- // Partial view (not on node, node copies)
- if (type === ArrayBuffer) {
- buf = new Uint8Array(3);
- buf[0] = 0x01; buf[1] = 0x02; buf[2] = 0x03;
- buf = new Uint8Array(buf.buffer, 1, 1);
- bb = ByteBuffer.wrap(buf);
- test.strictEqual(bb.capacity(), 3);
- test.strictEqual(bb.toDebug(), "01<02>03");
- }
-
- test.done();
- };
-
- suite.wrap.Array = function(test) {
- var arr = [1,255,-1];
- var bb = ByteBuffer.wrap(arr);
- test.strictEqual(bb.capacity(), 3);
- test.strictEqual(bb.toDebug(), "<01 FF FF>");
- test.done();
- };
- suite.wrap.ByteBuffer = function(test) {
- var bb2 = ByteBuffer.wrap("\x12\x34\x56\x78", "binary");
- bb2.offset = 1;
- var bb = ByteBuffer.wrap(bb2);
- test.strictEqual(bb2.offset, bb.offset);
- test.strictEqual(bb2.limit, bb.limit);
- test.strictEqual(bb2.capacity(), bb.capacity());
- test.strictEqual(bb2.toString("debug"), bb.toString("debug"));
- test.done();
- };
-
- suite.wrap.string = function(test) {
- var bb = ByteBuffer.wrap("\u0061\u0062");
- test.equal(bb.toDebug(), "<61 62>");
- test.done();
- };
-
- suite.encodings = {};
-
- suite.encodings.UTF8 = function(test) {
- ["aäöü߀b", ""].forEach(function(str) {
- var bb = ByteBuffer.wrap(str, "utf8"); // Calls ByteBuffer#fromUTF8
- test.strictEqual(bb.toUTF8(), str);
- if (str.length > 2) {
- bb.offset = 1;
- bb.limit = bb.capacity()-1;
- test.strictEqual(bb.toUTF8(), str.substring(1, str.length-1));
- }
- });
- test.done();
- };
- suite.encodings.debug = function(test) {
- ["60<61 62]63", "<60 61 62 63]", "|", "|61", "<61>", "!12"].forEach(function(str) {
- var bb = ByteBuffer.wrap(str, "debug"); // Calls ByteBuffer#fromDebug
- test.equal(bb.toDebug(), str);
- });
- test.done();
- };
-
- suite.encodings.binary = function(test) {
- ["\x61\x62\x63\x64", "", " "].forEach(function(str) {
- var bb = ByteBuffer.wrap(str, "binary"); // Calls ByteBuffer#fromBinary
- test.strictEqual(bb.toBinary(), str);
- if (str.length > 2) {
- bb.offset = 1;
- bb.limit = bb.capacity()-1;
- test.strictEqual(bb.toBinary(), str.substring(1, str.length-1));
- }
- });
- test.done();
- };
-
- suite.encodings.hex = function(test) {
- ["61626364", "61", ""].forEach(function(str) {
- var bb = ByteBuffer.wrap(str, "hex"); // Calls ByteBuffer#fromHex
- test.strictEqual(bb.toHex(), str);
- if (str.length > 2) {
- bb.offset = 1;
- bb.limit = bb.capacity()-1;
- test.strictEqual(bb.toHex(), str.substring(2, str.length-2));
- }
- });
- test.done();
- };
-
- suite.encodings.base64 = function(test) {
- ["", "YWI=", "YWJjZGVmZw==", "YWJjZGVmZ2g=", "YWJjZGVmZ2hp"].forEach(function(str) {
- var bb = ByteBuffer.wrap(str, "base64"); // Calls ByteBuffer#fromBase64
- test.strictEqual(bb.toBase64(), str);
- if (str.length > 8) {
- bb.offset = 3;
- bb.limit = bb.offset + 3;
- test.strictEqual(bb.toBase64(), str.substr(4, 4));
- }
- });
- test.done();
- };
-
- suite.methods = {};
-
- suite.methods.concat = function(test) {
- var bbs = [
- new ArrayBuffer(1),
- ByteBuffer.fromDebug('00<01 02>'),
- ByteBuffer.fromDebug('00 01 02<03>00'),
- ByteBuffer.fromDebug('00|'),
- ByteBuffer.fromDebug('<04>'),
- type === Buffer ? new Buffer(0) : new ArrayBuffer(0),
- new Uint8Array(0),
- '05'
- ];
- var bb = ByteBuffer.concat(bbs, 'hex', !ByteBuffer.DEFAULT_ENDIAN, !ByteBuffer.DEFAULT_NOASSERT);
- test.strictEqual(bb.littleEndian, !ByteBuffer.DEFAULT_ENDIAN);
- test.strictEqual(bb.noAssert, !ByteBuffer.DEFAULT_NOASSERT);
- test.equal(bb.toDebug(), '<00 01 02 03 04 05>');
- bb = ByteBuffer.concat([]);
- test.strictEqual(bb.buffer, new ByteBuffer(0).buffer); // EMPTY_BUFFER
- test.done();
- };
-
- suite.methods.resize = function(test) {
- var bb = new ByteBuffer(1);
- bb.offset = 1;
- bb.resize(2);
- bb.fill(0, 0, 2);
- test.equal(bb.capacity(), 2);
- test.equal(bb.toDebug(), "00|00");
- test.done();
- };
- suite.methods.ensureCapacity = function(test) {
- var bb = new ByteBuffer(5);
- test.equal(bb.capacity(), 5);
- bb.ensureCapacity(6); // Doubles
- test.equal(bb.capacity(), 10);
- bb.ensureCapacity(21); // Uses 21
- test.equal(bb.capacity(), 21);
- test.done();
- };
-
- suite.methods.slice = function(test) {
- var bb = new ByteBuffer.wrap("\x12\x34\x56"),
- bb2 = bb.slice(1,2);
- test.strictEqual(bb.buffer, bb2.buffer);
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 3);
- test.equal(bb2.offset, 1);
- test.equal(bb2.limit, 2);
- test.done();
- };
-
- suite.methods.flip = function(test) {
- var bb = ByteBuffer.wrap('\x12\x34\x56\x78');
- bb.offset = 4;
- test.equal(bb.offset, 4);
- test.equal(bb.limit, 4);
- bb.flip();
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 4);
- test.done();
- };
-
- suite.methods.mark = function(test) {
- var bb = ByteBuffer.wrap('\x12\x34\x56\x78');
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 4);
- test.equal(bb.markedOffset, -1);
- bb.mark();
- test.equal(bb.markedOffset, 0);
- test.done();
- };
-
- suite.methods.reset = function(test) {
- var bb = ByteBuffer.wrap('\x12\x34\x56\x78');
- bb.reset();
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 4);
- bb.offset = 1;
- bb.mark();
- test.equal(bb.markedOffset, 1);
- bb.reset();
- test.equal(bb.offset, 1);
- test.equal(bb.markedOffset, -1);
- test.done();
- };
-
- suite.methods.copy = function(test) {
- var bb = ByteBuffer.wrap("\x01", !ByteBuffer.DEFAULT_ENDIAN),
- bb2 = bb.copy();
- test.equal(bb.offset, 0);
- test.notStrictEqual(bb, bb2);
- test.notStrictEqual(bb.buffer, bb2.buffer);
- test.equal(bb2.offset, bb.offset);
- test.equal(bb2.limit, bb.limit);
- test.equal(bb2.markedOffset, bb.markedOffset);
- test.equal(bb2.littleEndian, bb.littleEndian);
- test.equal(bb2.noAssert, bb.noAssert);
- test.done();
- };
-
- suite.methods.copyTo = function(test) {
- var bb = ByteBuffer.wrap("\x01"),
- bb2 = new ByteBuffer(2).fill(0).flip();
- test.equal(bb.toDebug(), "<01>");
- // Modifies source and target offsets
- bb.copyTo(bb2 /* all offsets omitted */);
- test.equal(bb.toDebug(), "01|"); // Read 1 byte
- test.equal(bb2.toDebug(), "01<00>"); // Written 1 byte
- bb.reset();
- test.equal(bb.toDebug(), "<01>");
- // Again, but with bb2.offset=1
- bb.copyTo(bb2 /* all offsets omitted */);
- test.equal(bb.toDebug(), "01|"); // Read 1 byte
- test.equal(bb2.toDebug(), "01 01|"); // Written 1 byte at 2
- bb.reset();
- bb2.clear().fill(0).flip();
- // Modifies source offsets only
- bb.copyTo(bb2, 0 /* source offsets omitted */);
- test.equal(bb.toDebug(), "01|"); // Read 1 byte
- test.equal(bb2.toDebug(), "<01 00>"); // Written 1 byte (no change)
- // Modifies no offsets at all
- bb.reset();
- bb2.fill(0).flip();
- bb.copyTo(bb2, 1, 0, bb.capacity() /* no offsets omitted */);
- test.equal(bb.toDebug(), "<01>"); // Read 1 byte (no change)
- test.equal(bb2.toDebug(), "<00 01>"); // Written 1 byte (no change)
- test.done();
- };
-
- suite.methods.compact = function(test) {
- var bb = ByteBuffer.wrap("\x01\x02");
- bb.limit = 1;
- bb.markedOffset = 2;
- var prevBuffer = bb.buffer,
- prevView = bb.view;
- bb.compact();
- test.notStrictEqual(bb.buffer, prevBuffer);
- if (type === ArrayBuffer) {
- test.notStrictEqual(bb.buffer, prevView);
- }
- test.equal(bb.capacity(), 1);
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 1);
- test.equal(bb.markedOffset, 2); // Actually out of bounds
-
- // Empty region
- bb.offset = 1;
- prevBuffer = bb.buffer;
- bb.compact();
- test.notStrictEqual(bb.buffer, prevBuffer);
- test.strictEqual(bb.buffer, new ByteBuffer(0).buffer); // EMPTY_BUFFER
- if (type === ArrayBuffer) {
- test.strictEqual(bb.view, null);
- }
- test.equal(bb.capacity(), 0);
- test.equal(bb.offset, 0);
- test.equal(bb.limit, 0);
- test.done();
- };
-
- suite.methods.reverse = function(test) {
- var bb = ByteBuffer.wrap("\x12\x34\x56\x78");
- bb.reverse(1, 3);
- test.equal(bb.toString("debug"), "<12 56 34 78>");
- bb.reverse();
- test.equal(bb.toString("debug"), "<78 34 56 12>");
- bb.offset = 1;
- bb.limit = 3;
- bb.reverse();
- test.equal(bb.toString("debug"), "78<56 34>12");
- bb.reverse(0, 4).clear();
- test.equal(bb.toString("debug"), "<12 34 56 78>");
- test.done();
- };
-
- suite.methods.append = function(test) {
- var bb = ByteBuffer.wrap("\x12\x34");
- var bb2 = ByteBuffer.wrap("\x56\x78");
- bb.offset = 2;
- bb.append(bb2); // Modifies offsets of both
- test.equal(bb.toString("debug"), "12 34>56 78<");
- test.equal(bb2.toString("debug"), "56 78|");
- bb2.reset();
- bb.append(bb2, 1); // Modifies offsets of bb2 only
- test.equal(bb.toString("debug"), "12 56>78 78<");
- test.equal(bb2.toString("debug"), "56 78|");
- test.done();
- };
-
- suite.methods.prepend = function(test) {
- var bb = ByteBuffer.wrap("\x12\x34"),
- bb2 = ByteBuffer.wrap("\x56\x78");
- test.strictEqual(bb.prepend(bb2), bb); // Relative prepend at 0, 2 bytes (2 overflow)
- test.equal(bb.toDebug(), "<56 78 12 34>");
- test.equal(bb2.toDebug(), "56 78|");
- bb.offset = 4;
- bb2.offset = 1;
- bb.prepend(bb2, 3); // Absolute prepend at 3, 1 byte
- test.equal(bb.toDebug(), "56 78 78 34|");
- test.equal(bb2.toDebug(), "56 78|");
- bb2.offset = 0;
- bb.prepend(bb2); // Relative prepend at 4, 2 bytes
- test.equal(bb.toDebug(), "56 78<56 78>");
- test.equal(bb2.toDebug(), "56 78|");
- bb.offset = 3;
- bb2.offset = 0;
- test.throws(function() {
- bb.prepend(bb2, 6); // Absolute out of bounds
- }, RangeError);
- bb.prepend("abcde", "utf8"); // Relative prepend at 3, 5 bytes (1 overflow)
- test.equal(bb.toDebug(), "<61 62 63 64 65 78>");
- test.done();
- };
-
- suite.methods.prependTo = function(test) {
- var bb = ByteBuffer.wrap("\x12\x34"),
- bb2 = ByteBuffer.wrap("\x56\x78");
- test.strictEqual(bb2.prependTo(bb), bb2);
- test.equal(bb.toDebug(), "<56 78 12 34>");
- test.equal(bb2.toDebug(), "56 78|");
- test.done();
- };
-
- suite.methods.remaining = function(test) {
- var bb = ByteBuffer.wrap("\x12\x34");
- test.strictEqual(bb.remaining(), 2);
- bb.offset = 2;
- test.strictEqual(bb.remaining(), 0);
- bb.offset = 3;
- test.strictEqual(bb.remaining(), -1);
- test.done();
- };
-
- suite.methods.skip = function(test) {
- var bb = ByteBuffer.wrap("\x12\x34\x56");
- test.strictEqual(bb.offset, 0);
- bb.skip(3);
- test.strictEqual(bb.offset, 3);
- test.strictEqual(bb.noAssert, false);
- test.throws(function() {
- bb.skip(1);
- });
- test.strictEqual(bb.offset, 3);
- bb.noAssert = true;
- test.doesNotThrow(function() {
- bb.skip(1);
- });
- test.strictEqual(bb.offset, 4);
- test.done();
- };
-
- suite.methods.order = function(test) {
- test.strictEqual(ByteBuffer.LITTLE_ENDIAN, true);
- test.strictEqual(ByteBuffer.BIG_ENDIAN, false);
- var bb = new ByteBuffer(2);
- test.strictEqual(bb.littleEndian, false);
- bb.writeInt32(0x12345678);
- bb.flip();
- test.strictEqual(bb.toHex(), "12345678");
- bb.clear();
- test.strictEqual(bb.LE(), bb);
- test.strictEqual(bb.littleEndian, true);
- bb.writeInt32(0x12345678);
- bb.flip();
- test.strictEqual(bb.toHex(), "78563412");
- test.strictEqual(bb.BE(), bb);
- test.strictEqual(bb.littleEndian, false);
- test.strictEqual(bb.order(ByteBuffer.LITTLE_ENDIAN), bb);
- test.strictEqual(bb.littleEndian, true);
- test.strictEqual(bb.order(ByteBuffer.BIG_ENDIAN), bb);
- test.strictEqual(bb.littleEndian, false);
- test.done();
- };
-
- var types = [
- // name | alias | size | input | output | BE representation
- ["Int8" , "Byte" , 1 , 0xFE , -2 , "fe" ],
- ["Uint8" , null , 1 , -2 , 0xFE , "fe" ],
- ["Int16" , "Short" , 2 , 0xFFFE , -2 , "fffe" ],
- ["Uint16" , null , 2 , -2 , 0xFFFE , "fffe" ],
- ["Int32" , "Int" , 4 , 0xFFFFFFFE , -2 , "fffffffe" ],
- ["Uint32" , null , 4 , -2 , 0xFFFFFFFE , "fffffffe" ],
- ["Float32" , "Float" , 4 , 0.5 , 0.5 , "3f000000" ],
- ["Float64" , "Double", 8 , 0.1 , 0.1 , "3fb999999999999a" ],
- ["Int64" , "Long" , 8 , new Long(0xFFFFFFFE, 0xFFFFFFFF, true) , new Long(0xFFFFFFFE, 0xFFFFFFFF, false) , "fffffffffffffffe" ],
- ["Uint64" , null , 8 , new Long(0xFFFFFFFE, 0xFFFFFFFF, false) , new Long(0xFFFFFFFE, 0xFFFFFFFF, true) , "fffffffffffffffe" ],
-
- // name | alias | size | input | output | representation
- ["Varint32" , null , 5 , 0xFFFFFFFE , -2 , "feffffff0f" ],
- ["Varint32ZigZag", null , 1 , -1 , -1 , "01" ],
- ["Varint64" , null , 10 , new Long(0xFFFFFFFE, 0xFFFFFFFF, true) , new Long(0xFFFFFFFE, 0xFFFFFFFF, false) , "feffffffffffffffff01"],
- ["Varint64ZigZag", null , 1 , Long.fromNumber(-1) , Long.fromNumber(-1) , "01" ]
- ];
-
- suite.types = {};
-
- types.forEach(function(type) {
- var name = type[0],
- varint = name.indexOf("Varint") >= 0,
- alias = type[1],
- size = type[2],
- input = type[3],
- output = type[4],
- be = type[5],
- le = "";
- for (var i=be.length; i>0; i-=2) {
- le += be.substr(i-2, 2);
- }
- suite.types[name.toLowerCase()] = function(test) {
- var bb = new ByteBuffer(size);
- // Relative BE (always LE for varints)
- test.strictEqual(bb["write"+name](input), bb);
- bb.flip();
- var val = bb["read"+name]();
- if (output instanceof Long) {
- test.deepEqual(val, output);
- } else {
- test.strictEqual(val, output);
- }
- bb.flip();
- test.strictEqual(bb.toHex(), be);
- if (!varint) {
- // Relative LE
- bb.LE();
- bb["write"+name](input);
- bb.flip();
- val = bb["read"+name]();
- if (output instanceof Long) {
- test.deepEqual(val, output);
- } else {
- test.strictEqual(val, output);
- }
- bb.flip();
- test.strictEqual(bb.toHex(), le);
- }
- test.throws(function() { // OOB
- bb.offset = bb.capacity() - size + 1;
- bb["read"+name](input);
- });
- test.doesNotThrow(function() { // OOB, automatic resizing * 2
- bb["write"+name](input);
- });
- test.strictEqual(bb.capacity(), size * 2);
- // Absolute
- bb.clear();
- if (!varint)
- test.strictEqual(bb["write"+name](input, 1), bb);
- else
- test.strictEqual(bb["write"+name](input, 1), size);
- val = bb["read"+name](1);
- if (output instanceof Long) {
- if (!varint)
- test.deepEqual(val, output);
- else
- test.deepEqual(val, {value: output, length: size});
- } else {
- if (!varint)
- test.strictEqual(val, output);
- else
- test.deepEqual(val, {value: output, length: size});
- }
- // Alias
- if (alias) {
- test.strictEqual(bb["write"+name], bb["write"+alias]);
- test.strictEqual(bb["read"+name], bb["read"+alias]);
- }
- test.done();
- };
- });
-
- suite.types.bitset = function(test) {
- var bb = new ByteBuffer(2),
- arr;
- function run(data) {
- bb.reset();
- bb.writeBitSet(data);
- bb.reset();
- test.deepEqual(bb.readBitSet(),data);
- };
- run([]);
- run([true]);
- run([false]);
- run([false,true]);
- run([false,false,false,false,false,false,false,false]);
- run([true,false,true,false,true,false,true,false]);
- run([true,true,true,true,true,true,true,true]);
- run([true,false,true,false,true,false,true,false]);
- run([true,false,true,false,true,false,true,false,true]);
-
- bb.reset();
- bb.writeBitSet([,null,"",0,42,"hello world",new Date(0),{},[]]);
- bb.reset();
- test.deepEqual(bb.readBitSet(),[false,false,false,false,true,true,true,true,true]);
- test.done();
- };
- suite.types.calculateVarint = function(test) {
- test.equal(ByteBuffer.MAX_VARINT32_BYTES, 5);
- test.equal(ByteBuffer.MAX_VARINT64_BYTES, 10);
- var values = [
- [0, 1],
- [-1, 5, 10],
- [1<<7, 2],
- [1<<14, 3],
- [1<<21, 4],
- [1<<28, 5],
- [0x7FFFFFFF | 0, 5],
- [0xFFFFFFFF, 5],
- [0xFFFFFFFF | 0, 5, 10]
- ];
- for (var i=0; i<values.length; i++) {
- test.equal(ByteBuffer.calculateVarint32(values[i][0]), values[i][1]);
- test.equal(ByteBuffer.calculateVarint64(values[i][0]), values[i].length > 2 ? values[i][2] : values[i][1]);
- }
- var Long = ByteBuffer.Long;
- values = [
- [Long.fromNumber(1).shiftLeft(35), 6],
- [Long.fromNumber(1).shiftLeft(42), 7],
- [Long.fromNumber(1).shiftLeft(49), 8],
- [Long.fromNumber(1).shiftLeft(56), 9],
- [Long.fromNumber(1).shiftLeft(63), 10],
- [Long.fromNumber(1, true).shiftLeft(63), 10]
- ];
- for (i=0; i<values.length; i++) {
- test.equal(ByteBuffer.calculateVarint64(values[i][0]), values[i][1]);
- }
- test.done();
- };
-
- suite.types.zigZagVarint = function(test) {
- var Long = ByteBuffer.Long;
- var values = [
- [ 0, 0],
- [-1, 1],
- [ 1, 2],
- [-2, 3],
- [ 2, 4],
- [-3, 5],
- [ 3, 6],
- [ 2147483647, 4294967294],
- [-2147483648, 4294967295]
- ];
- for (var i=0; i<values.length; i++) {
- test.equal(ByteBuffer.zigZagEncode32(values[i][0]), values[i][1]);
- test.equal(ByteBuffer.zigZagDecode32(values[i][1]), values[i][0]);
- test.equal(ByteBuffer.zigZagEncode64(values[i][0]).toNumber(), values[i][1]);
- test.equal(ByteBuffer.zigZagDecode64(values[i][1]).toNumber(), values[i][0]);
- }
- values = [
- [Long.MAX_VALUE, Long.MAX_UNSIGNED_VALUE.subtract(Long.ONE)],
- [Long.MIN_VALUE, Long.MAX_UNSIGNED_VALUE]
- ];
- // NOTE: Even 64bit doubles from toNumber() fail for these values so we are using toString() here
- for (i=0; i<values.length; i++) {
- test.equal(ByteBuffer.zigZagEncode64(values[i][0]).toString(), values[i][1].toString());
- test.equal(ByteBuffer.zigZagDecode64(values[i][1]).toString(), values[i][0].toString());
- }
-
- // 32 bit ZZ
- values = [
- 0,
- 1,
- 300,
- -300,
- 2147483647,
- -2147483648
- ];
- bb = new ByteBuffer(10);
- for (i=0; i<values.length; i++) {
- var encLen = bb.writeVarint32ZigZag(values[i], 0);
- bb.limit = encLen;
- var dec = bb.readVarint32ZigZag(0);
- test.equal(dec['value'], values[i]);
- test.equal(encLen, dec['length']);
- bb.clear();
- }
-
- // 64 bit ZZ
- values = [
- Long.ONE, 1,
- Long.fromNumber(-3),
- Long.fromNumber(300),
- Long.fromNumber(-300),
- Long.fromNumber(0x7FFFFFFF),
- Long.fromNumber(0x8FFFFFFF),
- Long.fromNumber(0xFFFFFFFF),
- Long.fromBits(0xFFFFFFFF, 0x7FFFFFFF),
- Long.fromBits(0xFFFFFFFF, 0xFFFFFFFF)
- ];
- var bb = new ByteBuffer(10);
- for (i=0; i<values.length; i++) {
- encLen = bb.writeVarint64ZigZag(values[i], 0);
- dec = bb.readVarint64ZigZag(0);
- test.equal(values[i].toString(), dec['value'].toString());
- test.equal(encLen, dec['length']);
- }
- test.done();
- };
-
- suite.types.utf8string = function(test) {
- var bb = new ByteBuffer(2);
- // Aliases
- test.strictEqual(bb.writeUTF8String, bb.writeString);
- test.strictEqual(bb.readUTF8String, bb.readString);
- var str = "ä☺𠜎️☁️", str2;
- // Writing
- test.strictEqual(bb.writeUTF8String(str), bb);
- bb.flip();
- // bb.printDebug();
- // Reading
- str2 = bb.readUTF8String(ByteBuffer.calculateUTF8Chars(str), ByteBuffer.METRICS_CHARS);
- // bb.printDebug();
- test.strictEqual(str2.length, str.length);
- test.strictEqual(str2, str);
- bb.reset();
- str2 = bb.readUTF8String(bb.limit, ByteBuffer.METRICS_BYTES);
- test.strictEqual(str2, str);
- test.done();
- };
- suite.types.istring = function(test) {
- var bb = new ByteBuffer(2);
- test.strictEqual(bb.writeIString("ab"), bb); // resizes to 4+2=6
- test.strictEqual(bb.capacity(), 6);
- test.strictEqual(bb.offset, 6);
- test.strictEqual(bb.limit, 2);
- bb.flip();
- test.equal(bb.toString("debug"), "<00 00 00 02 61 62>");
- test.deepEqual(bb.readIString(0), {"string": "ab", "length": 6});
- test.strictEqual(bb.readIString(), "ab");
- bb.reset();
- test.equal(bb.toString("debug"), "<00 00 00 02 61 62>");
- test.strictEqual(bb.readIString(), "ab");
- test.equal(bb.toString("debug"), "00 00 00 02 61 62|");
- test.done();
- };
-
- suite.types.vstring = function(test) {
- var bb = new ByteBuffer(2);
- bb.writeVString("ab"); // resizes to 2*2=4
- test.strictEqual(bb.capacity(), 4);
- test.strictEqual(bb.offset, 3);
- test.strictEqual(bb.limit, 2);
- bb.flip();
- test.equal(bb.toString("debug").substr(0, 10), "<02 61 62>");
- test.deepEqual(bb.readVString(0), {"string": "ab", "length": 3});
- test.equal(bb.toString("debug").substr(0, 10), "<02 61 62>");
- test.equal(bb.readVString(), "ab");
- test.equal(bb.toString("debug").substr(0, 9), "02 61 62|");
- test.done();
- };
-
- suite.types.cstring = function(test) {
- var bb = new ByteBuffer(2);
- bb.writeCString("a");
- test.equal(bb.capacity(), 2);
- test.equal(bb.offset, 2);
- test.equal(bb.limit, 2);
- bb.offset = 1;
- bb.writeCString("b"); // resizes to 4
- test.equal(bb.capacity(), 4);
- test.equal(bb.offset, 3);
- test.equal(bb.limit, 2);
- bb.flip();
- test.equal(bb.toString("debug").substr(0, 10), "<61 62 00>");
- test.deepEqual(bb.readCString(0), {"string": "ab", "length": 3});
- test.equal(bb.toString("debug").substr(0, 10), "<61 62 00>");
- test.equal(bb.readCString(), "ab");
- test.equal(bb.toString("debug").substr(0, 9), "61 62 00|");
- test.done();
- };
-
- suite.convert = {};
-
- suite.convert.toHex = function(test) {
- var bb = new ByteBuffer(4);
- bb.writeUint16(0x1234);
- bb.writeUint8(0x56);
- bb.flip();
- test.equal(bb.toHex(), "123456");
- test.strictEqual(bb.offset, 0);
- test.equal(bb.toHex(1), "3456");
- test.equal(bb.toHex(1,2), "34");
- test.equal(bb.toHex(1,1), "");
- test.throws(function() {
- bb.toHex(1,0);
- });
- test.done();
- };
-
- suite.convert.toBase64 = function(test) {
- var bb = new ByteBuffer(8);
- bb.writeUTF8String("abcdefg"); // 7 chars
- bb.flip();
- test.equal(bb.toBase64(), "YWJjZGVmZw==");
- test.strictEqual(bb.offset, 0);
- test.equal(bb.toBase64(3), "ZGVmZw==");
- test.equal(bb.toBase64(3,6), "ZGVm");
- test.equal(bb.toBase64(3,3), "");
- test.throws(function() {
- bb.toBase64(1,0);
- });
- test.done();
- };
-
- suite.convert.toBinary = function(test) {
- var bb = new ByteBuffer(5);
- bb.writeUint32(0x001234FF);
- bb.flip();
- test.strictEqual(bb.toBinary(), "\x00\x12\x34\xFF");
- test.strictEqual(bb.offset, 0);
- test.done();
- };
-
- suite.convert.toString = function(test) {
- var bb = new ByteBuffer(3);
- bb.writeUint16(0x6162).flip();
- test.equal(bb.toString("hex"), "6162");
- test.equal(bb.toString("base64"), "YWI=");
- test.equal(bb.toString("utf8"), "ab");
- test.equal(bb.toString("debug").substr(0,7), "<61 62>");
- test.equal(bb.toString(), (type === ArrayBuffer ? (accessor === DataView ? "ByteBufferAB_DataView" : "ByteBufferAB") : "ByteBufferNB")+"(offset=0,markedOffset=-1,limit=2,capacity=3)");
- test.strictEqual(bb.offset, 0);
- test.done();
- };
-
- suite.convert.toBuffer = function(test) {
- var bb = new ByteBuffer(2);
- bb.writeUint16(0x1234).flip();
- var buf = bb.toBuffer();
- test.strictEqual(buf, bb.buffer);
- if (type === ArrayBuffer) {
- test.ok(buf instanceof ArrayBuffer);
- test.strictEqual(buf.byteLength, 2);
- } else {
- test.ok(buf instanceof Buffer);
- test.strictEqual(buf.length, 2);
- }
- bb.limit = 1;
- buf = bb.toBuffer();
- test.notStrictEqual(buf, bb.buffer);
- if (type === ArrayBuffer) {
- test.ok(buf instanceof ArrayBuffer);
- test.strictEqual(buf.byteLength, 1);
- } else {
- test.ok(buf instanceof Buffer);
- test.strictEqual(buf.length, 1);
- }
- test.done();
- };
-
- suite.convert.toArrayBuffer = function(test) {
- var bb = new ByteBuffer(3);
- if (type === ArrayBuffer) {
- test.strictEqual(bb.toArrayBuffer, bb.toBuffer);
- } else {
- test.ok(bb.buffer instanceof Buffer);
- bb.writeUint16(0x1234);
- bb.flip();
- bb.offset = 1;
- var ab = bb.toArrayBuffer();
- test.ok(ab instanceof ArrayBuffer);
- test.strictEqual(ab.byteLength, 1);
- }
- test.done();
- };
- suite.misc = {};
-
- suite.misc.pbjsi19 = function(test) {
- // test that this issue is fixed: https://github.com/dcodeIO/ProtoBuf.js/issues/19
- var bb = new ByteBuffer(9); // Trigger resize to 18 in writeVarint64
- bb.writeVarint32(16);
- bb.writeVarint32(2);
- bb.writeVarint32(24);
- bb.writeVarint32(0);
- bb.writeVarint32(32);
- bb.writeVarint64(ByteBuffer.Long.fromString("1368057600000"));
- bb.writeVarint32(40);
- bb.writeVarint64(ByteBuffer.Long.fromString("1235455123"));
- bb.flip();
- test.equal(bb.toString("debug").substr(0,52), "<10 02 18 00 20 80 B0 D9 B4 E8 27 28 93 99 8E CD 04>");
- test.done();
- };
-
- suite.misc.NaN = function(test) {
- var bb = new ByteBuffer(4);
- test.ok(isNaN(bb.writeFloat(NaN).flip().readFloat(0)));
- test.strictEqual(bb.writeFloat(+Infinity).flip().readFloat(0), +Infinity);
- test.strictEqual(bb.writeFloat(-Infinity).flip().readFloat(0), -Infinity);
- bb.resize(8);
- test.ok(isNaN(bb.writeDouble(NaN).flip().readDouble(0)));
- test.strictEqual(bb.writeDouble(+Infinity).flip().readDouble(0), +Infinity);
- test.strictEqual(bb.writeDouble(-Infinity).flip().readDouble(0), -Infinity);
- // Varints, however, always need a cast, which results in the following:
- test.strictEqual(NaN >>> 0, 0);
- test.strictEqual(NaN | 0, 0);
- test.strictEqual(Infinity >>> 0, 0);
- test.strictEqual(Infinity | 0, 0);
- test.strictEqual(-Infinity >>> 0, 0);
- test.strictEqual(-Infinity | 0, 0);
- test.done();
- };
- suite.debug = {};
- suite.debug.printDebug = function(test) {
- var bb = new ByteBuffer(3);
- function callMe() { callMe.called = true; }
- bb.printDebug(callMe);
- test.ok(callMe.called);
- test.done();
- };
-
- if (type === ArrayBuffer) {
- suite.debug.printDebugVisual = function(test) {
- var bb = ByteBuffer.wrap("Hello world! from byteBuffer.js. This is just a last visual test of ByteBuffer#printDebug.");
- console.log("");
- bb.printDebug(console.log);
- test.done();
- };
- }
-
- return suite;
- }
- module.exports = {
- "info": function(test) {
- test.log("Version "+ByteBuffer.VERSION+", "+new Date().toISOString()+"\n");
- test.done();
- },
- "node": makeSuite(ByteBufferNode),
- "browser": makeSuite(ByteBufferBrowser),
- "dataview": makeSuite(ByteBufferBrowser_DataView)
- };
|