Skip to content

Commit

Permalink
Structure: add fromArray helper function
Browse files Browse the repository at this point in the history
Useful when constructing a compatible object from a argument list.

Closes issue #3
  • Loading branch information
pabigot committed Oct 25, 2015
1 parent fa505d1 commit a352cd3
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
51 changes: 49 additions & 2 deletions lib/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ if (!Object.assign) {
* Layout#encode|encode} or {@link Layout#decode|decode} functions.
*
* **NOTE** All instances of concrete extensions of this class are
* frozen prior to being returned from the construtor so that state
* frozen prior to being returned from the constructor so that state
* relationships between layouts are not inadvertently corrupted.
*
* @param {Number} span - Default for {@link Layout#span|span}. The
Expand Down Expand Up @@ -207,6 +207,31 @@ Layout.prototype.replicate = function (property) {
return rv;
};

/** Create an object from layout properties and an array of values.
*
* **NOTE** This function returns `undefined` if invoked on a layout
* that does not return its value as an Object. That would generally
* be anything that isn't fundamentally a {@link Structure|Structure},
* which includes {@link VariantLayout|variant layouts} if they are
* structures, and excludes {@link Union|Union}s. If you want this
* feature for a union you must use {@link
* Union.getVariant|getVariant} to select the desired layout.
*
* @param {Array} values - an array of values that correspond to the
* default order for properties. As with {@link Layout#decode|decode}
* layout elements that have no property name are skipped when
* iterating over the array values. Only the top-level properties are
* assigned; arguments are not assigned to properties of contained
* layouts. Any unused values are ignored.
*
* @param {Object} dest - as with {@link Layout#decode|decode}. If
* required but not provided an empty Object will be used.
*
* @return {(Object|undefined)} */
Layout.prototype.fromArray = function () {
return undefined;
};

/** Represent an unsigned integer in little-endian format.
*
* @param {Number} span - initializer for {@link Layout#span|span}.
Expand Down Expand Up @@ -591,7 +616,7 @@ Structure.prototype.encode = function (src, b, offset) {
if (undefined === offset) {
offset = 0;
}
this.fields.map(function (fd) {
this.fields.forEach(function (fd) {
if (undefined !== fd.property) {
var fv = src[fd.property];
if (undefined === fv) {
Expand All @@ -603,6 +628,20 @@ Structure.prototype.encode = function (src, b, offset) {
offset += fd.span;
});
};
/** Implement {@link Layout#fromArray|fromArray} for {@link
* Structure|Structure}. */
Structure.prototype.fromArray = function (values, dest) {
if (undefined === dest) {
dest = {};
}
this.fields.forEach(function (fd) {
if ((undefined !== fd.property)
&& (0 < values.length)) {
dest[fd.property] = values.shift();
}
});
return dest;
};

/** Represent any number of span-compatible layouts.
*
Expand Down Expand Up @@ -856,6 +895,14 @@ VariantLayout.prototype.encode = function (src, b, offset) {
dlo.encode(this.variant, b, offset);
this.layout.encode(src, b, offset + dlo.span);
};
/** Implement {@link Layout#fromArray|fromArray} for {@link
* VariantLayout|VariantLayout}. */
VariantLayout.prototype.fromArray = function (values, dest) {
if (this.layout instanceof Structure) {
return this.layout.fromArray(values, dest);
}
return undefined;
};

exports.Layout = Layout;
exports.UInt = UInt;
Expand Down
13 changes: 13 additions & 0 deletions test/LayoutTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,4 +529,17 @@ suite("Layout", function () {
assert.equal('payload', un.layout.fields[1].property);
});
});
test("fromArray", function () {
assert.strictEqual(undefined, lo.u8().fromArray([1]));
var st = new lo.Structure([lo.u8('a'), lo.u8('b'), lo.u16('c')]);
assert(_.isEqual({a:1, b:2, c:3}, st.fromArray([1,2,3])));
assert(_.isEqual({a:1, b:2}, st.fromArray([1,2])));
var un = new lo.Union(lo.u8('v'), lo.u32('c'));
assert.strictEqual(undefined, un.fromArray([1,2,3]));
var v1 = un.addVariant(1, st),
v2 = un.addVariant(2, lo.f32());
assert(v1 instanceof lo.VariantLayout);
assert(_.isEqual({a:1, b:2, c:3}, un.getVariant(1).fromArray([1,2,3])));
assert.strictEqual(undefined, un.getVariant(2).fromArray([1,2,3]));
});
});

0 comments on commit a352cd3

Please sign in to comment.