Skip to content

Commit

Permalink
Whole serialize alternation of open range.
Browse files Browse the repository at this point in the history
Closes #343.
  • Loading branch information
flatheadmill committed Aug 12, 2015
1 parent ed57df6 commit eb2065f
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 16 deletions.
87 changes: 71 additions & 16 deletions compose/serializer/all.js
Expand Up @@ -19,6 +19,59 @@ function nested (variables, definition, depth) {
')
}

function alternation (variables, name, field, depth) {
var select = qualify('select', depth)
variables.hoist(select)
field.choose.forEach(function (option, index) {
var when = option.write.when || {}, test
if (when.range != null) {
var range = []
if (when.range.from) {
range.push(when.range.from + ' <= select')
}
if (when.range.to) {
range.push('select < ' + when.range.to)
}
test = range.join(' && ')
}
option.condition = '} else {'
if (test) {
if (index === 0) {
option.condition = 'if (' + test + ') {'
} else {
option.condition = '} else if (' + test + ') {'
}
}
})
var choices = ''
function slurp (option) {
return subSerialize(variables, name, explode(option.write), depth)
}
field.choose.forEach(function (option) {
choices = $(' \n\
// __reference__ \n\
', choices, ' \n\
', option.condition, ' \n\
// __blank__ \n\
', slurp(option), ' \n\
// __blank__ \n\
')
})
var source = $(' \n\
' + select + ' = object.' + name + ' \n\
')
choices = $(' \n\
// __reference__ \n\
', choices, ' \n\
} \n\
')
return $(' \n\
', source, ' \n\
// __blank__ \n\
', choices, ' \n\
')
}

function lengthEncoded (variables, name, field, depth) {
var source = ''
var object = qualify('object', depth)
Expand All @@ -45,25 +98,27 @@ function lengthEncoded (variables, name, field, depth) {
return source
}

function subSerialize (variables, name, field, depth) {
if (field.type === 'alternation') {
return alternation(variables, name, field, depth)
} else if (field.length) {
return lengthEncoded(variables, name, field, depth)
} else {
var object = qualify('object', depth)
field = explode(field)
if (field.type === 'integer') {
return $(' \n\
', integer(field, object + '.' + name), ' \n\
// __reference__ \n\
')
}
}
}

function serialize (variables, definition, depth) {
var sources = []
for (var name in definition) {
if (name[0] === '$') {
continue
}
var field = definition[name]
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\
'))
}
}
sources.push(subSerialize(variables, name, definition[name], depth))
}
return joinSources(sources)
}
Expand Down
36 changes: 36 additions & 0 deletions t/generated/alternation.serialize.all.js
@@ -0,0 +1,36 @@
module.exports = (function () {
var serializers = {}

serializers.object = function (object) {
this.object = object
}

serializers.object.prototype.serialize = function (engine) {
var buffer = engine.buffer
var start = engine.start
var end = engine.end

var object = this.object

var select

select = object.number

if (128 <= select) {

buffer[start++] = object.number >>> 8 & 0xff
buffer[start++] = object.number & 0xff

} else {

buffer[start++] = object.number & 0xff

}

engine.start = start

return object
}

return serializers
})()
51 changes: 51 additions & 0 deletions t/serialize/all/alternation.t.js
@@ -0,0 +1,51 @@
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/alternation.serialize.all.js')

var serializers = composer(compiler(filename), {
object: {
number: {
type: 'alternation',
select: { endianess: 'b', bits: 8 },
choose: [{
read: {
when: { and: 0x80 },
endianess: 'b',
bits: 16
},
write: {
when: { range: { from: 0x80 } },
endianess: 'b',
bits: 16
}
}, {
read: {
endianess: 'b',
bits: 8
},
write: {
endianess: 'b',
bits: 8
}
}]
}
}
})
var buffer = new Buffer(2)
var object = {
number: 0xffff
}
var engine = {
buffer: buffer,
start: 0,
end: buffer.length
}
var serializer = new serializers.object(object)
serializer.serialize(engine)
assert(buffer.toJSON(), [ 0xff, 0xff ], 'compiled')
assert(engine.start, buffer.length, 'start moved')
}

0 comments on commit eb2065f

Please sign in to comment.