Skip to content

Commit

Permalink
Implement conditional length encodings.
Browse files Browse the repository at this point in the history
Finish by implementing switch conditionals.

Closes #570.
  • Loading branch information
flatheadmill committed Aug 13, 2020
1 parent b5c0e48 commit 4f27805
Show file tree
Hide file tree
Showing 45 changed files with 2,411 additions and 5 deletions.
2 changes: 1 addition & 1 deletion language.js
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ module.exports = function (packets) {
function lengthEncoded () {
const fields = []
assert(Array.isArray(packet[1]))
const encoding = map(packet[0], {})
const encoding = map(packet[0], { dotted: '' })
const element = buffered(packet[1][0]) || map(packet[1][0], {})
assert.equal(element.length, 1, 'badness')
fields.push({
Expand Down
15 changes: 13 additions & 2 deletions sizeof.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,23 @@ function generate (packet, { require = null }) {
}
break
case 'lengthEncoded': {
const encoding = map(dispatch, `${path}.length`, field.encoding)
const encoding = function () {
if (field.fields[0].type == 'buffer' && ! field.fields[0].concat) {
variables.length = true
return $(`
$length = ${path}.reduce((sum, buffer) => sum + buffer.length, 0)
`, map(dispatch, '$length', field.encoding), `
`)
}
return map(dispatch, `${path}.length`, field.encoding)
} ()
if (field.fields[0].fixed) {
return field.fields[0].type == 'buffer' && !field.fields[0].concat
? $(`
`, encoding, `
$start += ${path}.reduce((sum, buffer) => sum + buffer.length, 0)
$start += $length
`) : $(`
`, encoding, `
Expand Down Expand Up @@ -343,6 +353,7 @@ function generate (packet, { require = null }) {
const declarations = {
register: '$start = 0',
i: '$i = []',
length: '$length',
starts: '$starts = []',
accumulator: '$accumulator = {}'
}
Expand Down
93 changes: 93 additions & 0 deletions test/cycle/array.t.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,97 @@ function prove (okay) {
sentry: 0xaa
}]
})
cycle(okay, {
name: 'array/conditional/chunked',
define: {
object: {
nudge: 8,
array: [[
[
value => value < 128, 8,
true, [ 16, 0x80, 7, 0x0, 7 ]
], [ 8,
sip => (sip & 0x80) == 0, 8,
true, [ 16, 0x80, 7, 0x0, 7 ]
]
], [[ Buffer ]]],
sentry: 8
}
},
objects: [{
nudge: 0xaa,
array: [ Buffer.from(array) ],
sentry: 0xaa
}, {
nudge: 0xaa,
array: [ Buffer.from([ 0x0, 0x1 ]) ],
sentry: 0xaa
}]
})
cycle(okay, {
name: 'array/switch/bytes',
define: {
object: {
type: 8,
array: [[ $ => $.type, [
{ $_: 0 }, 8,
{ $_: [] }, 16
]], [ 8 ]],
sentry: 8
}
},
objects: [{
type: 0,
array: [ 0x0, 0x1 ],
sentry: 0xaa
}, {
type: 1,
array: [ 0x0, 0x1 ],
sentry: 0xaa
}]
})
cycle(okay, {
name: 'array/switch/concat',
define: {
object: {
type: 8,
array: [[ $ => $.type, [
{ $_: 0 }, 8,
{ $_: [] }, 16
]], [ Buffer ]],
sentry: 8
}
},
objects: [{
type: 0,
array: Buffer.from([ 0x0, 0x1 ]),
sentry: 0xaa
}, {
type: 1,
array: Buffer.from([ 0x0, 0x1 ]),
sentry: 0xaa
}]
})
cycle(okay, {
name: 'array/switch/chunked',
define: {
object: {
type: 8,
array: [[ $ => $.type, [
{ $_: 0 }, 8,
{ $_: [] }, 16
]], [[ Buffer ]]],
sentry: 8
}
},
objects: [{
type: 0,
array: [ Buffer.from([ 0x0, 0x1 ]) ],
sentry: 0xaa
}, {
type: 1,
array: [ Buffer.from([ 0x0, 0x1 ]) ],
sentry: 0xaa
}]
})
}
6 changes: 4 additions & 2 deletions test/generated/array/chunked.sizeof.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
module.exports = {
object: function () {
return function (object) {
let $start = 0
let $start = 0, $length

$start += 1

$length = object.array.reduce((sum, buffer) => sum + buffer.length, 0)

$start += 1

$start += object.array.reduce((sum, buffer) => sum + buffer.length, 0)
$start += $length

$start += 1

Expand Down
1 change: 1 addition & 0 deletions test/generated/array/conditional/chunked.lookup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = []
38 changes: 38 additions & 0 deletions test/generated/array/conditional/chunked.parser.all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = function ({ $lookup }) {
return {
object: function () {
return function ($buffer, $start) {
let $i = [], $I = [], $sip = []

let object = {
nudge: 0,
array: [],
sentry: 0
}

object.nudge = $buffer[$start++]

$sip[0] = $buffer[$start++]

if ((sip => (sip & 0x80) == 0)($sip[0], object)) {
$start -= 1

$I[0] = $buffer[$start++]
} else {
$start -= 1

$I[0] =
($buffer[$start++] & 0x7f) << 7 |
$buffer[$start++]
}

object.array = [ $buffer.slice($start, $start + $I[0]) ]
$start += $I[0]

object.sentry = $buffer[$start++]

return object
}
} ()
}
}
60 changes: 60 additions & 0 deletions test/generated/array/conditional/chunked.parser.bff.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module.exports = function ({ $incremental, $lookup }) {
return {
object: function () {
return function () {
return function ($buffer, $start, $end) {
let $i = [], $I = [], $sip = []

let object = {
nudge: 0,
array: [],
sentry: 0
}

if ($end - $start < 1) {
return $incremental.object(object, 1, $i, $I, $sip)($buffer, $start, $end)
}

object.nudge = $buffer[$start++]

if ($end - $start < 1) {
return $incremental.object(object, 3, $i, $I, $sip)($buffer, $start, $end)
}

$sip[0] = $buffer[$start++]

if ((sip => (sip & 0x80) == 0)($sip[0], object)) {
if ($end - ($start - 1) < 1) {
return $incremental.object(object, 6, $i, $I, $sip)($buffer, $start - 1, $end)
}

$start -= 1

$I[0] = $buffer[$start++]
} else {
if ($end - ($start - 1) < 2) {
return $incremental.object(object, 8, $i, $I, $sip)($buffer, $start - 1, $end)
}

$start -= 1

$I[0] =
($buffer[$start++] & 0x7f) << 7 |
$buffer[$start++]
}

if ($end - $start < 1 + 1 * $I[0]) {
return $incremental.object(object, 11, $i, $I, $sip)($buffer, $start, $end)
}

object.array = [ $buffer.slice($start, $start + $I[0]) ]
$start += $I[0]

object.sentry = $buffer[$start++]

return { start: $start, object: object, parse: null }
}
} ()
}
}
}
64 changes: 64 additions & 0 deletions test/generated/array/conditional/chunked.parser.chk.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module.exports = function ({ $incremental, $lookup }) {
return {
object: function () {
return function () {
return function ($buffer, $start, $end) {
let $i = [], $I = [], $sip = []

let object = {
nudge: 0,
array: [],
sentry: 0
}

if ($end - $start < 1) {
return $incremental.object(object, 1, $i, $I, $sip)($buffer, $start, $end)
}

object.nudge = $buffer[$start++]

if ($end - $start < 1) {
return $incremental.object(object, 3, $i, $I, $sip)($buffer, $start, $end)
}

$sip[0] = $buffer[$start++]

if ((sip => (sip & 0x80) == 0)($sip[0], object)) {
if ($end - ($start - 1) < 1) {
return $incremental.object(object, 6, $i, $I, $sip)($buffer, $start - 1, $end)
}

$start -= 1

$I[0] = $buffer[$start++]
} else {
if ($end - ($start - 1) < 2) {
return $incremental.object(object, 8, $i, $I, $sip)($buffer, $start - 1, $end)
}

$start -= 1

$I[0] =
($buffer[$start++] & 0x7f) << 7 |
$buffer[$start++]
}

if ($end - $start < 1 * $I[0]) {
return $incremental.object(object, 11, $i, $I, $sip)($buffer, $start, $end)
}

object.array = [ $buffer.slice($start, $start + $I[0]) ]
$start += $I[0]

if ($end - $start < 1) {
return $incremental.object(object, 12, $i, $I, $sip)($buffer, $start, $end)
}

object.sentry = $buffer[$start++]

return { start: $start, object: object, parse: null }
}
} ()
}
}
}
Loading

0 comments on commit 4f27805

Please sign in to comment.