Mapping a variable length value in an offset

0 votes
asked Sep 17, 2016 in Grammars by dmaclach (160 points)

So I have a grammar that has a root level object in it with an offset.

The offset refers to a structure of type "Values" that contains 

a: custom value (a varint from an earlier question)
b: a number
c: a script

The script takes the number as an enumeration for figuring out what the rest of foo is:

function numberfunc(element, byteView, offset, results, length)
  number = byteView:readUnsignedInt(offset, length, synalysis.ENDIAN_LITTLE)  
  value = synalysis.Value()
  value:setName("Value")
  value:setUnsigned(number)
  results:addElement(element, length, 1, value)
end

function floatingfunc(element, byteView, offset, results, length)
  number = byteView:readUnsignedIntBits(offset * 8, length * 8, synalysis.ENDIAN_LITTLE)  
  value = synalysis.Value()
  value:setFloat(number)
  -- add element with value to results
  results:addElement(element, length, 1, value)
end

function int8func(element, byteView, offset, results)
  numberfunc(element, byteView, offset, results, 1)
end

function int16func(element, byteView, offset, results)
  numberfunc(element, byteView, offset, results, 2)
end

function int32func(element, byteView, offset, results)
  numberfunc(element, byteView, offset, results, 4)
end

function int64func(element, byteView, offset, results)
  numberfunc(element, byteView, offset, results, 8)
end

function truefunc(element, byteView, offset, results)
  value = synalysis.Value()
  value:setString("true")
  results:addElement(element, 0, 0, value)
end

function falsefunc(element, byteView, offset, results)
  value = synalysis.Value()
  value:setString("false")
  results:addElement(element, 0, 0, value)
end

function floatfunc(element, byteView, offset, results)
  floatingfunc(element, byteView, offset, results, 4)
end

function doublefunc(element, byteView, offset, results)
  floatingfunc(element, byteView, offset, results, 8)
end

function datafunc(element, byteView, offset, results)
end

function nilfunc(element, byteView, offset, results)
end

function objectfunc(element, byteView, offset, results)
  number = byteView:readUnsignedInt(offset, 4, synalysis.ENDIAN_LITTLE)  
  value = synalysis.Value()
  value:setUnsigned(number)
  value:setName("ObjectIndex")
  element:setLength(4, synalysis.LENGTH_UNIT_BYTES)
  results:addElement(element, 4, 1, value)
end

-- get collection with results so far
results = currentMapper:getCurrentResults()
-- get latest added result
lastResult = results:getLastResult()
-- access the parsed value
value = lastResult:getValue()
-- get the value parsed
num = value:getUnsignedNumber()

local funcs = {
int8func,
int16func,
int32func,
int64func,
truefunc,
falsefunc,
floatfunc,
doublefunc,
datafunc,
nilfunc,
objectfunc
}

element = currentMapper:getCurrentStructureElement()
byteView = currentMapper:getCurrentByteView()
offset = currentMapper:getCurrentOffset()

funcs[num + 1](element, byteView, offset, results)

datafunc and nilfunc aren't implemented yet (and please excuse my Lua, I'm just learning).

Anyways, once I parse my file the values being read in by my script don't appear to be being added to my offsets.

I would expect Values[1] to be being read in from offset 2031 instead of 2027. What am I missing? I've tried setting the currentOffset amongst other things with no luck.

1 Answer

0 votes
answered Sep 23, 2016 by andreas (1,480 points)

Here also the GZIP grammar could serve as an example. If you call the parser ("structure mapper") to process the elements instead of adding them to the results tree, the current offset is advanced:

currentMapper.mapElementWithSize(element, 4)

...