Skip to content

Commit

Permalink
Blob: add capability
Browse files Browse the repository at this point in the history
For cases where we can't figure out how to decode something without
decoding something else first.

Closes #9.
  • Loading branch information
pabigot committed Nov 20, 2015
1 parent 002bd5c commit 58bb760
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

buffer-layout is a utility module implemented in pure JavaScript that
supports translations between JavaScript values and Buffers. It is made
available under the MIT license.
available through [github](https://github.com/pabigot/buffer-layout) and
released under the MIT license.

Layout support is provided for these types of data:

Expand All @@ -14,7 +15,8 @@ Layout support is provided for these types of data:
* Bit fields within 8, 16, 24, or 32-bit unsigned integers, numbering
from the least or most significant bit;
* Unions of variant layouts where the type of data is recorded in a
prefix value.
prefix value, another layout element, or provided externally;
* Blobs of fixed length raw data.

## Installation

Expand Down
37 changes: 36 additions & 1 deletion lib/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
* determine the layout used to interpret the remainder of the span.
* * {@link module:Layout~BitStructure|BitStructure}s that contain a
* sequence of individual {@link module:Layout~BitField|BitField}s
* packed into an 8, 16, 24, or 32-bit unsigned integer.
* packed into an 8, 16, 24, or 32-bit unsigned integer;
* * {@link module:Layout~Blob|Blobs} of fixed length.
*
* All {@link module:Layout~Layout|Layout} instances are immutable
* after construction, to prevent internal state from becoming
Expand All @@ -94,6 +95,7 @@
* @local VariantLayout
* @local BitStructure
* @local BitField
* @local Blob
* @module Layout
* @license MIT
* @author Peter A. Bigot
Expand Down Expand Up @@ -1336,6 +1338,38 @@ BitField.prototype.encode = function (value) {
this.container._packedSetValue((word & ~this.word_mask) | word_value);
};

/** Contain an arbitrary block of data of fixed length, represented as
* a Buffer.
*
* @param {Number} length - the number of bytes in the blob.
*
* @constructor
* @augments {Layout} */
function Blob (length, property) {
if (! Number.isInteger(length)) {
throw new TypeError("length must be unsigned integer");
}
Layout.call(this, length, property);
Object.freeze(this);
}
Blob.prototype = Object.create(Layout.prototype);
Blob.prototype.constructor = Blob;
/** Implement {@link Layout#decode|decode} for {@link Blob|Blob}. */
Blob.prototype.decode = function (b, offset, dest) {
if (undefined === offset) {
offset = 0;
}
return b.slice(offset, offset + this.span);
};
/** Implement {@link Layout#encode|encode} for {@link Blob|Blob}. */
Blob.prototype.encode = function (src, b, offset) {
if (! ((src instanceof Buffer)
&& (this.span === src.length))) {
throw new Error("Blob.encode requires length " + this.span + " Buffer as src");
}
b.write(src.toString('hex'), offset, this.span, 'hex');
};

exports.Layout = Layout;
exports.UInt = UInt;
exports.UIntBE = UIntBE;
Expand All @@ -1353,6 +1387,7 @@ exports.Union = Union;
exports.VariantLayout = VariantLayout;
exports.BitStructure = BitStructure;
exports.BitField = BitField;
exports.Blob = Blob;

/** Factory for {@link UInt|unsigned int layouts} spanning one
* byte. */
Expand Down
25 changes: 25 additions & 0 deletions test/LayoutTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,4 +838,29 @@ suite("Layout", function () {
assert.equal(Buffer('2500a0', 'hex').compare(b), 0);
});
});
suite("Blob", function () {
test("invalid ctor", function () {
assert.throws(function () { new lo.Blob(); }, TypeError);
assert.throws(function () { new lo.Blob(lo.u8()); }, TypeError);
});
test("ctor", function () {
var bl = new lo.Blob(3, 'bl');
assert(bl instanceof lo.Blob);
assert(bl instanceof lo.Layout);
assert.equal(bl.span, 3);
assert.equal(bl.property, 'bl');
});
test("basics", function () {
var bl = new lo.Blob(3, 'bl'),
b = Buffer("0102030405", 'hex'),
bv = bl.decode(b);
assert(bv instanceof Buffer);
assert.equal(bv.length, bl.span);
assert.equal(Buffer("010203", 'hex').compare(bv), 0);
bv = bl.decode(b, 2);
assert.equal(Buffer("030405", 'hex').compare(bv), 0);
bl.encode(Buffer("112233", 'hex'), b, 1);
assert.equal(Buffer("0111223305", 'hex').compare(b), 0);
});
});
});

0 comments on commit 58bb760

Please sign in to comment.