The Problem With Offset Arrays
Posted by kelvSYC on 6-13-2014
The offset primitive type in Synalyze It! is meant to be a pointer. An offset field is basically an enhanced integer field, where the parsed integer, along with some context info (“Relative To”, “Additional”, and, of course, the referenced structure type), additionally renders a structure where the parsed integer refers to. This is fine and all, but the offset model breaks down in many ways, of which I will talk about one here.
Just like any other data type, you can assign a repeat count to an offset to create a fixed-size array. The problem is that the results tree simply doesn’t look right. There are two things at play:
- The referenced structures are inserted into the results tree after the rest of the structure is parsed. This is extremely inconvenient, as one would expect that the structure would be right next to where the integer wold lie.
- The referenced structure does not carry the array index of the offset array. This means that in an array of offsets, all of the structures would appear to have an array index of 0. Needless to say, finding the structure for a corresponding offset in your array is painful if the array is large.
Of course, a single script element can be used to actually solve both issues, and has the additional benefit of being able to compute the actual location with greater granularity than what the “Additional” field can provide (the tradeoff is that duplicating the “Relative to” field functionality by traversing the results tree is that much more difficult). The overall idea in your script element, which will render the entire array, is to, on each iteration, parse the integer (via StructureMapper::getCurrentByteView()) and add it to your results tree (StructureMapper::getCurrentResults()), and then subsequently map the structure based on the value of the integer (StructureMapper::mapStructureAtPosition()). Both Results::addElement() and StructureMapper::mapStructureAtPosition() take in the “iteration number”, which acts as the array index. There are a couple of downsides to this, however:
- It presumes that the structure is of fixed size. Unfortunately, mapStructureAtPosition() takes in a “maximum size”, which is equivalent to giving a structure a fixed size and assuming that any data that’s left after rendering the structure is padding.
- This is not reusable. You will have to duplicate this code (and make subtle tweaks for array size, offset location, etc.) every time you need it.
All in all, quite a bit of effort to attempt to re-render a tree just because you don’t like where the referenced structures are located in the results tree. More trouble than it’s worth, but it just seems like the way it is currently is a bug.