Advanced Peach: Relative Offset Relationships

.!.
.!.

Welcome to the first advanced Peach article.  In this series I’ll be covering a number of more advanced Peach concepts, tips, and tricks.

Today we are going to talk about relative offset relationships.  It’s not uncommon to find file formats that contain offsets to other parts of the file.  Two examples of this are: OpenType font files (TTF), and ZIP files.  Both formats contain offsets to additional structures in the file.  In the case of TTF most of these offsets are relative to other portions of the file.  By default Peach relationships are relative to the start of the data stream, however it’s easy to change this for relative offsets.

Lets start out with a basic example that contains a Header, some Data in the body, and has an Index located at the very end of the file.  This is the most basic example, and as you would guess it looks something like the following:

<DataModel name="RelativeOffsets">
    <Block name="Header">
        <Number name="DataLength">
            <Relative type="size" of="Data" />
        </Number>

        <Number name="IndexOffset">
            <Relative type="offset" of="Index" />
        </Number>
    </Block>

    <Blob name="Data" />

    <Block name="Index">
        <Number name="CountOfStrings">
            <Relative type="count" of="Strings" />
        </Number>
        <String name="Strings" nullTerminated="true" minOccures="1" maxOccures="1024" />
    </Block>
</DataModel>

Now, the value of IndexOffset is going to be relative to the start of the data consumed or produced by this data model.  However what if the specification said that IndexOffset‘s value was relative to the position of IndexOffset?  In that case we would set the relative attribute to true like this:

<DataModel name=”RelativeOffsets”>
    <Block name=”Header”>
        <Number name=”DataLength”>
            <Relative type=”size” of=”Data” />
        </Number>
        <Number name=”IndexOffset”>
            <Relative type=”offset” of=”Index” relative=”true” />
        </Number>
    </Block>
    <Blob name=”Data” />
    <Block name=”Index”>
        <Number name=”CountOfStrings”>
            <Relative type=”count” of=”Strings” />
        </Number>
        <String name=”Strings” nullTerminated=”true” minOccures=”1″ maxOccures=”1024″ />
    </Block>
</DataModel>

Lets take it one set further and say we are instead relative to the end of Header.  In that case we could use the relativeTo attribute to specify which element, note however that we will not use Header but instead Data!  Why? Because the value specified in relativeTo will be relative to the beginning of that element, not the end.

<DataModel name=”RelativeOffsets”>
    <Block name=”Header”>
        <Number name=”DataLength”>
            <Relative type=”size” of=”Data” />
        </Number>
        <Number name=”IndexOffset”>
            <Relative type=”offset” of=”Index” relative=”true” relativeTo=”Data” />
        </Number>
    </Block>
    <Blob name=”Data” />
    <Block name=”Index”>
        <Number name=”CountOfStrings”>
            <Relative type=”count” of=”Strings” />
        </Number>
        <String name=”Strings” nullTerminated=”true” minOccures=”1″ maxOccures=”1024″ />
    </Block>
</DataModel>

Hey, that wasn’t so hard!!

~ by meddington on January 30, 1999.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.