Comparing version 0.0.5 to 0.0.6
@@ -15,3 +15,3 @@ import * as XDR from "../src"; | ||
}); | ||
}); | ||
@@ -31,2 +31,2 @@ | ||
console.log( xdr.Color.red() !== xdr.ResultType.ok() ); | ||
console.log( xdr.Color.red() !== xdr.ResultType.ok() ); |
import * as XDR from "../src"; | ||
let xdr = XDR.config(xdr => { | ||
xdr.enum('ResultType', { | ||
ok: 0, | ||
error: 1, | ||
nonsense: 2 | ||
}); | ||
@@ -16,3 +11,3 @@ xdr.union('Result', { | ||
}, | ||
defaultArm: xdr.void(), | ||
// defaultArm: xdr.void(), | ||
arms: { | ||
@@ -22,2 +17,8 @@ message: xdr.string(100) | ||
}); | ||
xdr.enum('ResultType', { | ||
ok: 0, | ||
error: 1, | ||
nonsense: 2 | ||
}); | ||
}); | ||
@@ -36,3 +37,3 @@ | ||
r.set("nonsense"); | ||
// r.set("nonsense"); | ||
r.get(); // => undefined | ||
@@ -39,0 +40,0 @@ |
@@ -9,4 +9,2 @@ "use strict"; | ||
var _toConsumableArray = require("babel-runtime/helpers/to-consumable-array")["default"]; | ||
var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"]; | ||
@@ -47,3 +45,3 @@ | ||
var Reference = (function () { | ||
var Reference = exports.Reference = (function () { | ||
function Reference() { | ||
@@ -57,3 +55,3 @@ _classCallCheck(this, Reference); | ||
value: function resolve(definitions) { | ||
value: function resolve(context) { | ||
throw new Error("implement resolve in child class"); | ||
@@ -78,4 +76,5 @@ } | ||
resolve: { | ||
value: function resolve(definitions) { | ||
return definitions[this.name]; | ||
value: function resolve(context) { | ||
var defn = context.definitions[this.name]; | ||
return defn.resolve(context); | ||
} | ||
@@ -104,4 +103,4 @@ } | ||
resolve: { | ||
value: function resolve(definitions) { | ||
var resolvedChild = this.childReference.resolve(definitions); | ||
value: function resolve(context) { | ||
var resolvedChild = this.childReference.resolve(context); | ||
if (this.variable) { | ||
@@ -131,4 +130,4 @@ return new XDR.VarArray(resolvedChild, this.length); | ||
resolve: { | ||
value: function resolve(definitions) { | ||
var resolvedChild = this.childReference.resolve(definitions); | ||
value: function resolve(context) { | ||
var resolvedChild = this.childReference.resolve(context); | ||
return new XDR.Option(resolvedChild); | ||
@@ -143,9 +142,3 @@ } | ||
var Definition = (function () { | ||
function Definition(constructor, name) { | ||
var _this = this; | ||
for (var _len = arguments.length, config = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
config[_key - 2] = arguments[_key]; | ||
} | ||
function Definition(constructor, name, config) { | ||
_classCallCheck(this, Definition); | ||
@@ -156,49 +149,19 @@ | ||
this.config = config; | ||
this.dep = []; | ||
// walk the defintion config for Reference objects, push their names onto | ||
// this.deps so we can use sequencify to order our resolutions | ||
this._walkConfig(this.config, function (value) { | ||
if (value instanceof Reference) { | ||
_this.dep.push(value.name); | ||
} | ||
}); | ||
} | ||
_createClass(Definition, { | ||
create: { | ||
value: function create(deps) { | ||
this._walkConfig(this.config, function (value, key, parent) { | ||
if (!(value instanceof Reference)) { | ||
return; | ||
} | ||
resolve: { | ||
var dep = value.resolve(deps); | ||
// resolve calls the constructor of this definition with the provided context | ||
// and this definitions config values. The definitions constructor should | ||
// populate the final type on `context.results`, and may refer to other | ||
// definitions through `context.definitions` | ||
if (!dep) { | ||
// throw if the reference couldn't be resolved | ||
throw new Error("XDR Error:" + value.name + " could not be resolved."); | ||
} else { | ||
// overwrite the reference with the concrete value | ||
parent[key] = dep; | ||
} | ||
}); | ||
value: function resolve(context) { | ||
if (this.name in context.results) { | ||
return context.results[this.name]; | ||
} | ||
// actually create the concrete definition | ||
return this.constructor.apply(this, [this.name].concat(_toConsumableArray(this.config))); | ||
return this.constructor(context, this.name, this.config); | ||
} | ||
}, | ||
_walkConfig: { | ||
value: function _walkConfig(current, fn) { | ||
var _this = this; | ||
each(current, function (value, key) { | ||
fn(value, key, current); | ||
// recurse if the value is a nested object | ||
if (isPlainObject(value) || isArray(value)) { | ||
_this._walkConfig(value, fn); | ||
} | ||
}); | ||
} | ||
} | ||
@@ -241,4 +204,8 @@ }); | ||
// the "constructor" for a typedef just returns the resolved value | ||
var createTypedef = function (name, args) { | ||
return args; | ||
var createTypedef = function (context, name, value) { | ||
if (value instanceof Reference) { | ||
value = value.resolve(context); | ||
} | ||
context.results[name] = value; | ||
return value; | ||
}; | ||
@@ -252,5 +219,7 @@ | ||
value: function _const(name, config) { | ||
var createConst = function (name, args) { | ||
return args; | ||
var createConst = function (context, name, value) { | ||
context.results[name] = value; | ||
return value; | ||
}; | ||
var result = new Definition(createConst, name, config); | ||
@@ -365,18 +334,7 @@ this.define(name, result); | ||
var sequence = []; | ||
sequencify(this._definitions, map(this._definitions, function (d) { | ||
return d.name; | ||
}), sequence); | ||
each(sequence, function (name) { | ||
var defn = _this._definitions[name]; | ||
var deps = pick.apply(undefined, [_this._destination].concat(_toConsumableArray(defn.dep))); | ||
var result = defn.create(deps); | ||
//Ensure we aren't redefining a name | ||
if (!isUndefined(_this._destination[name])) { | ||
throw new Error("XDR Error:" + name + " is already defined"); | ||
} | ||
_this._destination[name] = result; | ||
each(this._definitions, function (defn, name) { | ||
defn.resolve({ | ||
definitions: _this._definitions, | ||
results: _this._destination | ||
}); | ||
}); | ||
@@ -383,0 +341,0 @@ } |
@@ -84,3 +84,3 @@ "use strict"; | ||
create: { | ||
value: function create(name, members) { | ||
value: function create(context, name, members) { | ||
var ChildEnum = (function (_Enum) { | ||
@@ -103,2 +103,4 @@ var _class = function ChildEnum() { | ||
ChildEnum.enumName = name; | ||
context.results[name] = ChildEnum; | ||
ChildEnum._members = {}; | ||
@@ -105,0 +107,0 @@ ChildEnum._byValue = new _core.Map(); |
@@ -28,2 +28,4 @@ "use strict"; | ||
var Reference = require("./config").Reference; | ||
var includeIoMixin = _interopRequire(require("./io-mixin")); | ||
@@ -76,3 +78,3 @@ | ||
create: { | ||
value: function create(name, fields) { | ||
value: function create(context, name, fields) { | ||
var ChildStruct = (function (_Struct) { | ||
@@ -96,5 +98,18 @@ var _class = function ChildStruct() { | ||
ChildStruct._fields = fields; | ||
context.results[name] = ChildStruct; | ||
each(fields, function (field) { | ||
ChildStruct._fields = fields.map(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 2); | ||
var name = _ref2[0]; | ||
var field = _ref2[1]; | ||
if (field instanceof Reference) { | ||
field = field.resolve(context); | ||
} | ||
return [name, field]; | ||
}); | ||
each(ChildStruct._fields, function (field) { | ||
var _field = _slicedToArray(field, 1); | ||
@@ -101,0 +116,0 @@ |
@@ -26,2 +26,4 @@ "use strict"; | ||
var Reference = require("./config").Reference; | ||
var includeIoMixin = _interopRequire(require("./io-mixin")); | ||
@@ -126,3 +128,3 @@ | ||
create: { | ||
value: function create(name, config) { | ||
value: function create(context, name, config) { | ||
var ChildUnion = (function (_Union) { | ||
@@ -145,10 +147,31 @@ var _class = function ChildUnion() { | ||
ChildUnion.unionName = name; | ||
ChildUnion._switchOn = config.switchOn; | ||
context.results[name] = ChildUnion; | ||
if (config.switchOn instanceof Reference) { | ||
ChildUnion._switchOn = config.switchOn.resolve(context); | ||
} else { | ||
ChildUnion._switchOn = config.switchOn; | ||
} | ||
ChildUnion._switches = new _core.Map(); | ||
ChildUnion._arms = config.arms; | ||
ChildUnion._arms = {}; | ||
each(config.arms, function (value, name) { | ||
if (value instanceof Reference) { | ||
value = value.resolve(context); | ||
} | ||
ChildUnion._arms[name] = value; | ||
}); | ||
// resolve default arm | ||
var defaultArm = config.defaultArm; | ||
if (defaultArm instanceof Reference) { | ||
defaultArm = defaultArm.resolve(context); | ||
} | ||
each(ChildUnion._switchOn.values(), function (aSwitch) { | ||
// build the enum => arm map | ||
var arm = config.switches[aSwitch.name] || config.defaultArm; | ||
var arm = config.switches[aSwitch.name] || defaultArm; | ||
ChildUnion._switches.set(aSwitch, arm); | ||
@@ -155,0 +178,0 @@ |
{ | ||
"name": "js-xdr", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"description": "Read/write XDR encoded data structures (RFC 4506)", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -7,3 +7,3 @@ import * as XDR from "./types"; | ||
// types is the root | ||
// types is the root | ||
var types = {}; | ||
@@ -23,5 +23,5 @@ | ||
class Reference { | ||
export class Reference { | ||
/* jshint unused: false */ | ||
resolve(definitions) { | ||
resolve(context) { | ||
throw new Error("implement resolve in child class"); | ||
@@ -36,4 +36,5 @@ } | ||
resolve(definitions) { | ||
return definitions[this.name]; | ||
resolve(context) { | ||
let defn = context.definitions[this.name]; | ||
return defn.resolve(context); | ||
} | ||
@@ -50,4 +51,4 @@ } | ||
resolve(definitions) { | ||
let resolvedChild = this.childReference.resolve(definitions); | ||
resolve(context) { | ||
let resolvedChild = this.childReference.resolve(context); | ||
if (this.variable) { | ||
@@ -67,4 +68,4 @@ return new XDR.VarArray(resolvedChild, this.length); | ||
resolve(definitions) { | ||
let resolvedChild = this.childReference.resolve(definitions); | ||
resolve(context) { | ||
let resolvedChild = this.childReference.resolve(context); | ||
return new XDR.Option(resolvedChild); | ||
@@ -75,47 +76,19 @@ } | ||
class Definition { | ||
constructor(constructor, name, ...config) { | ||
constructor(constructor, name, config) { | ||
this.constructor = constructor; | ||
this.name = name; | ||
this.config = config; | ||
this.dep = []; | ||
// walk the defintion config for Reference objects, push their names onto | ||
// this.deps so we can use sequencify to order our resolutions | ||
this._walkConfig(this.config, value => { | ||
if(value instanceof Reference) { | ||
this.dep.push(value.name); | ||
} | ||
}); | ||
} | ||
create(deps) { | ||
this._walkConfig(this.config, (value, key, parent) => { | ||
if(!(value instanceof Reference)) { return; } | ||
// resolve calls the constructor of this definition with the provided context | ||
// and this definitions config values. The definitions constructor should | ||
// populate the final type on `context.results`, and may refer to other | ||
// definitions through `context.definitions` | ||
resolve(context) { | ||
if (this.name in context.results) { | ||
return context.results[this.name]; | ||
} | ||
let dep = value.resolve(deps); | ||
if(!dep) { | ||
// throw if the reference couldn't be resolved | ||
throw new Error(`XDR Error:${value.name} could not be resolved.`); | ||
} else { | ||
// overwrite the reference with the concrete value | ||
parent[key] = dep; | ||
} | ||
}); | ||
// actually create the concrete definition | ||
return this.constructor(this.name, ...this.config); | ||
return this.constructor(context, this.name, this.config); | ||
} | ||
_walkConfig(current, fn) { | ||
each(current, (value, key) => { | ||
fn(value, key, current); | ||
// recurse if the value is a nested object | ||
if (isPlainObject(value) || isArray(value)) { | ||
this._walkConfig(value, fn); | ||
} | ||
}); | ||
} | ||
} | ||
@@ -147,3 +120,9 @@ | ||
// the "constructor" for a typedef just returns the resolved value | ||
let createTypedef = (name, args) => args; | ||
let createTypedef = (context, name, value) => { | ||
if (value instanceof Reference) { | ||
value = value.resolve(context); | ||
} | ||
context.results[name] = value; | ||
return value; | ||
}; | ||
@@ -155,3 +134,7 @@ let result = new Definition(createTypedef, name, config); | ||
const(name, config) { | ||
let createConst = (name, args) => args; | ||
let createConst = (context, name, value) => { | ||
context.results[name] = value; | ||
return value; | ||
}; | ||
let result = new Definition(createConst, name, config); | ||
@@ -175,23 +158,23 @@ this.define(name, result); | ||
array(childType, length) { | ||
array(childType, length) { | ||
if (childType instanceof Reference) { | ||
return new ArrayReference(childType, length); | ||
} else { | ||
return new XDR.Array(childType, length); | ||
return new XDR.Array(childType, length); | ||
} | ||
} | ||
varArray(childType, maxLength) { | ||
varArray(childType, maxLength) { | ||
if (childType instanceof Reference) { | ||
return new ArrayReference(childType, maxLength, true); | ||
} else { | ||
return new XDR.VarArray(childType, maxLength); | ||
return new XDR.VarArray(childType, maxLength); | ||
} | ||
} | ||
option(childType) { | ||
option(childType) { | ||
if (childType instanceof Reference) { | ||
return new OptionReference(childType); | ||
} else { | ||
return new XDR.Option(childType); | ||
return new XDR.Option(childType); | ||
} | ||
@@ -214,18 +197,9 @@ } | ||
resolve() { | ||
let sequence = []; | ||
sequencify(this._definitions, map(this._definitions, d => d.name), sequence); | ||
each(sequence, name => { | ||
let defn = this._definitions[name]; | ||
let deps = pick(this._destination, ...defn.dep); | ||
let result = defn.create(deps); | ||
//Ensure we aren't redefining a name | ||
if(!isUndefined(this._destination[name])) { | ||
throw new Error(`XDR Error:${name} is already defined`); | ||
} | ||
this._destination[name] = result; | ||
each(this._definitions, (defn, name) => { | ||
defn.resolve({ | ||
definitions: this._definitions, | ||
results: this._destination | ||
}); | ||
}); | ||
} | ||
} | ||
} |
@@ -30,3 +30,3 @@ import { Int } from "./int"; | ||
} | ||
Int.write(value.value, io); | ||
@@ -50,4 +50,4 @@ } | ||
if(!result) { | ||
throw new Error(`${name} is not a member of ${this.enumName}`); | ||
if(!result) { | ||
throw new Error(`${name} is not a member of ${this.enumName}`); | ||
} | ||
@@ -58,3 +58,3 @@ | ||
static create(name, members) { | ||
static create(context, name, members) { | ||
let ChildEnum = class extends Enum { | ||
@@ -67,5 +67,7 @@ constructor(...args) { | ||
ChildEnum.enumName = name; | ||
context.results[name] = ChildEnum; | ||
ChildEnum._members = {}; | ||
ChildEnum._byValue = new Map(); | ||
each(members, (value, key) => { | ||
@@ -84,2 +86,2 @@ let inst = new ChildEnum(key, value); | ||
includeIoMixin(Enum); | ||
includeIoMixin(Enum); |
import { each, map, isUndefined } from "lodash"; | ||
import { zipObject } from "lodash"; | ||
import { Reference } from "./config"; | ||
import includeIoMixin from './io-mixin'; | ||
@@ -36,3 +37,3 @@ | ||
static create(name, fields) { | ||
static create(context, name, fields) { | ||
let ChildStruct = class extends Struct { | ||
@@ -45,11 +46,17 @@ constructor(...args) { | ||
ChildStruct.structName = name; | ||
ChildStruct._fields = fields; | ||
each(fields, field => { | ||
context.results[name] = ChildStruct; | ||
ChildStruct._fields = fields.map(([name, field]) => { | ||
if (field instanceof Reference) { | ||
field = field.resolve(context); | ||
} | ||
return [name, field]; | ||
}); | ||
each(ChildStruct._fields, field => { | ||
let [fieldName] = field; | ||
ChildStruct.prototype[fieldName] = readOrWriteAttribute(fieldName); | ||
}); | ||
@@ -70,2 +77,2 @@ return ChildStruct; | ||
}; | ||
} | ||
} |
import { each, isUndefined } from "lodash"; | ||
import { Void } from "./void"; | ||
import { Reference } from "./config"; | ||
import includeIoMixin from './io-mixin'; | ||
@@ -85,3 +86,3 @@ | ||
static create(name, config) { | ||
static create(context, name, config) { | ||
let ChildUnion = class extends Union { | ||
@@ -93,11 +94,32 @@ constructor(...args) { | ||
ChildUnion.unionName = name; | ||
ChildUnion._switchOn = config.switchOn; | ||
ChildUnion._switches = new Map(); | ||
ChildUnion._arms = config.arms; | ||
ChildUnion.unionName = name; | ||
context.results[name] = ChildUnion; | ||
if (config.switchOn instanceof Reference) { | ||
ChildUnion._switchOn = config.switchOn.resolve(context); | ||
} else { | ||
ChildUnion._switchOn = config.switchOn; | ||
} | ||
ChildUnion._switches = new Map(); | ||
ChildUnion._arms = {}; | ||
each(config.arms, (value, name) => { | ||
if (value instanceof Reference) { | ||
value = value.resolve(context); | ||
} | ||
ChildUnion._arms[name] = value; | ||
}); | ||
// resolve default arm | ||
let defaultArm = config.defaultArm; | ||
if (defaultArm instanceof Reference) { | ||
defaultArm = defaultArm.resolve(context); | ||
} | ||
each(ChildUnion._switchOn.values(), aSwitch => { | ||
// build the enum => arm map | ||
let arm = config.switches[aSwitch.name] || config.defaultArm; | ||
let arm = config.switches[aSwitch.name] || defaultArm; | ||
ChildUnion._switches.set(aSwitch, arm); | ||
@@ -129,2 +151,2 @@ | ||
includeIoMixin(Union); | ||
includeIoMixin(Union); |
import { Cursor } from "../../src/cursor"; | ||
import { cursorToArray } from "../support/io-helpers"; | ||
let Color = XDR.Enum.create('Color', { | ||
/* jshint -W030 */ | ||
let emptyContext = {definitions:{}, results:{}}; | ||
let Color = XDR.Enum.create(emptyContext, 'Color', { | ||
red: 0, | ||
@@ -24,3 +27,3 @@ green: 1, | ||
describe('Enum.read', function() { | ||
it('decodes correctly', function() { | ||
@@ -86,2 +89,1 @@ expect(read([0x00,0x00,0x00,0x00])).to.eql(Color.red()); | ||
}); | ||
import { Cursor } from "../../src/cursor"; | ||
import { cursorToArray } from "../support/io-helpers"; | ||
let MyRange = XDR.Struct.create('MyRange', [ | ||
/* jshint -W030 */ | ||
let emptyContext = {definitions:{}, results:{}}; | ||
let MyRange = XDR.Struct.create(emptyContext, 'MyRange', [ | ||
['begin', XDR.Int], | ||
@@ -11,3 +14,3 @@ ['end', XDR.Int], | ||
describe('Struct.read', function() { | ||
it('decodes correctly', function() { | ||
@@ -115,2 +118,1 @@ let empty = read([ | ||
}); | ||
import { Cursor } from "../../src/cursor"; | ||
import { cursorToArray } from "../support/io-helpers"; | ||
let ResultType = XDR.Enum.create('ResultType', { | ||
/* jshint -W030 */ | ||
let emptyContext = {definitions:{}, results:{}}; | ||
let ResultType = XDR.Enum.create(emptyContext, 'ResultType', { | ||
ok: 0, | ||
@@ -10,3 +13,3 @@ error: 1, | ||
let Result = XDR.Union.create('Result', { | ||
let Result = XDR.Union.create(emptyContext, 'Result', { | ||
switchOn: ResultType, | ||
@@ -36,3 +39,3 @@ switches: { | ||
describe('Union.read', function() { | ||
it('decodes correctly', function() { | ||
@@ -39,0 +42,0 @@ let ok = read([0x00,0x00,0x00,0x00]); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
93
954363
22471