-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement serialization of an array of objects.
Closes #333.
- Loading branch information
1 parent
a5a53ab
commit afb26ac
Showing
8 changed files
with
255 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
function explode (field) { | ||
var little = field.endianness === 'l' | ||
var bytes = field.bits / 8 | ||
return { | ||
endianness: field.endianess, | ||
type: 'integer', | ||
little: little, | ||
bite: little ? 0 : bytes - 1, | ||
direction: little ? 1 : -1, | ||
stop: little ? bytes : -1, | ||
bits: field.bits, | ||
bytes: bytes | ||
} | ||
} | ||
|
||
module.exports = explode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
function qualify (name, depth) { | ||
return name + (depth ? depth : '') | ||
} | ||
|
||
module.exports = qualify |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
var Variables = require('../variables') | ||
var explode = require('../explode') | ||
var qualify = require('../qualify') | ||
var $ = require('programmatic') | ||
|
||
function integer (field, value) { | ||
var bites = [], bite = field.bite, stop = field.stop, shift | ||
while (bite != stop) { | ||
shift = bite ? value + ' >>> ' + bite * 8 : value | ||
bites.push('buffer[start++] = ' + shift + ' & 0xff') | ||
bite += field.direction | ||
} | ||
return bites.join('\n') | ||
} | ||
|
||
function nested (variables, definition, depth) { | ||
return $(' \n\ | ||
', serialize(variables, definition, depth), ' \n\ | ||
') | ||
} | ||
|
||
function lengthEncoded (variables, name, field, depth) { | ||
var source = '' | ||
var object = qualify('object', depth) | ||
var length = qualify('length', depth) | ||
var array = qualify('array', depth) | ||
var subObject = qualify('object', depth + 1) | ||
var i = qualify('i', depth) | ||
variables.hoist(i) | ||
variables.hoist(length) | ||
variables.hoist(array) | ||
variables.hoist(subObject) | ||
var looped = nested(variables, field, depth + 1) | ||
source = $(' \n\ | ||
' + array + ' = ' + object + '.' + name + ' \n\ | ||
' + length + ' = array.length \n\ | ||
// __blank__ \n\ | ||
', integer(explode(field.$length), length), ' \n\ | ||
// __blank__ \n\ | ||
for (' + i + ' = 0; ' + i + ' < length; ' + i + '++) { \n\ | ||
' + subObject + ' = array[' + i + '] \n\ | ||
', looped, ' \n\ | ||
} \n\ | ||
') | ||
return source | ||
} | ||
|
||
function serialize (variables, definition, depth) { | ||
var sources = [] | ||
for (var name in definition) { | ||
if (name[0] === '$') { | ||
continue | ||
} | ||
var field = definition[name] | ||
if (Array.isArray(field)) { | ||
field = field[0] | ||
if (field.$length) { | ||
sources.push(lengthEncoded(variables, name, field, depth)) | ||
} | ||
} else { | ||
var object = qualify('object', depth) | ||
field = explode(field) | ||
if (field.type === 'integer') { | ||
sources.push($(' \n\ | ||
', integer(field, object + '.' + name), ' \n\ | ||
// __reference__ \n\ | ||
')) | ||
} | ||
} | ||
} | ||
return joinSources(sources) | ||
} | ||
|
||
function joinSources (sources) { | ||
var source = sources[0] | ||
for (var i = 1, I = sources.length; i < I; i++) { | ||
source = $(' \n\ | ||
', source, ' \n\ | ||
// __blank__ \n\ | ||
', sources[i], ' \n\ | ||
') | ||
} | ||
return source | ||
} | ||
|
||
function serializer (name, definition) { | ||
var variables = new Variables | ||
var source = $(' \n\ | ||
', serialize(variables, definition, 0), ' \n\ | ||
') | ||
return $(' \n\ | ||
serializers.' + name + ' = function () { \n\ | ||
} \n\ | ||
// __blank__ \n\ | ||
serializers.' + name + '.prototype.serialize = function (engine) { \n\ | ||
var buffer = engine.buffer \n\ | ||
var start = engine.start \n\ | ||
var end = engine.end \n\ | ||
var object = engine.object \n\ | ||
// __blank__ \n\ | ||
', String(variables), ' \n\ | ||
// __blank__ \n\ | ||
', source, ' \n\ | ||
// __blank__ \n\ | ||
engine.start = start \n\ | ||
// __blank__ \n\ | ||
return object \n\ | ||
} \n\ | ||
') | ||
} | ||
|
||
module.exports = function (compiler, definition) { | ||
var source = $(' \n\ | ||
var serializers = {} \n\ | ||
') | ||
Object.keys(definition).forEach(function (packet) { | ||
source = $(' \n\ | ||
', source, ' \n\ | ||
// __blank__ \n\ | ||
', serializer(packet, definition[packet]), ' \n\ | ||
') | ||
}) | ||
source = $(' \n\ | ||
', source, ' \n\ | ||
// __blank__ \n\ | ||
return serializers \n\ | ||
') | ||
return compiler(source) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
function Variables () { | ||
this._variables = [] | ||
} | ||
|
||
Variables.prototype.hoist = function (variable) { | ||
if (this._variables.indexOf(variable) === -1) { | ||
this._variables.push(variable) | ||
this._variables.sort() | ||
} | ||
} | ||
|
||
Variables.prototype.toString = function () { | ||
return this._variables.map(function (variable) { | ||
return 'var ' + variable | ||
}).join('\n') | ||
} | ||
|
||
module.exports = Variables |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
module.exports = (function () { | ||
var parsers | ||
|
||
parsers = {} | ||
var parsers = {} | ||
|
||
parsers.object = function () { | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
module.exports = (function () { | ||
var serializers = {} | ||
|
||
serializers.object = function () { | ||
} | ||
|
||
serializers.object.prototype.serialize = function (engine) { | ||
var buffer = engine.buffer | ||
var start = engine.start | ||
var end = engine.end | ||
var object = engine.object | ||
|
||
var array | ||
var i | ||
var length | ||
var object1 | ||
|
||
array = object.values | ||
length = array.length | ||
|
||
buffer[start++] = length >>> 8 & 0xff | ||
buffer[start++] = length & 0xff | ||
|
||
for (i = 0; i < length; i++) { | ||
object1 = array[i] | ||
buffer[start++] = object1.key >>> 8 & 0xff | ||
buffer[start++] = object1.key & 0xff | ||
|
||
buffer[start++] = object1.value >>> 8 & 0xff | ||
buffer[start++] = object1.value & 0xff | ||
} | ||
|
||
engine.start = start | ||
|
||
return object | ||
} | ||
|
||
return serializers | ||
})() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
require('proof')(2, prove) | ||
|
||
function prove (assert) { | ||
var path = require('path') | ||
var compiler = require('../../../compiler/require') | ||
var composer = require('../../../compose/serializer/all.js') | ||
var filename = path.resolve(__filename, '../../../generated/array-of-objects.serialize.all.js') | ||
|
||
var serializers = composer(compiler(filename), { | ||
object: { | ||
values: [{ | ||
$length: { | ||
endianess: 'b', | ||
bits: 16 | ||
}, | ||
key: { | ||
endianess: 'b', | ||
bits: 16 | ||
}, | ||
value: { | ||
endianess: 'b', | ||
bits: 16 | ||
} | ||
}] | ||
} | ||
}) | ||
var buffer = new Buffer(10) | ||
var object = { | ||
values: [ { key: 2570, value: 1 }, { key: 2, value: 3 } ] | ||
} | ||
var engine = { | ||
buffer: buffer, | ||
start: 0, | ||
end: buffer.length, | ||
object: object | ||
} | ||
var serializer = new serializers.object | ||
serializer.serialize(engine) | ||
assert(engine.buffer.toJSON() , [ | ||
0x0, 0x2, 0xa, 0xa, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3 | ||
], 'compiled') | ||
assert(engine.start, buffer.length, 'start moved') | ||
} |