Skip to content

Commit

Permalink
Writing an array of bytes.
Browse files Browse the repository at this point in the history
  • Loading branch information
bigeasy committed Sep 21, 2010
1 parent 4ea701b commit 535ee39
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 17 deletions.
56 changes: 40 additions & 16 deletions src/packet.coffee
Expand Up @@ -38,19 +38,24 @@ class Packet
@callback = null

# Setup the next field in the current pattern to read or write.
next: (value) ->
reading = not value?
next: ->
reading = not @outgoing
pattern = @pattern[@patternIndex]
little = pattern.endianness == 'l'
bytes = pattern.bytes

if pattern.unpacked
if reading
value = []
if @outgoing
if pattern.arrayed
value = @outgoing[@patternIndex][@index]
else
value = @outgoing[@patternIndex]
if pattern.unpacked
value = @pack(value)
else if reading
value = 0
else
if pattern.unpacked
value = []
else
value = 0

@value = value
@offset = if little then 0 else bytes - 1
Expand Down Expand Up @@ -178,8 +183,8 @@ module.exports.Parser = class Parser extends Packet
break if @offset is @terminal
return @bytesRead - start if offset is end

# Otherwise we're packing bytes into an unsigned integer, the most common
# case.
# Otherwise we're packing bytes into an unsigned integer, the most
# common case.
else
loop
b = buffer[offset]
Expand Down Expand Up @@ -215,7 +220,7 @@ module.exports.Parser = class Parser extends Packet
continue

# If we are reading an arrayed pattern and we have not read all of the
# array elements, we repeat the current field.
# array elements, we repeat the current field type.
if ++@index < @repeat
@next()

Expand Down Expand Up @@ -279,9 +284,10 @@ module.exports.Serializer = class Serializer extends Packet
@patternIndex = 0
@repeat = pattern[@patternIndex].repeat
@element = 0
@index = 0
@outgoing = shiftable

@next(shiftable[0])
@next()

##### serializer.write(buffer[, offset][, length])
# The `write` method writes to the buffer, returning when the current pattern is
Expand All @@ -295,27 +301,45 @@ module.exports.Serializer = class Serializer extends Packet
# We set the pattern to null when all the fields have been written, so while
# there is a pattern to fill and space to write.
while @pattern and offset < length
# If the pattern is unpacked, the value we're writing is an array.
if @pattern[@patternIndex].unpacked
loop
buffer[offset] = @value[@offset]
@offset += @increment
@bytesWritten++
offset++
break if @offset is @terminal
return true if offset is length
return if offset is length

# Otherwise we're unpacking bytes of an unsigned integer, the most common
# case.
else
loop
buffer[offset] = Math.floor(@value / Math.pow(256, @offset)) & 0xff
@offset += @increment
@bytesWritten++
offset++
break if @offset is @terminal
return true if offset is length
if ++@patternIndex is @pattern.length
return if offset is length

# If we are reading an arrayed pattern and we have not read all of the
# array elements, we repeat the current field type.
if ++@index < @repeat
@next()

# If we have written all of the packet fields, call the associated
# callback with this parser.
#
# The pattern is set to null, our terminal condition, before the callback,
# because the callback may specify a subsequent packet to parse.
else if ++@patternIndex is @pattern.length
@pattern = null
@callback.apply null, [ this ]

else
@next(@outgoing[@patternIndex])
true
@next()

@outgoing = null

module.exports.Structure = class Structure
constructor: (pattern) ->
Expand Down
18 changes: 17 additions & 1 deletion vows/packet-test.js
Expand Up @@ -111,7 +111,7 @@ vows.describe('Packet').addBatch({
readHexString([ 0xff, 0xff, 0xff, 0xff ], 'ffffffff');
readHexString([ 0xA0, 0xB0, 0xC0, 0xD0 ], 'a0b0c0d0');
},
'a 64 bit float': function (topic) {
'a big-endian 64 bit float': function (topic) {
function readSingleFloat(bytes, value) {
var invoked = false;
topic.reset();
Expand Down Expand Up @@ -230,6 +230,22 @@ vows.describe('Packet').addBatch({
}
writeDoubleFloat([ 0xdb, 0x01, 0x32, 0xcf, 0xf6, 0xee, 0xc1, 0xc0 ], -9.1819281981e3);
writeDoubleFloat([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xc0 ], -10);
},
'an array of 8 bytes': function (topic) {
var buffer = [];

var invoked = false;
var bytes = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]
topic.reset();
topic.serialize("n8[8]", bytes, function (engine) {
assert.equal(engine.getBytesWritten(), 8);
invoked = true;
});

topic.write(buffer, 0, 10);

assert.isTrue(invoked);
assert.deepEqual(buffer, bytes);
}
}
}).export(module);
Expand Down

0 comments on commit 535ee39

Please sign in to comment.