From 336c8040d27858fc77a96bddf44802157ecf1ec9 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Sun, 11 Nov 2018 14:09:11 +0100 Subject: [PATCH] convert to standard style --- benchmark/benchmark_all_types.js | 63 +++--- benchmark/benchmark_by_kind.js | 62 +++--- benchmark/benchmark_by_subtype.js | 70 +++--- benchmark/benchmark_by_test.js | 91 ++++---- benchmark/benchmark_by_type.js | 66 +++--- benchmark/benchmark_unified.js | 39 ++-- example.js | 94 ++++---- examples/error_handling.js | 44 ++-- examples/full_protocol.js | 38 ++-- index.js | 2 +- package.json | 10 +- src/datatypes/conditional.js | 82 ++++--- src/datatypes/numeric.js | 146 ++++++------- src/datatypes/structures.js | 112 +++++----- src/datatypes/utils.js | 343 +++++++++++++++--------------- src/index.js | 18 +- src/protodef.js | 236 ++++++++++---------- src/serializer.js | 106 +++++---- src/utils.js | 101 ++++----- test/dataTypes/datatypes.js | 113 +++++----- test/dataTypes/prepareTests.js | 71 +++---- 21 files changed, 920 insertions(+), 987 deletions(-) diff --git a/benchmark/benchmark_all_types.js b/benchmark/benchmark_all_types.js index cd7d98b..e540f48 100644 --- a/benchmark/benchmark_all_types.js +++ b/benchmark/benchmark_all_types.js @@ -1,44 +1,45 @@ -const testData=require("../test/dataTypes/prepareTests").testData; -const proto=require("../test/dataTypes/prepareTests").proto; -const Benchmark = require('benchmark'); +/* eslint-env mocha */ -it('reads',function() { - this.timeout(1000*60*10); - const readSuite = new Benchmark.Suite; +const testData = require('../test/dataTypes/prepareTests').testData +const proto = require('../test/dataTypes/prepareTests').proto +const Benchmark = require('benchmark') + +it('reads', function () { + this.timeout(1000 * 60 * 10) + const readSuite = new Benchmark.Suite() readSuite.add('read', function () { testData.forEach(tests => { - tests.data.forEach(test => { - test.subtypes.forEach(subType => { - subType.values.forEach((value) => { - proto.parsePacketBuffer(subType.type, value.buffer); - }); + tests.data.forEach(test => { + test.subtypes.forEach(subType => { + subType.values.forEach((value) => { + proto.parsePacketBuffer(subType.type, value.buffer) }) - }); - }); + }) + }) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); -}); + .run({ 'async': false }) +}) -it('writes',function() { - this.timeout(1000*60*10); - const writeSuite = new Benchmark.Suite; +it('writes', function () { + this.timeout(1000 * 60 * 10) + const writeSuite = new Benchmark.Suite() writeSuite.add('write', function () { testData.forEach(tests => { - tests.data.forEach(test => { - test.subtypes.forEach(subType => { - subType.values.forEach((value) => { - proto.createPacketBuffer(subType.type, value.value); - }); - }); - }); - }); + tests.data.forEach(test => { + test.subtypes.forEach(subType => { + subType.values.forEach((value) => { + proto.createPacketBuffer(subType.type, value.value) + }) + }) + }) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); -}); - + .run({ 'async': false }) +}) diff --git a/benchmark/benchmark_by_kind.js b/benchmark/benchmark_by_kind.js index 3becd0e..92ca811 100644 --- a/benchmark/benchmark_by_kind.js +++ b/benchmark/benchmark_by_kind.js @@ -1,45 +1,45 @@ -const testData=require("../test/dataTypes/prepareTests").testData; -const proto=require("../test/dataTypes/prepareTests").proto; -const Benchmark = require('benchmark'); +/* eslint-env mocha */ + +const testData = require('../test/dataTypes/prepareTests').testData +const proto = require('../test/dataTypes/prepareTests').proto +const Benchmark = require('benchmark') testData.forEach(tests => { - describe(tests.kind,function(){ - this.timeout(1000*60*10); + describe(tests.kind, function () { + this.timeout(1000 * 60 * 10) - it('reads',function() { - const readSuite = new Benchmark.Suite; + it('reads', function () { + const readSuite = new Benchmark.Suite() readSuite.add('read', function () { - tests.data.forEach(test => { - test.subtypes.forEach(subType => { - subType.values.forEach((value) => { - proto.parsePacketBuffer(subType.type, value.buffer); - }); + tests.data.forEach(test => { + test.subtypes.forEach(subType => { + subType.values.forEach((value) => { + proto.parsePacketBuffer(subType.type, value.buffer) }) - }); - + }) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); - }); + .run({ 'async': false }) + }) - it('writes',function() { - const writeSuite = new Benchmark.Suite; + it('writes', function () { + const writeSuite = new Benchmark.Suite() writeSuite.add('write', function () { tests.data.forEach(test => { test.subtypes.forEach(subType => { subType.values.forEach((value) => { - proto.createPacketBuffer(subType.type, value.value); - }); - }); - }); - }) - .on('cycle', function (event) { - console.log(String(event.target)); + proto.createPacketBuffer(subType.type, value.value) + }) + }) + }) }) - .run({'async': false}); - }); - }); -}); - + .on('cycle', function (event) { + console.log(String(event.target)) + }) + .run({ 'async': false }) + }) + }) +}) diff --git a/benchmark/benchmark_by_subtype.js b/benchmark/benchmark_by_subtype.js index 6c0d172..8c6c393 100644 --- a/benchmark/benchmark_by_subtype.js +++ b/benchmark/benchmark_by_subtype.js @@ -1,51 +1,51 @@ -const testData=require("../test/dataTypes/prepareTests").testData; -const proto=require("../test/dataTypes/prepareTests").proto; -const Benchmark = require('benchmark'); +/* eslint-env mocha */ -function testType(type,values) -{ - it('reads',function() { - const readSuite = new Benchmark.Suite; +const testData = require('../test/dataTypes/prepareTests').testData +const proto = require('../test/dataTypes/prepareTests').proto +const Benchmark = require('benchmark') + +function testType (type, values) { + it('reads', function () { + const readSuite = new Benchmark.Suite() readSuite.add('read', function () { - values.forEach((value) => { - proto.parsePacketBuffer(type, value.buffer); - }); + values.forEach((value) => { + proto.parsePacketBuffer(type, value.buffer) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); - }); + .run({ 'async': false }) + }) - it('writes',function() { - const writeSuite = new Benchmark.Suite; + it('writes', function () { + const writeSuite = new Benchmark.Suite() writeSuite.add('write', function () { - values.forEach((value) => { - proto.createPacketBuffer(type, value.value); - }); + values.forEach((value) => { + proto.createPacketBuffer(type, value.value) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); - }); + .run({ 'async': false }) + }) } testData.forEach(tests => { - describe(tests.kind,function(){ - this.timeout(1000*60*10); + describe(tests.kind, function () { + this.timeout(1000 * 60 * 10) tests.data.forEach(test => { - describe(test.type,() => { + describe(test.type, () => { test.subtypes.forEach((subtype) => { - if(subtype.description) describe(subtype.description,() => { - testType(subtype.type,subtype.values); - }); - else - testType(subtype.type,subtype.values); - }); - }); - }); - }); -}); - + if (subtype.description) { + describe(subtype.description, () => { + testType(subtype.type, subtype.values) + }) + } else { testType(subtype.type, subtype.values) } + }) + }) + }) + }) +}) diff --git a/benchmark/benchmark_by_test.js b/benchmark/benchmark_by_test.js index 5eff261..50a7e24 100644 --- a/benchmark/benchmark_by_test.js +++ b/benchmark/benchmark_by_test.js @@ -1,59 +1,56 @@ -const testData=require("../test/dataTypes/prepareTests").testData; -const proto=require("../test/dataTypes/prepareTests").proto; -const Benchmark = require('benchmark'); +/* eslint-env mocha */ -function testValue(type,value,buffer) -{ - it('writes',function(){ - const suite = new Benchmark.Suite; - suite.add('writes', function() { - proto.createPacketBuffer(type,value); - }) - .on('cycle', function(event) { - console.log(String(event.target)); - }) - .run({ 'async': false }); - }); - it('reads',function(){ - const suite = new Benchmark.Suite; - suite.add('read', function() { - proto.parsePacketBuffer(type,buffer) +const testData = require('../test/dataTypes/prepareTests').testData +const proto = require('../test/dataTypes/prepareTests').proto +const Benchmark = require('benchmark') + +function testValue (type, value, buffer) { + it('writes', function () { + const suite = new Benchmark.Suite() + suite.add('writes', function () { + proto.createPacketBuffer(type, value) + }) + .on('cycle', function (event) { + console.log(String(event.target)) }) - .on('cycle', function(event) { - console.log(String(event.target)); + .run({ 'async': false }) + }) + it('reads', function () { + const suite = new Benchmark.Suite() + suite.add('read', function () { + proto.parsePacketBuffer(type, buffer) + }) + .on('cycle', function (event) { + console.log(String(event.target)) }) - .run({ 'async': false }); - }); + .run({ 'async': false }) + }) } -function testType(type,values) -{ +function testType (type, values) { values.forEach((value) => { - if(value.description) - describe(value.description,() => { - testValue(type,value.value,value.buffer); - }); - else - testValue(type,value.value,value.buffer); - }); + if (value.description) { + describe(value.description, () => { + testValue(type, value.value, value.buffer) + }) + } else { testValue(type, value.value, value.buffer) } + }) } testData.forEach(tests => { - describe(tests.kind,function(){ - this.timeout(1000*60*10); + describe(tests.kind, function () { + this.timeout(1000 * 60 * 10) tests.data.forEach(test => { - describe(test.type,() => { + describe(test.type, () => { test.subtypes.forEach((subtype) => { - if(subtype.description) - describe(subtype.description,() => { - testType(subtype.type,subtype.values); - }); - else - testType(subtype.type,subtype.values); - }); - }); - }); - }); -}); - + if (subtype.description) { + describe(subtype.description, () => { + testType(subtype.type, subtype.values) + }) + } else { testType(subtype.type, subtype.values) } + }) + }) + }) + }) +}) diff --git a/benchmark/benchmark_by_type.js b/benchmark/benchmark_by_type.js index 81582f0..6cb5a64 100644 --- a/benchmark/benchmark_by_type.js +++ b/benchmark/benchmark_by_type.js @@ -1,45 +1,45 @@ -const testData=require("../test/dataTypes/prepareTests").testData; -const proto=require("../test/dataTypes/prepareTests").proto; -const Benchmark = require('benchmark'); +/* eslint-env mocha */ + +const testData = require('../test/dataTypes/prepareTests').testData +const proto = require('../test/dataTypes/prepareTests').proto +const Benchmark = require('benchmark') testData.forEach(tests => { - describe(tests.kind,function(){ - this.timeout(1000*60*10); + describe(tests.kind, function () { + this.timeout(1000 * 60 * 10) tests.data.forEach(test => { - describe(test.type,() => { - - it('reads',function() { - const readSuite = new Benchmark.Suite; + describe(test.type, () => { + it('reads', function () { + const readSuite = new Benchmark.Suite() readSuite.add('read', function () { - test.subtypes.forEach(subType => { - subType.values.forEach((value) => { - proto.parsePacketBuffer(subType.type, value.buffer); - }); + test.subtypes.forEach(subType => { + subType.values.forEach((value) => { + proto.parsePacketBuffer(subType.type, value.buffer) }) + }) }) - .on('cycle', function (event) { - console.log(String(event.target)); - }) - .run({'async': false}); - }); + .on('cycle', function (event) { + console.log(String(event.target)) + }) + .run({ 'async': false }) + }) - it('writes',function() { - const writeSuite = new Benchmark.Suite; + it('writes', function () { + const writeSuite = new Benchmark.Suite() writeSuite.add('write', function () { - test.subtypes.forEach(subType => { - subType.values.forEach((value) => { - proto.createPacketBuffer(subType.type, value.value); - }); - }); + test.subtypes.forEach(subType => { + subType.values.forEach((value) => { + proto.createPacketBuffer(subType.type, value.value) + }) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); - }); - }); - }); - }); -}); - + .run({ 'async': false }) + }) + }) + }) + }) +}) diff --git a/benchmark/benchmark_unified.js b/benchmark/benchmark_unified.js index 85ca5ff..fb7036d 100644 --- a/benchmark/benchmark_unified.js +++ b/benchmark/benchmark_unified.js @@ -1,25 +1,26 @@ -const testData=require("../test/dataTypes/prepareTests").testData; -const proto=require("../test/dataTypes/prepareTests").proto; -const Benchmark = require('benchmark'); +/* eslint-env mocha */ -it('read/write',function() { - this.timeout(1000*60*10); - const suite = new Benchmark.Suite; +const testData = require('../test/dataTypes/prepareTests').testData +const proto = require('../test/dataTypes/prepareTests').proto +const Benchmark = require('benchmark') + +it('read/write', function () { + this.timeout(1000 * 60 * 10) + const suite = new Benchmark.Suite() suite.add('read/write', function () { - testData.forEach(tests => { - tests.data.forEach(test => { - test.subtypes.forEach(subType => { - subType.values.forEach((value) => { - proto.parsePacketBuffer(subType.type, value.buffer); - proto.createPacketBuffer(subType.type, value.value); - }); + testData.forEach(tests => { + tests.data.forEach(test => { + test.subtypes.forEach(subType => { + subType.values.forEach((value) => { + proto.parsePacketBuffer(subType.type, value.buffer) + proto.createPacketBuffer(subType.type, value.value) }) - }); - }); + }) + }) }) + }) .on('cycle', function (event) { - console.log(String(event.target)); + console.log(String(event.target)) }) - .run({'async': false}); -}); - + .run({ 'async': false }) +}) diff --git a/example.js b/example.js index 9b3d096..e701a43 100644 --- a/example.js +++ b/example.js @@ -1,82 +1,82 @@ -const ProtoDef = require("protodef").ProtoDef; -const Serializer = require("protodef").Serializer; -const Parser = require("protodef").Parser; +const ProtoDef = require('protodef').ProtoDef +const Serializer = require('protodef').Serializer +const Parser = require('protodef').Parser // the protocol can be in a separate json file -const example_protocol={ - "container": "native", - "varint": "native", - "byte": "native", - "bool": "native", - "switch": "native", - "entity_look": [ - "container", +const exampleProtocol = { + 'container': 'native', + 'varint': 'native', + 'byte': 'native', + 'bool': 'native', + 'switch': 'native', + 'entity_look': [ + 'container', [ { - "name": "entityId", - "type": "varint" + 'name': 'entityId', + 'type': 'varint' }, { - "name": "yaw", - "type": "i8" + 'name': 'yaw', + 'type': 'i8' }, { - "name": "pitch", - "type": "i8" + 'name': 'pitch', + 'type': 'i8' }, { - "name": "onGround", - "type": "bool" + 'name': 'onGround', + 'type': 'bool' } ] ], - "packet": [ - "container", + 'packet': [ + 'container', [ { - "name": "name", - "type": [ - "mapper", + 'name': 'name', + 'type': [ + 'mapper', { - "type": "varint", - "mappings": { - "22": "entity_look" + 'type': 'varint', + 'mappings': { + '22': 'entity_look' } } ] }, { - "name": "params", - "type": [ - "switch", + 'name': 'params', + 'type': [ + 'switch', { - "compareTo": "name", - "fields": { - "entity_look": "entity_look" + 'compareTo': 'name', + 'fields': { + 'entity_look': 'entity_look' } } ] } ] ] -}; +} -const proto = new ProtoDef(); -proto.addTypes(example_protocol); -const parser = new Parser(proto, "packet"); -const serializer = new Serializer(proto, "packet"); +const proto = new ProtoDef() +proto.addTypes(exampleProtocol) +const parser = new Parser(proto, 'packet') +const serializer = new Serializer(proto, 'packet') serializer.write({ - name: "entity_look", + name: 'entity_look', params: { - "entityId": 1, - "yaw": 1, - "pitch": 1, - "onGround": true + 'entityId': 1, + 'yaw': 1, + 'pitch': 1, + 'onGround': true } -}); -serializer.pipe(parser); +}) +serializer.pipe(parser) parser.on('data', function (chunk) { - console.log(JSON.stringify(chunk, null, 2)); -}); + console.log(JSON.stringify(chunk, null, 2)) +}) diff --git a/examples/error_handling.js b/examples/error_handling.js index b949fc8..37114fc 100644 --- a/examples/error_handling.js +++ b/examples/error_handling.js @@ -1,33 +1,33 @@ -const ProtoDef = require("protodef").ProtoDef; -const Serializer = require("protodef").Serializer; -const Parser = require("protodef").Parser; +const ProtoDef = require('protodef').ProtoDef +const Serializer = require('protodef').Serializer +const Parser = require('protodef').Parser -const example_protocol=require("./example_protocol.json"); +const exampleProtocol = require('./example_protocol.json') -const proto = new ProtoDef(); -proto.addTypes(example_protocol); -const parser = new Parser(proto, "packet"); -const serializer = new Serializer(proto, "packet"); +const proto = new ProtoDef() +proto.addTypes(exampleProtocol) +const parser = new Parser(proto, 'packet') +const serializer = new Serializer(proto, 'packet') serializer.write({ - name: "entity_look", + name: 'entity_look', params: { - "entityId": 1, - "yaw": 1, - "pitch": 1, - "onGround": true + 'entityId': 1, + 'yaw': 1, + 'pitch': 1, + 'onGround': true } -}); +}) -parser.on('error',function(err){ - console.log(err.stack); - console.log(err.buffer); -}); +parser.on('error', function (err) { + console.log(err.stack) + console.log(err.buffer) +}) -parser.write(Buffer.from([0x17,0x01,0x01,0x01,0x01])); +parser.write(Buffer.from([0x17, 0x01, 0x01, 0x01, 0x01])) -serializer.pipe(parser); +serializer.pipe(parser) parser.on('data', function (chunk) { - console.log(JSON.stringify(chunk.data, null, 2)); -}); + console.log(JSON.stringify(chunk.data, null, 2)) +}) diff --git a/examples/full_protocol.js b/examples/full_protocol.js index 16063de..6aad290 100644 --- a/examples/full_protocol.js +++ b/examples/full_protocol.js @@ -1,29 +1,29 @@ -const ProtoDef = require("protodef").ProtoDef; -const Serializer = require("protodef").Serializer; -const Parser = require("protodef").Parser; +const ProtoDef = require('protodef').ProtoDef +const Serializer = require('protodef').Serializer +const Parser = require('protodef').Parser -const example_protocol=require("./full_protocol_example.json"); +const exampleProtocol = require('./full_protocol_example.json') -const proto = new ProtoDef(); -proto.addProtocol(example_protocol,["login","toClient"]); -const parser = new Parser(proto, "packet"); -const serializer = new Serializer(proto, "packet"); +const proto = new ProtoDef() +proto.addProtocol(exampleProtocol, ['login', 'toClient']) +const parser = new Parser(proto, 'packet') +const serializer = new Serializer(proto, 'packet') serializer.write({ - name: "success", + name: 'success', params: { - "uuid": "some uuid", - "username": "some name" + 'uuid': 'some uuid', + 'username': 'some name' } -}); +}) -parser.on('error',function(err){ - console.log(err.stack); - console.log(err.buffer); -}); +parser.on('error', function (err) { + console.log(err.stack) + console.log(err.buffer) +}) -serializer.pipe(parser); +serializer.pipe(parser) parser.on('data', function (chunk) { - console.log(JSON.stringify(chunk.data, null, 2)); -}); + console.log(JSON.stringify(chunk.data, null, 2)) +}) diff --git a/index.js b/index.js index 220c3fa..d12c5e7 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -module.exports = require('./src/index.js'); +module.exports = require('./src/index.js') diff --git a/package.json b/package.json index ad01c47..d0bb6e5 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,11 @@ "main": "index.js", "author": "roblabla ", "scripts": { - "prepublish": "require-self", - "test": "mocha --recursive --reporter spec", + "prepare": "require-self", + "lint": "standard", + "fix": "standard --fix", + "unit-test": "mocha --recursive --reporter spec", + "test": "npm run lint && npm run unit-test", "benchmark": "mocha benchmark/benchmark_unified.js" }, "tonicExampleFilename": "example.js", @@ -33,6 +36,7 @@ "chai": "^4.1.2", "jsonschema": "^1.2.4", "mocha": "^5.2.0", - "require-self": "^0.1.0" + "require-self": "^0.1.0", + "standard": "^12.0.1" } } diff --git a/src/datatypes/conditional.js b/src/datatypes/conditional.js index 2a63338..99a4597 100644 --- a/src/datatypes/conditional.js +++ b/src/datatypes/conditional.js @@ -1,64 +1,56 @@ -const { getField, getFieldInfo, tryDoc, PartialReadError} = require('../utils'); +const { getField, getFieldInfo, tryDoc, PartialReadError } = require('../utils') module.exports = { - 'switch': [readSwitch, writeSwitch, sizeOfSwitch, require('../../ProtoDef/schemas/conditional')["switch"]], - 'option': [readOption, writeOption, sizeOfOption, require('../../ProtoDef/schemas/conditional')["option"]] -}; + 'switch': [readSwitch, writeSwitch, sizeOfSwitch, require('../../ProtoDef/schemas/conditional')['switch']], + 'option': [readOption, writeOption, sizeOfOption, require('../../ProtoDef/schemas/conditional')['option']] +} -function readSwitch(buffer, offset, {compareTo,fields,compareToValue,"default":defVal}, rootNode) { - compareTo = compareToValue!==undefined ? compareToValue : getField(compareTo, rootNode); - if (typeof fields[compareTo] === 'undefined' && typeof defVal === "undefined") - throw new Error(compareTo + " has no associated fieldInfo in switch"); +function readSwitch (buffer, offset, { compareTo, fields, compareToValue, 'default': defVal }, rootNode) { + compareTo = compareToValue !== undefined ? compareToValue : getField(compareTo, rootNode) + if (typeof fields[compareTo] === 'undefined' && typeof defVal === 'undefined') { throw new Error(compareTo + ' has no associated fieldInfo in switch') } - const caseDefault=typeof fields[compareTo] === 'undefined'; - const resultingType = caseDefault ? defVal : fields[compareTo]; - const fieldInfo = getFieldInfo(resultingType); - return tryDoc(() => this.read(buffer, offset, fieldInfo, rootNode),caseDefault ? "default" : compareTo); + const caseDefault = typeof fields[compareTo] === 'undefined' + const resultingType = caseDefault ? defVal : fields[compareTo] + const fieldInfo = getFieldInfo(resultingType) + return tryDoc(() => this.read(buffer, offset, fieldInfo, rootNode), caseDefault ? 'default' : compareTo) } -function writeSwitch(value, buffer, offset, {compareTo,fields,compareToValue,"default":defVal}, rootNode) { - compareTo = compareToValue!==undefined ? compareToValue : getField(compareTo, rootNode); - if (typeof fields[compareTo] === 'undefined' && typeof defVal === "undefined") - throw new Error(compareTo + " has no associated fieldInfo in switch"); +function writeSwitch (value, buffer, offset, { compareTo, fields, compareToValue, 'default': defVal }, rootNode) { + compareTo = compareToValue !== undefined ? compareToValue : getField(compareTo, rootNode) + if (typeof fields[compareTo] === 'undefined' && typeof defVal === 'undefined') { throw new Error(compareTo + ' has no associated fieldInfo in switch') } - const caseDefault=typeof fields[compareTo] === 'undefined'; - const fieldInfo = getFieldInfo(caseDefault ? defVal : fields[compareTo]); - return tryDoc(() => this.write(value, buffer, offset, fieldInfo, rootNode),caseDefault ? "default" : compareTo); + const caseDefault = typeof fields[compareTo] === 'undefined' + const fieldInfo = getFieldInfo(caseDefault ? defVal : fields[compareTo]) + return tryDoc(() => this.write(value, buffer, offset, fieldInfo, rootNode), caseDefault ? 'default' : compareTo) } -function sizeOfSwitch(value, {compareTo,fields,compareToValue,"default":defVal}, rootNode) { - compareTo = compareToValue!==undefined ? compareToValue : getField(compareTo, rootNode); - if (typeof fields[compareTo] === 'undefined' && typeof defVal === "undefined") - throw new Error(compareTo + " has no associated fieldInfo in switch"); +function sizeOfSwitch (value, { compareTo, fields, compareToValue, 'default': defVal }, rootNode) { + compareTo = compareToValue !== undefined ? compareToValue : getField(compareTo, rootNode) + if (typeof fields[compareTo] === 'undefined' && typeof defVal === 'undefined') { throw new Error(compareTo + ' has no associated fieldInfo in switch') } - const caseDefault=typeof fields[compareTo] === 'undefined'; - const fieldInfo = getFieldInfo(caseDefault ? defVal : fields[compareTo]); - return tryDoc(() => this.sizeOf(value, fieldInfo, rootNode),caseDefault ? "default" : compareTo); + const caseDefault = typeof fields[compareTo] === 'undefined' + const fieldInfo = getFieldInfo(caseDefault ? defVal : fields[compareTo]) + return tryDoc(() => this.sizeOf(value, fieldInfo, rootNode), caseDefault ? 'default' : compareTo) } -function readOption(buffer, offset, typeArgs, context) { - if(buffer.length buffer.length) - throw new PartialReadError(); +function readI64 (buffer, offset) { + if (offset + 8 > buffer.length) { throw new PartialReadError() } return { value: [buffer.readInt32BE(offset), buffer.readInt32BE(offset + 4)], size: 8 - }; + } } -function writeI64(value, buffer, offset) { - buffer.writeInt32BE(value[0], offset); - buffer.writeInt32BE(value[1], offset + 4); - return offset + 8; +function writeI64 (value, buffer, offset) { + buffer.writeInt32BE(value[0], offset) + buffer.writeInt32BE(value[1], offset + 4) + return offset + 8 } -function readLI64(buffer, offset) { - if(offset + 8 > buffer.length) - throw new PartialReadError(); +function readLI64 (buffer, offset) { + if (offset + 8 > buffer.length) { throw new PartialReadError() } return { - value: [buffer.readInt32LE(offset+4), buffer.readInt32LE(offset)], + value: [buffer.readInt32LE(offset + 4), buffer.readInt32LE(offset)], size: 8 - }; + } } -function writeLI64(value, buffer, offset) { - buffer.writeInt32LE(value[0], offset+4); - buffer.writeInt32LE(value[1], offset); - return offset + 8; +function writeLI64 (value, buffer, offset) { + buffer.writeInt32LE(value[0], offset + 4) + buffer.writeInt32LE(value[1], offset) + return offset + 8 } -function readU64(buffer, offset) { - if(offset + 8 > buffer.length) - throw new PartialReadError(); +function readU64 (buffer, offset) { + if (offset + 8 > buffer.length) { throw new PartialReadError() } return { value: [buffer.readUInt32BE(offset), buffer.readUInt32BE(offset + 4)], size: 8 - }; + } } -function writeU64(value, buffer, offset) { - buffer.writeUInt32BE(value[0], offset); - buffer.writeUInt32BE(value[1], offset + 4); - return offset + 8; +function writeU64 (value, buffer, offset) { + buffer.writeUInt32BE(value[0], offset) + buffer.writeUInt32BE(value[1], offset + 4) + return offset + 8 } -function readLU64(buffer, offset) { - if(offset + 8 > buffer.length) - throw new PartialReadError(); +function readLU64 (buffer, offset) { + if (offset + 8 > buffer.length) { throw new PartialReadError() } return { - value: [buffer.readUInt32LE(offset+4), buffer.readUInt32LE(offset)], + value: [buffer.readUInt32LE(offset + 4), buffer.readUInt32LE(offset)], size: 8 - }; + } } -function writeLU64(value, buffer, offset) { - buffer.writeUInt32LE(value[0], offset+4); - buffer.writeUInt32LE(value[1], offset); - return offset + 8; +function writeLU64 (value, buffer, offset) { + buffer.writeUInt32LE(value[0], offset + 4) + buffer.writeUInt32LE(value[1], offset) + return offset + 8 } -function generateFunctions(bufferReader,bufferWriter,size,schema) -{ - const reader=function(buffer, offset) - { - if(offset + size > buffer.length) - throw new PartialReadError(); - const value = buffer[bufferReader](offset); +function generateFunctions (bufferReader, bufferWriter, size, schema) { + const reader = function (buffer, offset) { + if (offset + size > buffer.length) { throw new PartialReadError() } + const value = buffer[bufferReader](offset) return { value: value, size: size - }; - }; - const writer=function(value, buffer, offset) { - buffer[bufferWriter](value, offset); - return offset + size; - }; - return [reader, writer, size, schema]; + } + } + const writer = function (value, buffer, offset) { + buffer[bufferWriter](value, offset) + return offset + size + } + return [reader, writer, size, schema] } -const nums= { - 'i8': ["readInt8", "writeInt8", 1], - 'u8': ["readUInt8", "writeUInt8", 1], - 'i16': ["readInt16BE", "writeInt16BE", 2], - 'u16': ["readUInt16BE", "writeUInt16BE", 2], - 'i32': ["readInt32BE", "writeInt32BE", 4], - 'u32': ["readUInt32BE", "writeUInt32BE", 4], - 'f32': ["readFloatBE", "writeFloatBE", 4], - 'f64': ["readDoubleBE", "writeDoubleBE", 8], - 'li8': ["readInt8", "writeInt8", 1], - 'lu8': ["readUInt8", "writeUInt8", 1], - 'li16': ["readInt16LE", "writeInt16LE", 2], - 'lu16': ["readUInt16LE", "writeUInt16LE", 2], - 'li32': ["readInt32LE", "writeInt32LE", 4], - 'lu32': ["readUInt32LE", "writeUInt32LE", 4], - 'lf32': ["readFloatLE", "writeFloatLE", 4], - 'lf64': ["readDoubleLE", "writeDoubleLE", 8] -}; - -const types=Object.keys(nums).reduce(function(types,num){ - types[num]=generateFunctions(nums[num][0], nums[num][1], nums[num][2], require('../../ProtoDef/schemas/numeric')[num]); - return types; -},{}); -types["i64"]=[readI64, writeI64, 8, require('../../ProtoDef/schemas/numeric')["i64"]]; -types["li64"]=[readLI64, writeLI64, 8, require('../../ProtoDef/schemas/numeric')["li64"]]; -types["u64"]=[readU64, writeU64, 8, require('../../ProtoDef/schemas/numeric')["u64"]]; -types["lu64"]=[readLU64, writeLU64, 8, require('../../ProtoDef/schemas/numeric')["lu64"]]; +const nums = { + 'i8': ['readInt8', 'writeInt8', 1], + 'u8': ['readUInt8', 'writeUInt8', 1], + 'i16': ['readInt16BE', 'writeInt16BE', 2], + 'u16': ['readUInt16BE', 'writeUInt16BE', 2], + 'i32': ['readInt32BE', 'writeInt32BE', 4], + 'u32': ['readUInt32BE', 'writeUInt32BE', 4], + 'f32': ['readFloatBE', 'writeFloatBE', 4], + 'f64': ['readDoubleBE', 'writeDoubleBE', 8], + 'li8': ['readInt8', 'writeInt8', 1], + 'lu8': ['readUInt8', 'writeUInt8', 1], + 'li16': ['readInt16LE', 'writeInt16LE', 2], + 'lu16': ['readUInt16LE', 'writeUInt16LE', 2], + 'li32': ['readInt32LE', 'writeInt32LE', 4], + 'lu32': ['readUInt32LE', 'writeUInt32LE', 4], + 'lf32': ['readFloatLE', 'writeFloatLE', 4], + 'lf64': ['readDoubleLE', 'writeDoubleLE', 8] +} +const types = Object.keys(nums).reduce(function (types, num) { + types[num] = generateFunctions(nums[num][0], nums[num][1], nums[num][2], require('../../ProtoDef/schemas/numeric')[num]) + return types +}, {}) +types['i64'] = [readI64, writeI64, 8, require('../../ProtoDef/schemas/numeric')['i64']] +types['li64'] = [readLI64, writeLI64, 8, require('../../ProtoDef/schemas/numeric')['li64']] +types['u64'] = [readU64, writeU64, 8, require('../../ProtoDef/schemas/numeric')['u64']] +types['lu64'] = [readLU64, writeLU64, 8, require('../../ProtoDef/schemas/numeric')['lu64']] -module.exports = types; +module.exports = types diff --git a/src/datatypes/structures.js b/src/datatypes/structures.js index 46ad2b1..9f03897 100644 --- a/src/datatypes/structures.js +++ b/src/datatypes/structures.js @@ -1,90 +1,90 @@ -const { getField, getCount, sendCount, calcCount, tryDoc } = require("../utils"); +const { getField, getCount, sendCount, calcCount, tryDoc } = require('../utils') module.exports = { 'array': [readArray, writeArray, sizeOfArray, require('../../ProtoDef/schemas/structures')['array']], 'count': [readCount, writeCount, sizeOfCount, require('../../ProtoDef/schemas/structures')['count']], 'container': [readContainer, writeContainer, sizeOfContainer, require('../../ProtoDef/schemas/structures')['container']] -}; +} -function readArray(buffer, offset, typeArgs, rootNode) { +function readArray (buffer, offset, typeArgs, rootNode) { const results = { value: [], size: 0 - }; - let value; - let { count, size } = getCount.call(this, buffer, offset, typeArgs, rootNode); - offset += size; - results.size += size; - for(let i = 0; i < count; i++) { - ({size,value}=tryDoc(() => this.read(buffer, offset, typeArgs.type, rootNode), i)); - results.size += size; - offset += size; - results.value.push(value); } - return results; + let value + let { count, size } = getCount.call(this, buffer, offset, typeArgs, rootNode) + offset += size + results.size += size + for (let i = 0; i < count; i++) { + ({ size, value } = tryDoc(() => this.read(buffer, offset, typeArgs.type, rootNode), i)) + results.size += size + offset += size + results.value.push(value) + } + return results } -function writeArray(value, buffer, offset, typeArgs, rootNode) { - offset = sendCount.call(this, value.length, buffer, offset, typeArgs, rootNode); - return value.reduce((offset,v,index) =>tryDoc(() => this.write(v, buffer, offset, typeArgs.type, rootNode),index),offset); +function writeArray (value, buffer, offset, typeArgs, rootNode) { + offset = sendCount.call(this, value.length, buffer, offset, typeArgs, rootNode) + return value.reduce((offset, v, index) => tryDoc(() => this.write(v, buffer, offset, typeArgs.type, rootNode), index), offset) } -function sizeOfArray(value, typeArgs, rootNode) { - let size = calcCount.call(this, value.length, typeArgs, rootNode); - size = value.reduce((size,v,index) =>tryDoc(() => size+this.sizeOf(v, typeArgs.type, rootNode), index),size); - return size; +function sizeOfArray (value, typeArgs, rootNode) { + let size = calcCount.call(this, value.length, typeArgs, rootNode) + size = value.reduce((size, v, index) => tryDoc(() => size + this.sizeOf(v, typeArgs.type, rootNode), index), size) + return size } - -function readContainer(buffer, offset, typeArgs, context) { +function readContainer (buffer, offset, typeArgs, context) { const results = { - value: { "..": context }, + value: { '..': context }, size: 0 - }; - typeArgs.forEach(({type,name,anon}) => { + } + typeArgs.forEach(({ type, name, anon }) => { tryDoc(() => { - const readResults = this.read(buffer, offset, type, results.value); - results.size += readResults.size; - offset += readResults.size; + const readResults = this.read(buffer, offset, type, results.value) + results.size += readResults.size + offset += readResults.size if (anon) { - if(readResults.value !== undefined) Object.keys(readResults.value).forEach(function(key) { - results.value[key] = readResults.value[key]; - }); - } else - results.value[name] = readResults.value; - }, name ? name : "unknown"); - }); - delete results.value[".."]; - return results; + if (readResults.value !== undefined) { + Object.keys(readResults.value).forEach(function (key) { + results.value[key] = readResults.value[key] + }) + } + } else { results.value[name] = readResults.value } + }, name || 'unknown') + }) + delete results.value['..'] + return results } -function writeContainer(value, buffer, offset, typeArgs, context) { - value[".."] = context; - offset=typeArgs.reduce((offset,{type,name,anon}) => - tryDoc(() => this.write(anon ? value : value[name], buffer, offset, type, value),name ? name : "unknown"),offset); - delete value[".."]; - return offset; +function writeContainer (value, buffer, offset, typeArgs, context) { + value['..'] = context + offset = typeArgs.reduce((offset, { type, name, anon }) => + tryDoc(() => this.write(anon ? value : value[name], buffer, offset, type, value), name || 'unknown'), offset) + delete value['..'] + return offset } -function sizeOfContainer(value, typeArgs, context) { - value[".."] = context; - const size = typeArgs.reduce((size,{type,name,anon}) => - size + tryDoc(() => this.sizeOf(anon ? value : value[name], type, value), name ? name : "unknown"),0); - delete value[".."]; - return size; +function sizeOfContainer (value, typeArgs, context) { + value['..'] = context + const size = typeArgs.reduce((size, { type, name, anon }) => + size + tryDoc(() => this.sizeOf(anon ? value : value[name], type, value), name || 'unknown'), 0) + delete value['..'] + return size } -function readCount(buffer, offset, {type}, rootNode) { - return this.read(buffer, offset, type, rootNode); +function readCount (buffer, offset, { type }, rootNode) { + return this.read(buffer, offset, type, rootNode) } -function writeCount(value, buffer, offset, {countFor,type}, rootNode) { +function writeCount (value, buffer, offset, { countFor, type }, rootNode) { // Actually gets the required field, and writes its length. Value is unused. // TODO : a bit hackityhack. - return this.write(getField(countFor, rootNode).length, buffer, offset, type, rootNode); + return this.write(getField(countFor, rootNode).length, buffer, offset, type, rootNode) } -function sizeOfCount(value, {countFor,type}, rootNode) { +function sizeOfCount (value, { countFor, type }, rootNode) { // TODO : should I use value or getField().length ? - return this.sizeOf(getField(countFor, rootNode).length, type, rootNode); + return this.sizeOf(getField(countFor, rootNode).length, type, rootNode) } diff --git a/src/datatypes/utils.js b/src/datatypes/utils.js index a79de66..5405106 100644 --- a/src/datatypes/utils.js +++ b/src/datatypes/utils.js @@ -1,6 +1,6 @@ -const assert = require('assert'); +const assert = require('assert') -const { getCount, sendCount, calcCount, tryDoc, PartialReadError } = require("../utils"); +const { getCount, sendCount, calcCount, PartialReadError } = require('../utils') module.exports = { 'varint': [readVarInt, writeVarInt, sizeOfVarInt, require('../../ProtoDef/schemas/utils')['varint']], @@ -10,260 +10,251 @@ module.exports = { 'void': [readVoid, writeVoid, 0, require('../../ProtoDef/schemas/utils')['void']], 'bitfield': [readBitField, writeBitField, sizeOfBitField, require('../../ProtoDef/schemas/utils')['bitfield']], 'cstring': [readCString, writeCString, sizeOfCString, require('../../ProtoDef/schemas/utils')['cstring']], - 'mapper':[readMapper,writeMapper,sizeOfMapper, require('../../ProtoDef/schemas/utils')['mapper']] -}; + 'mapper': [readMapper, writeMapper, sizeOfMapper, require('../../ProtoDef/schemas/utils')['mapper']] +} + +function mapperEquality (a, b) { + return a === b || parseInt(a) === parseInt(b) +} -function readMapper(buffer,offset,{type,mappings},rootNode) -{ - const {size,value}=this.read(buffer, offset, type, rootNode); - let mappedValue=null; - const keys=Object.keys(mappings); - for(let i=0;i buffer.length) - throw new PartialReadError(); - const b = buffer.readUInt8(cursor); - result |= ((b & 0x7f) << shift); // Add the bits to our number, except MSB - cursor++; - if(!(b & 0x80)) { // If the MSB is not set, we return the number + while (true) { + if (cursor + 1 > buffer.length) { throw new PartialReadError() } + const b = buffer.readUInt8(cursor) + result |= ((b & 0x7f) << shift) // Add the bits to our number, except MSB + cursor++ + if (!(b & 0x80)) { // If the MSB is not set, we return the number return { value: result, size: cursor - offset - }; + } } - shift += 7; // we only have 7 bits, MSB being the return-trigger - assert.ok(shift < 64, "varint is too big"); // Make sure our shift don't overflow. + shift += 7 // we only have 7 bits, MSB being the return-trigger + assert.ok(shift < 64, 'varint is too big') // Make sure our shift don't overflow. } } -function sizeOfVarInt(value) { - let cursor = 0; - while(value & ~0x7F) { - value >>>= 7; - cursor++; +function sizeOfVarInt (value) { + let cursor = 0 + while (value & ~0x7F) { + value >>>= 7 + cursor++ } - return cursor + 1; + return cursor + 1 } -function writeVarInt(value, buffer, offset) { - let cursor = 0; - while(value & ~0x7F) { - buffer.writeUInt8((value & 0xFF) | 0x80, offset + cursor); - cursor++; - value >>>= 7; +function writeVarInt (value, buffer, offset) { + let cursor = 0 + while (value & ~0x7F) { + buffer.writeUInt8((value & 0xFF) | 0x80, offset + cursor) + cursor++ + value >>>= 7 } - buffer.writeUInt8(value, offset + cursor); - return offset + cursor + 1; + buffer.writeUInt8(value, offset + cursor) + return offset + cursor + 1 } - -function readPString(buffer, offset, typeArgs,rootNode) { - const { size, count } = getCount.call(this, buffer, offset, typeArgs, rootNode); - const cursor = offset + size; - const strEnd = cursor + count; - if(strEnd > buffer.length) throw new PartialReadError("Missing characters in string, found size is "+buffer.length+ - " expected size was "+strEnd); +function readPString (buffer, offset, typeArgs, rootNode) { + const { size, count } = getCount.call(this, buffer, offset, typeArgs, rootNode) + const cursor = offset + size + const strEnd = cursor + count + if (strEnd > buffer.length) { + throw new PartialReadError('Missing characters in string, found size is ' + buffer.length + + ' expected size was ' + strEnd) + } return { value: buffer.toString('utf8', cursor, strEnd), size: strEnd - offset - }; + } } -function writePString(value, buffer, offset, typeArgs,rootNode) { - const length = Buffer.byteLength(value, 'utf8'); - offset = sendCount.call(this, length, buffer, offset, typeArgs, rootNode); - buffer.write(value, offset, length, 'utf8'); - return offset + length; +function writePString (value, buffer, offset, typeArgs, rootNode) { + const length = Buffer.byteLength(value, 'utf8') + offset = sendCount.call(this, length, buffer, offset, typeArgs, rootNode) + buffer.write(value, offset, length, 'utf8') + return offset + length } - -function sizeOfPString(value, typeArgs,rootNode) { - const length = Buffer.byteLength(value, 'utf8'); - const size = calcCount.call(this, length, typeArgs, rootNode); - return size + length; +function sizeOfPString (value, typeArgs, rootNode) { + const length = Buffer.byteLength(value, 'utf8') + const size = calcCount.call(this, length, typeArgs, rootNode) + return size + length } -function readBool(buffer, offset) { - if(offset + 1 > buffer.length) throw new PartialReadError(); - const value = buffer.readInt8(offset); +function readBool (buffer, offset) { + if (offset + 1 > buffer.length) throw new PartialReadError() + const value = buffer.readInt8(offset) return { value: !!value, size: 1 - }; + } } -function writeBool(value, buffer, offset) { - buffer.writeInt8(+value, offset); - return offset + 1; +function writeBool (value, buffer, offset) { + buffer.writeInt8(+value, offset) + return offset + 1 } - -function readBuffer(buffer, offset, typeArgs, rootNode) { - const { size, count } = getCount.call(this, buffer, offset, typeArgs, rootNode); - offset += size; - if(offset+count > buffer.length) throw new PartialReadError(); +function readBuffer (buffer, offset, typeArgs, rootNode) { + const { size, count } = getCount.call(this, buffer, offset, typeArgs, rootNode) + offset += size + if (offset + count > buffer.length) throw new PartialReadError() return { value: buffer.slice(offset, offset + count), size: size + count - }; + } } -function writeBuffer(value, buffer, offset, typeArgs, rootNode) { - offset = sendCount.call(this, value.length, buffer, offset, typeArgs, rootNode); - value.copy(buffer, offset); - return offset + value.length; +function writeBuffer (value, buffer, offset, typeArgs, rootNode) { + offset = sendCount.call(this, value.length, buffer, offset, typeArgs, rootNode) + value.copy(buffer, offset) + return offset + value.length } -function sizeOfBuffer(value, typeArgs, rootNode) { - const size = calcCount.call(this, value.length, typeArgs, rootNode); - return size + value.length; +function sizeOfBuffer (value, typeArgs, rootNode) { + const size = calcCount.call(this, value.length, typeArgs, rootNode) + return size + value.length } -function readVoid() { +function readVoid () { return { value: undefined, size: 0 - }; + } } -function writeVoid(value, buffer, offset) { - return offset; +function writeVoid (value, buffer, offset) { + return offset } -function generateBitMask(n) { - return (1 << n) - 1; +function generateBitMask (n) { + return (1 << n) - 1 } -function readBitField(buffer, offset, typeArgs) { - const beginOffset = offset; - let curVal = null; - let bits = 0; - const results = {}; - results.value = typeArgs.reduce(function(acc, {size,signed,name}) { - let currentSize = size; - let val = 0; +function readBitField (buffer, offset, typeArgs) { + const beginOffset = offset + let curVal = null + let bits = 0 + const results = {} + results.value = typeArgs.reduce(function (acc, { size, signed, name }) { + let currentSize = size + let val = 0 while (currentSize > 0) { - if (bits == 0) { - if(buffer.length> (bits - bitsToRead); - bits -= bitsToRead; - currentSize -= bitsToRead; + const bitsToRead = Math.min(currentSize, bits) + val = (val << bitsToRead) | (curVal & generateBitMask(bits)) >> (bits - bitsToRead) + bits -= bitsToRead + currentSize -= bitsToRead } - if (signed && val >= 1 << (size - 1)) - val -= 1 << size; - acc[name] = val; - return acc; - }, {}); - results.size = offset - beginOffset; - return results; + if (signed && val >= 1 << (size - 1)) { val -= 1 << size } + acc[name] = val + return acc + }, {}) + results.size = offset - beginOffset + return results } -function writeBitField(value, buffer, offset, typeArgs) { - let toWrite = 0; - let bits = 0; - typeArgs.forEach(function({size,signed,name}) { - const val = value[name]; - if ((!signed && val < 0) || (signed && val < -(1 << (size - 1)))) - throw new Error(value + " < " + signed ? (-(1 << (size - 1))) : 0); - else if ((!signed && val >= 1 << size) - || (signed && val >= (1 << (size - 1)) - 1)) - throw new Error(value + " >= " + signed ? (1 << size) : ((1 << (size - 1)) - 1)); +function writeBitField (value, buffer, offset, typeArgs) { + let toWrite = 0 + let bits = 0 + typeArgs.forEach(function ({ size, signed, name }) { + const val = value[name] + if ((!signed && val < 0) || (signed && val < -(1 << (size - 1)))) { throw new Error(value + ' < ' + signed ? (-(1 << (size - 1))) : 0) } else if ((!signed && val >= 1 << size) || + (signed && val >= (1 << (size - 1)) - 1)) { throw new Error(value + ' >= ' + signed ? (1 << size) : ((1 << (size - 1)) - 1)) } while (size > 0) { - const writeBits = Math.min(8 - bits, size); + const writeBits = Math.min(8 - bits, size) toWrite = toWrite << writeBits | - ((val >> (size - writeBits)) & generateBitMask(writeBits)); - size -= writeBits; - bits += writeBits; + ((val >> (size - writeBits)) & generateBitMask(writeBits)) + size -= writeBits + bits += writeBits if (bits === 8) { - buffer[offset++] = toWrite; - bits = 0; - toWrite = 0; + buffer[offset++] = toWrite + bits = 0 + toWrite = 0 } } - }); - if (bits != 0) - buffer[offset++] = toWrite << (8 - bits); - return offset; + }) + if (bits !== 0) { buffer[offset++] = toWrite << (8 - bits) } + return offset } -function sizeOfBitField(value, typeArgs) { - return Math.ceil(typeArgs.reduce(function(acc, {size}) { - return acc + size; - }, 0) / 8); +function sizeOfBitField (value, typeArgs) { + return Math.ceil(typeArgs.reduce(function (acc, { size }) { + return acc + size + }, 0) / 8) } -function readCString(buffer, offset) { - let size=0; - while (offset+size < buffer.length && buffer[offset+size] != 0x00) - size++; - if (buffer.length ({ "path": k + "." + v.path, "val": v.val }))); - return acc; +function findArgs (acc, v, k) { + if (typeof v === 'string' && v.charAt(0) === '$') { acc.push({ 'path': k, 'val': v.substr(1) }) } else if (Array.isArray(v) || typeof v === 'object') { acc = acc.concat(reduce(v, findArgs, []).map((v) => ({ 'path': k + '.' + v.path, 'val': v.val }))) } + return acc } -function setField(path, val, into) { - const c = path.split('.').reverse(); +function setField (path, val, into) { + const c = path.split('.').reverse() while (c.length > 1) { - into = into[c.pop()]; + into = into[c.pop()] } - into[c.pop()] = val; + into[c.pop()] = val } -function extendType(functions, defaultTypeArgs) { - const json=JSON.stringify(defaultTypeArgs); - const argPos = reduce(defaultTypeArgs, findArgs, []); - function produceArgs(typeArgs) { - const args = JSON.parse(json); +function extendType (functions, defaultTypeArgs) { + const json = JSON.stringify(defaultTypeArgs) + const argPos = reduce(defaultTypeArgs, findArgs, []) + function produceArgs (typeArgs) { + const args = JSON.parse(json) argPos.forEach((v) => { - setField(v.path, typeArgs[v.val], args); - }); - return args; + setField(v.path, typeArgs[v.val], args) + }) + return args } - return [function read(buffer, offset, typeArgs, context) { - return functions[0].call(this, buffer, offset, produceArgs(typeArgs), context); - }, function write(value, buffer, offset, typeArgs, context) { - return functions[1].call(this, value, buffer, offset, produceArgs(typeArgs), context); - }, function sizeOf(value, typeArgs, context) { - if (typeof functions[2] === "function") - return functions[2].call(this, value, produceArgs(typeArgs), context); - else - return functions[2]; - }]; + return [function read (buffer, offset, typeArgs, context) { + return functions[0].call(this, buffer, offset, produceArgs(typeArgs), context) + }, function write (value, buffer, offset, typeArgs, context) { + return functions[1].call(this, value, buffer, offset, produceArgs(typeArgs), context) + }, function sizeOf (value, typeArgs, context) { + if (typeof functions[2] === 'function') { return functions[2].call(this, value, produceArgs(typeArgs), context) } else { return functions[2] } + }] } -class ProtoDef -{ - constructor(validation=true) { - this.types={}; - this.validator=validation ? new Validator() : null; - this.addDefaultTypes(); +class ProtoDef { + constructor (validation = true) { + this.types = {} + this.validator = validation ? new Validator() : null + this.addDefaultTypes() } - addDefaultTypes() { - this.addTypes(require("./datatypes/numeric")); - this.addTypes(require("./datatypes/utils")); - this.addTypes(require("./datatypes/structures")); - this.addTypes(require("./datatypes/conditional")); + addDefaultTypes () { + this.addTypes(require('./datatypes/numeric')) + this.addTypes(require('./datatypes/utils')) + this.addTypes(require('./datatypes/structures')) + this.addTypes(require('./datatypes/conditional')) } - - addProtocol(protocolData, path) { - const self=this; - function recursiveAddTypes(protocolData,path) - { - if(protocolData===undefined) - return; - if(protocolData.types) - self.addTypes(protocolData.types); - recursiveAddTypes(get(protocolData,path.shift()),path); + + addProtocol (protocolData, path) { + const self = this + function recursiveAddTypes (protocolData, path) { + if (protocolData === undefined) { return } + if (protocolData.types) { self.addTypes(protocolData.types) } + recursiveAddTypes(get(protocolData, path.shift()), path) } - if(this.validator) - this.validator.validateProtocol(protocolData); + if (this.validator) { this.validator.validateProtocol(protocolData) } - recursiveAddTypes(protocolData,path); + recursiveAddTypes(protocolData, path) } - addType(name, functions, validate=true) { - if (functions === "native") { - if(this.validator) - this.validator.addType(name); - return; + addType (name, functions, validate = true) { + if (functions === 'native') { + if (this.validator) { this.validator.addType(name) } + return } if (isFieldInfo(functions)) { - if(this.validator) { - if (validate) - this.validator.validateType(functions); - this.validator.addType(name); + if (this.validator) { + if (validate) { this.validator.validateType(functions) } + this.validator.addType(name) } - let {type,typeArgs} = getFieldInfo(functions); - this.types[name] = typeArgs ? extendType(this.types[type], typeArgs) : this.types[type]; - } - else { - if(this.validator) { + let { type, typeArgs } = getFieldInfo(functions) + this.types[name] = typeArgs ? extendType(this.types[type], typeArgs) : this.types[type] + } else { + if (this.validator) { if (functions[3]) { - this.validator.addType(name, functions[3]); - } - else - this.validator.addType(name); + this.validator.addType(name, functions[3]) + } else { this.validator.addType(name) } } - this.types[name] = functions; + this.types[name] = functions } } - addTypes(types) { - Object.keys(types).forEach((name) => this.addType(name, types[name],false)); - if(this.validator) { + addTypes (types) { + Object.keys(types).forEach((name) => this.addType(name, types[name], false)) + if (this.validator) { Object.keys(types).forEach((name) => { if (isFieldInfo(types[name])) { this.validator.validateType(types[name]) } - }); + }) } } - read(buffer, cursor, _fieldInfo, rootNodes) { - let {type,typeArgs} = getFieldInfo(_fieldInfo); - const typeFunctions = this.types[type]; - if(!typeFunctions) - throw new Error("missing data type: " + type); - return typeFunctions[0].call(this, buffer, cursor, typeArgs, rootNodes); + read (buffer, cursor, _fieldInfo, rootNodes) { + let { type, typeArgs } = getFieldInfo(_fieldInfo) + const typeFunctions = this.types[type] + if (!typeFunctions) { throw new Error('missing data type: ' + type) } + return typeFunctions[0].call(this, buffer, cursor, typeArgs, rootNodes) } - write(value, buffer, offset, _fieldInfo, rootNode) { - let {type,typeArgs} = getFieldInfo(_fieldInfo); - const typeFunctions = this.types[type]; - if(!typeFunctions) - throw new Error("missing data type: " + type); - return typeFunctions[1].call(this, value, buffer, offset, typeArgs, rootNode); + write (value, buffer, offset, _fieldInfo, rootNode) { + let { type, typeArgs } = getFieldInfo(_fieldInfo) + const typeFunctions = this.types[type] + if (!typeFunctions) { throw new Error('missing data type: ' + type) } + return typeFunctions[1].call(this, value, buffer, offset, typeArgs, rootNode) } - sizeOf(value, _fieldInfo, rootNode) { - let {type,typeArgs} = getFieldInfo(_fieldInfo); - const typeFunctions = this.types[type]; - if(!typeFunctions) { - throw new Error("missing data type: " + type); + sizeOf (value, _fieldInfo, rootNode) { + let { type, typeArgs } = getFieldInfo(_fieldInfo) + const typeFunctions = this.types[type] + if (!typeFunctions) { + throw new Error('missing data type: ' + type) } - if(typeof typeFunctions[2] === 'function') { - return typeFunctions[2].call(this, value, typeArgs, rootNode); + if (typeof typeFunctions[2] === 'function') { + return typeFunctions[2].call(this, value, typeArgs, rootNode) } else { - return typeFunctions[2]; + return typeFunctions[2] } } - createPacketBuffer(type,packet) { - const length=tryCatch(()=> this.sizeOf(packet, type, {}), - (e)=> { - e.message = `SizeOf error for ${e.field} : ${e.message}`; - throw e; - }); - const buffer = new Buffer(length); - tryCatch(()=> this.write(packet, buffer, 0, type, {}), - (e)=> { - e.message = `Write error for ${e.field} : ${e.message}`; - throw e; - }); - return buffer; + createPacketBuffer (type, packet) { + const length = tryCatch(() => this.sizeOf(packet, type, {}), + (e) => { + e.message = `SizeOf error for ${e.field} : ${e.message}` + throw e + }) + const buffer = Buffer.allocUnsafe(length) + tryCatch(() => this.write(packet, buffer, 0, type, {}), + (e) => { + e.message = `Write error for ${e.field} : ${e.message}` + throw e + }) + return buffer } - parsePacketBuffer(type,buffer) { - const {value,size}=tryCatch(()=> this.read(buffer, 0, type, {}), + parsePacketBuffer (type, buffer) { + const { value, size } = tryCatch(() => this.read(buffer, 0, type, {}), (e) => { - e.message=`Read error for ${e.field} : ${e.message}`; - throw e; - }); + e.message = `Read error for ${e.field} : ${e.message}` + throw e + }) return { data: value, - metadata:{ - size:size + metadata: { + size: size }, - buffer:buffer.slice(0,size) - }; + buffer: buffer.slice(0, size) + } } } -module.exports = ProtoDef; +module.exports = ProtoDef diff --git a/src/serializer.js b/src/serializer.js index f7e8a09..f7632df 100644 --- a/src/serializer.js +++ b/src/serializer.js @@ -1,89 +1,85 @@ -const Transform = require("readable-stream").Transform; +const Transform = require('readable-stream').Transform class Serializer extends Transform { - constructor(proto, mainType) { - super({ writableObjectMode: true }); - this.proto = proto; - this.mainType = mainType; - this.queue = Buffer.alloc(0); + constructor (proto, mainType) { + super({ writableObjectMode: true }) + this.proto = proto + this.mainType = mainType + this.queue = Buffer.alloc(0) } - createPacketBuffer(packet) { - return this.proto.createPacketBuffer(this.mainType,packet); + createPacketBuffer (packet) { + return this.proto.createPacketBuffer(this.mainType, packet) } - _transform(chunk, enc, cb) { - let buf; + _transform (chunk, enc, cb) { + let buf try { - buf = this.createPacketBuffer(chunk); + buf = this.createPacketBuffer(chunk) } catch (e) { - return cb(e); + return cb(e) } - this.push(buf); - return cb(); + this.push(buf) + return cb() } } class Parser extends Transform { - constructor(proto, mainType) { - super({ readableObjectMode: true }); - this.proto = proto; - this.mainType = mainType; - this.queue = Buffer.alloc(0); + constructor (proto, mainType) { + super({ readableObjectMode: true }) + this.proto = proto + this.mainType = mainType + this.queue = Buffer.alloc(0) } - parsePacketBuffer(buffer) { - return this.proto.parsePacketBuffer(this.mainType,buffer); + parsePacketBuffer (buffer) { + return this.proto.parsePacketBuffer(this.mainType, buffer) } - _transform(chunk, enc, cb) { - this.queue = Buffer.concat([this.queue, chunk]); - while(true) { - let packet; + _transform (chunk, enc, cb) { + this.queue = Buffer.concat([this.queue, chunk]) + while (true) { + let packet try { - packet = this.parsePacketBuffer(this.queue); - } - catch (e) { - if (e.partialReadError) - return cb(); - else { - e.buffer = this.queue; - this.queue = Buffer.alloc(0); - return cb(e); + packet = this.parsePacketBuffer(this.queue) + } catch (e) { + if (e.partialReadError) { return cb() } else { + e.buffer = this.queue + this.queue = Buffer.alloc(0) + return cb(e) } } - this.push(packet); - this.queue=this.queue.slice(packet.metadata.size); + this.push(packet) + this.queue = this.queue.slice(packet.metadata.size) } } } - class FullPacketParser extends Transform { - constructor(proto,mainType) { - super({ readableObjectMode: true }); - this.proto=proto; - this.mainType=mainType; + constructor (proto, mainType) { + super({ readableObjectMode: true }) + this.proto = proto + this.mainType = mainType } - parsePacketBuffer(buffer) { - return this.proto.parsePacketBuffer(this.mainType,buffer); + parsePacketBuffer (buffer) { + return this.proto.parsePacketBuffer(this.mainType, buffer) } - _transform(chunk, enc, cb) { - let packet; + _transform (chunk, enc, cb) { + let packet try { - packet = this.parsePacketBuffer(chunk); - if(packet.metadata.size!==chunk.length) - console.log("Chunk size is "+chunk.length+" but only "+packet.metadata.size+" was read ; partial packet : "+ - JSON.stringify(packet.data)+"; buffer :"+chunk.toString("hex")); - } - catch(e) { - return cb(e); + packet = this.parsePacketBuffer(chunk) + if (packet.metadata.size !== chunk.length) { + console.log('Chunk size is ' + chunk.length + ' but only ' + packet.metadata.size + ' was read ; partial packet : ' + + JSON.stringify(packet.data) + '; buffer :' + chunk.toString('hex')) + } + } catch (e) { + return cb(e) } - this.push(packet); - cb(); + this.push(packet) + cb() } } @@ -91,4 +87,4 @@ module.exports = { Serializer: Serializer, Parser: Parser, FullPacketParser: FullPacketParser -}; +} diff --git a/src/utils.js b/src/utils.js index 96db0a2..1b8e9f6 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,85 +1,72 @@ -function getField(countField, context) { - const countFieldArr = countField.split("/"); - let i = 0; - if (countFieldArr[i] === "") { - while (context.hasOwnProperty("..")) - context = context[".."]; - i++; +function getField (countField, context) { + const countFieldArr = countField.split('/') + let i = 0 + if (countFieldArr[i] === '') { + while (context.hasOwnProperty('..')) { context = context['..'] } + i++ } - for(; i < countFieldArr.length; i++) - context = context[countFieldArr[i]]; - return context; + for (; i < countFieldArr.length; i++) { context = context[countFieldArr[i]] } + return context } -function getFieldInfo(fieldInfo) { - if (typeof fieldInfo === "string") - return { type: fieldInfo }; - else if (Array.isArray(fieldInfo)) - return { type: fieldInfo[0], typeArgs: fieldInfo[1] }; - else if (typeof fieldInfo.type === "string") - return fieldInfo; - else - throw new Error("Not a fieldinfo"); +function getFieldInfo (fieldInfo) { + if (typeof fieldInfo === 'string') { return { type: fieldInfo } } else if (Array.isArray(fieldInfo)) { return { type: fieldInfo[0], typeArgs: fieldInfo[1] } } else if (typeof fieldInfo.type === 'string') { return fieldInfo } else { throw new Error('Not a fieldinfo') } } -function getCount(buffer, offset, { count, countType }, rootNode) { - let c = 0; - let size = 0; - if(typeof count === "number") - c = count; - else if (typeof count !== "undefined") { - c = getField(count, rootNode); - } else if (typeof countType !== "undefined") { - ({size,value: c}=tryDoc(() => this.read(buffer, offset, getFieldInfo(countType), rootNode),"$count")); - } else // TODO : broken schema, should probably error out. - c = 0; - return { count: c, size }; +function getCount (buffer, offset, { count, countType }, rootNode) { + let c = 0 + let size = 0 + if (typeof count === 'number') { c = count } else if (typeof count !== 'undefined') { + c = getField(count, rootNode) + } else if (typeof countType !== 'undefined') { + ({ size, value: c } = tryDoc(() => this.read(buffer, offset, getFieldInfo(countType), rootNode), '$count')) + } else { // TODO : broken schema, should probably error out. + c = 0 + } + return { count: c, size } } -function sendCount(len, buffer, offset, { count, countType }, rootNode) { - if (typeof count !== "undefined" && len !== count) { +function sendCount (len, buffer, offset, { count, countType }, rootNode) { + if (typeof count !== 'undefined' && len !== count) { // TODO: Throw - } else if (typeof countType !== "undefined") { - offset = this.write(len, buffer, offset, getFieldInfo(countType), rootNode); + } else if (typeof countType !== 'undefined') { + offset = this.write(len, buffer, offset, getFieldInfo(countType), rootNode) } else { // TODO: Throw } - return offset; + return offset } -function calcCount(len, { count, countType }, rootNode) { - if (typeof count === "undefined" && typeof countType !== "undefined") - return tryDoc(() => this.sizeOf(len, getFieldInfo(countType), rootNode),"$count"); - else - return 0; +function calcCount (len, { count, countType }, rootNode) { + if (typeof count === 'undefined' && typeof countType !== 'undefined') { return tryDoc(() => this.sizeOf(len, getFieldInfo(countType), rootNode), '$count') } else { return 0 } } -function addErrorField(e, field) { - e.field = e.field ? field + "." + e.field : field; - throw e; +function addErrorField (e, field) { + e.field = e.field ? field + '.' + e.field : field + throw e } -function tryCatch(tryfn, catchfn) { - try { return tryfn(); } catch (e) { catchfn(e); } +function tryCatch (tryfn, catchfn) { + try { return tryfn() } catch (e) { catchfn(e) } } -function tryDoc(tryfn,field) { - return tryCatch(tryfn,(e) => addErrorField(e,field)); +function tryDoc (tryfn, field) { + return tryCatch(tryfn, (e) => addErrorField(e, field)) } class ExtendableError extends Error { - constructor(message) { - super(message); - this.name = this.constructor.name; - this.message = message; + constructor (message) { + super(message) + this.name = this.constructor.name + this.message = message Error.captureStackTrace(this, this.constructor.name) } } class PartialReadError extends ExtendableError { - constructor(message) { - super(message); - this.partialReadError=true; + constructor (message) { + super(message) + this.partialReadError = true } } @@ -92,5 +79,5 @@ module.exports = { calcCount: calcCount, tryCatch: tryCatch, tryDoc: tryDoc, - PartialReadError:PartialReadError -}; + PartialReadError: PartialReadError +} diff --git a/test/dataTypes/datatypes.js b/test/dataTypes/datatypes.js index 5683c83..e396584 100644 --- a/test/dataTypes/datatypes.js +++ b/test/dataTypes/datatypes.js @@ -1,76 +1,69 @@ -const expect = require('chai').expect; -const PartialReadError=require("../../").utils.PartialReadError; -const Validator = require('jsonschema').Validator; -const v = new Validator(); -const assert = require('assert'); +/* eslint-env mocha */ -const testData=require("./prepareTests").testData; -const proto=require("./prepareTests").proto; +const expect = require('chai').expect +const Validator = require('jsonschema').Validator +const v = new Validator() +const assert = require('assert') -function testValue(type,value,buffer) -{ - it('writes',function(){ - expect(proto.createPacketBuffer(type,value)).to.deep.equal(buffer); - }); - it('reads',function(){ - const actualResult=proto.parsePacketBuffer(type,buffer); - if(value===null) - assert.ok(actualResult.data == undefined); - else - expect(actualResult.data).to.deep.equal(value); - expect(actualResult.metadata.size).to.deep.equal(buffer.length); - }); +const testData = require('./prepareTests').testData +const proto = require('./prepareTests').proto + +function testValue (type, value, buffer) { + it('writes', function () { + expect(proto.createPacketBuffer(type, value)).to.deep.equal(buffer) + }) + it('reads', function () { + const actualResult = proto.parsePacketBuffer(type, buffer) + if (value === null) { assert.ok(actualResult.data === undefined) } else { expect(actualResult.data).to.deep.equal(value) } + expect(actualResult.metadata.size).to.deep.equal(buffer.length) + }) } -function testType(type,values) -{ - if(values.length==0) +function testType (type, values) { + if (values.length === 0) { it.skip('Has no tests', () => { - }); + }) + } values.forEach((value) => { - if(value.description) - describe(value.description,() => { - testValue(type,value.value,value.buffer); - }); - else - testValue(type,value.value,value.buffer); - }); - if(type!="void") + if (value.description) { + describe(value.description, () => { + testValue(type, value.value, value.buffer) + }) + } else { testValue(type, value.value, value.buffer) } + }) + if (type !== 'void') { it('reads 0 bytes and throw a PartialReadError', () => { try { - proto.parsePacketBuffer(type,new Buffer(0)); - } - catch (e) { - if(!e.partialReadError) - throw e; - return; + proto.parsePacketBuffer(type, Buffer.alloc(0)) + } catch (e) { + if (!e.partialReadError) { throw e } + return } - throw Error("no PartialReadError thrown"); - }); + throw Error('no PartialReadError thrown') + }) + } } testData.forEach(tests => { - describe(tests.kind,()=> { - it("validates the json schema",()=>{ - const schema = require('../../ProtoDef/test/datatype_tests_schema.json'); - v.addSchema(require('../../ProtoDef/schemas/datatype'),'dataType'); - const result = v.validate(tests.originalData, schema); - assert.strictEqual(result.errors.length,0,require('util').inspect(result.errors,{'depth':null})); - }); + describe(tests.kind, () => { + it('validates the json schema', () => { + const schema = require('../../ProtoDef/test/datatype_tests_schema.json') + v.addSchema(require('../../ProtoDef/schemas/datatype'), 'dataType') + const result = v.validate(tests.originalData, schema) + assert.strictEqual(result.errors.length, 0, require('util').inspect(result.errors, { 'depth': null })) + }) tests.data.forEach(test => { - describe(test.type,() => { + describe(test.type, () => { test.subtypes.forEach((subtype) => { - if(subtype.description) - describe(subtype.description,() => { - testType(subtype.type,subtype.values); - }); - else - testType(test.type,subtype.values); - }); - }); - }); - }); -}); - + if (subtype.description) { + describe(subtype.description, () => { + testType(subtype.type, subtype.values) + }) + } else { testType(test.type, subtype.values) } + }) + }) + }) + }) +}) diff --git a/test/dataTypes/prepareTests.js b/test/dataTypes/prepareTests.js index 9313f13..c1e7a49 100644 --- a/test/dataTypes/prepareTests.js +++ b/test/dataTypes/prepareTests.js @@ -1,61 +1,58 @@ -const ProtoDef = require("protodef").ProtoDef; +const ProtoDef = require('protodef').ProtoDef -const proto = new ProtoDef(); +const proto = new ProtoDef() const testData = [ { - "kind":"conditional", - "data":require("../../ProtoDef/test/conditional.json") + 'kind': 'conditional', + 'data': require('../../ProtoDef/test/conditional.json') }, { - "kind":"numeric", - "data":require("../../ProtoDef/test/numeric.json") + 'kind': 'numeric', + 'data': require('../../ProtoDef/test/numeric.json') }, { - "kind":"structures", - "data":require("../../ProtoDef/test/structures.json") + 'kind': 'structures', + 'data': require('../../ProtoDef/test/structures.json') }, { - "kind":"utils", - "data":require("../../ProtoDef/test/utils.json") + 'kind': 'utils', + 'data': require('../../ProtoDef/test/utils.json') } -]; +] -function arrayToBuffer(arr) -{ - return Buffer.from(arr.map(e => parseInt(e))); +function arrayToBuffer (arr) { + return Buffer.from(arr.map(e => parseInt(e))) } -function transformValues(type,values) -{ +function transformValues (type, values) { return values.map(value => ({ buffer: arrayToBuffer(value.buffer), - value: type.indexOf("buffer") == 0 ? arrayToBuffer(value.value) : value.value, + value: type.indexOf('buffer') === 0 ? arrayToBuffer(value.value) : value.value, description: value.description - })); + })) } - testData.forEach(tests => { - tests.originalData=JSON.parse(JSON.stringify(tests.data)); + tests.originalData = JSON.parse(JSON.stringify(tests.data)) tests.data.forEach(test => { - const subTypes = []; - if (test.subtypes) + const subTypes = [] + if (test.subtypes) { test.subtypes.forEach((subtype, i) => { - const type = test.type + "_" + i; - proto.addType(type, subtype.type); - - subtype.values = transformValues(test.type, subtype.values); - subtype.type = type; - subTypes.push(subtype); - }); - else { - test.values = transformValues(test.type, test.values); - subTypes.push({type: test.type, values: test.values}); + const type = test.type + '_' + i + proto.addType(type, subtype.type) + + subtype.values = transformValues(test.type, subtype.values) + subtype.type = type + subTypes.push(subtype) + }) + } else { + test.values = transformValues(test.type, test.values) + subTypes.push({ type: test.type, values: test.values }) } - test.subtypes=subTypes; - }); -}); + test.subtypes = subTypes + }) +}) -module.exports.testData = testData; -module.exports.proto = proto; +module.exports.testData = testData +module.exports.proto = proto