You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
8.2 KiB
CoffeeScript
278 lines
8.2 KiB
CoffeeScript
7 years ago
|
{Pointer, VoidPointer, uint8, DecodeStream, EncodeStream, Struct} = require '../'
|
||
|
should = require('chai').should()
|
||
|
concat = require 'concat-stream'
|
||
|
|
||
|
describe 'Pointer', ->
|
||
|
describe 'decode', ->
|
||
|
it 'should handle null pointers', ->
|
||
|
stream = new DecodeStream new Buffer [0]
|
||
|
pointer = new Pointer uint8, uint8
|
||
|
should.not.exist pointer.decode(stream, _startOffset: 50)
|
||
|
|
||
|
it 'should use local offsets from start of parent by default', ->
|
||
|
stream = new DecodeStream new Buffer [1, 53]
|
||
|
pointer = new Pointer uint8, uint8
|
||
|
pointer.decode(stream, _startOffset: 0).should.equal 53
|
||
|
|
||
|
it 'should support immediate offsets', ->
|
||
|
stream = new DecodeStream new Buffer [1, 53]
|
||
|
pointer = new Pointer uint8, uint8, type: 'immediate'
|
||
|
pointer.decode(stream).should.equal 53
|
||
|
|
||
|
it 'should support offsets relative to the parent', ->
|
||
|
stream = new DecodeStream new Buffer [0, 0, 1, 53]
|
||
|
stream.pos = 2
|
||
|
pointer = new Pointer uint8, uint8, type: 'parent'
|
||
|
pointer.decode(stream, parent: _startOffset: 2).should.equal 53
|
||
|
|
||
|
it 'should support global offsets', ->
|
||
|
stream = new DecodeStream new Buffer [1, 2, 4, 0, 0, 0, 53]
|
||
|
pointer = new Pointer uint8, uint8, type: 'global'
|
||
|
stream.pos = 2
|
||
|
pointer.decode(stream, parent: parent: _startOffset: 2).should.equal 53
|
||
|
|
||
|
it 'should support offsets relative to a property on the parent', ->
|
||
|
stream = new DecodeStream new Buffer [1, 0, 0, 0, 0, 53]
|
||
|
pointer = new Pointer uint8, uint8, relativeTo: 'parent.ptr'
|
||
|
pointer.decode(stream, _startOffset: 0, parent: ptr: 4).should.equal 53
|
||
|
|
||
|
it 'should support returning pointer if there is no decode type', ->
|
||
|
stream = new DecodeStream new Buffer [4]
|
||
|
pointer = new Pointer uint8, 'void'
|
||
|
pointer.decode(stream, _startOffset: 0).should.equal 4
|
||
|
|
||
|
it 'should support decoding pointers lazily', ->
|
||
|
stream = new DecodeStream new Buffer [1, 53]
|
||
|
struct = new Struct
|
||
|
ptr: new Pointer uint8, uint8, lazy: yes
|
||
|
|
||
|
res = struct.decode(stream)
|
||
|
Object.getOwnPropertyDescriptor(res, 'ptr').get.should.be.a('function')
|
||
|
Object.getOwnPropertyDescriptor(res, 'ptr').enumerable.should.equal(true)
|
||
|
res.ptr.should.equal 53
|
||
|
|
||
|
describe 'size', ->
|
||
|
it 'should add to local pointerSize', ->
|
||
|
pointer = new Pointer uint8, uint8
|
||
|
ctx = pointerSize: 0
|
||
|
pointer.size(10, ctx).should.equal 1
|
||
|
ctx.pointerSize.should.equal 1
|
||
|
|
||
|
it 'should add to immediate pointerSize', ->
|
||
|
pointer = new Pointer uint8, uint8, type: 'immediate'
|
||
|
ctx = pointerSize: 0
|
||
|
pointer.size(10, ctx).should.equal 1
|
||
|
ctx.pointerSize.should.equal 1
|
||
|
|
||
|
it 'should add to parent pointerSize', ->
|
||
|
pointer = new Pointer uint8, uint8, type: 'parent'
|
||
|
ctx = parent: pointerSize: 0
|
||
|
pointer.size(10, ctx).should.equal 1
|
||
|
ctx.parent.pointerSize.should.equal 1
|
||
|
|
||
|
it 'should add to global pointerSize', ->
|
||
|
pointer = new Pointer uint8, uint8, type: 'global'
|
||
|
ctx = parent: parent: parent: pointerSize: 0
|
||
|
pointer.size(10, ctx).should.equal 1
|
||
|
ctx.parent.parent.parent.pointerSize.should.equal 1
|
||
|
|
||
|
it 'should handle void pointers', ->
|
||
|
pointer = new Pointer uint8, 'void'
|
||
|
ctx = pointerSize: 0
|
||
|
pointer.size(new VoidPointer(uint8, 50), ctx).should.equal 1
|
||
|
ctx.pointerSize.should.equal 1
|
||
|
|
||
|
it 'should throw if no type and not a void pointer', ->
|
||
|
pointer = new Pointer uint8, 'void'
|
||
|
ctx = pointerSize: 0
|
||
|
should.throw ->
|
||
|
pointer.size(30, ctx).should.equal 1
|
||
|
|
||
|
it 'should return a fixed size without a value', ->
|
||
|
pointer = new Pointer uint8, uint8
|
||
|
pointer.size().should.equal 1
|
||
|
|
||
|
describe 'encode', ->
|
||
|
it 'should handle null pointers', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [0]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 0,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, null, ctx)
|
||
|
ctx.pointerSize.should.equal 0
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should handle local offsets', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [1]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 1,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, 10, ctx)
|
||
|
ctx.pointerOffset.should.equal 2
|
||
|
ctx.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 10, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should handle immediate offsets', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [0]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8, type: 'immediate'
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 1,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, 10, ctx)
|
||
|
ctx.pointerOffset.should.equal 2
|
||
|
ctx.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 10, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should handle immediate offsets', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [0]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8, type: 'immediate'
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 1,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, 10, ctx)
|
||
|
ctx.pointerOffset.should.equal 2
|
||
|
ctx.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 10, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should handle offsets relative to parent', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [2]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8, type: 'parent'
|
||
|
ctx =
|
||
|
parent:
|
||
|
pointerSize: 0,
|
||
|
startOffset: 3,
|
||
|
pointerOffset: 5,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, 10, ctx)
|
||
|
ctx.parent.pointerOffset.should.equal 6
|
||
|
ctx.parent.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 10, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should handle global offsets', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [5]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8, type: 'global'
|
||
|
ctx =
|
||
|
parent:
|
||
|
parent:
|
||
|
parent:
|
||
|
pointerSize: 0,
|
||
|
startOffset: 3,
|
||
|
pointerOffset: 5,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, 10, ctx)
|
||
|
ctx.parent.parent.parent.pointerOffset.should.equal 6
|
||
|
ctx.parent.parent.parent.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 10, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should support offsets relative to a property on the parent', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [6]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, uint8, relativeTo: 'ptr'
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 10,
|
||
|
pointers: []
|
||
|
val:
|
||
|
ptr: 4
|
||
|
|
||
|
ptr.encode(stream, 10, ctx)
|
||
|
ctx.pointerOffset.should.equal 11
|
||
|
ctx.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 10, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should support void pointers', (done) ->
|
||
|
stream = new EncodeStream
|
||
|
stream.pipe concat (buf) ->
|
||
|
buf.should.deep.equal new Buffer [1]
|
||
|
done()
|
||
|
|
||
|
ptr = new Pointer uint8, 'void'
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 1,
|
||
|
pointers: []
|
||
|
|
||
|
ptr.encode(stream, new VoidPointer(uint8, 55), ctx)
|
||
|
ctx.pointerOffset.should.equal 2
|
||
|
ctx.pointers.should.deep.equal [
|
||
|
{ type: uint8, val: 55, parent: ctx }
|
||
|
]
|
||
|
|
||
|
stream.end()
|
||
|
|
||
|
it 'should throw if not a void pointer instance', ->
|
||
|
stream = new EncodeStream
|
||
|
ptr = new Pointer uint8, 'void'
|
||
|
ctx =
|
||
|
pointerSize: 0,
|
||
|
startOffset: 0,
|
||
|
pointerOffset: 1,
|
||
|
pointers: []
|
||
|
|
||
|
should.throw ->
|
||
|
ptr.encode(stream, 44, ctx)
|