=== Index Block version 2 (`IDX2`)

The index block stores references to all blocks present in the file.
It is composed of a header, followed by a sequence of entries, the count of which is defined within the header.

Multiple index blocks may exist within a file to represent previous states or historical versions; however, only the final index block must be referenced by the main file header.

==== Structure Definition

[source,c]
#define INDEX2_MAGIC 0x32584449
/**Header for the index, followed by entries */
typedef struct IndexHeader2
{
    uint32_t identifier;  ///< Block identifier (must be BlockType::IndexBlock2).
    uint64_t entries;     ///< Number of \ref IndexEntry records that follow immediately.
    uint64_t crc64;  ///< CRC64-ECMA of the entries array (legacy byte-swapped rule still applies for old versions).
} IndexHeader2;

==== Field Descriptions

[cols="2,2,2,6",options="header"]
|===
|Type
|Size
|Name
|Description

|uint32_t
|4 bytes
|identifier
|The index block identifier, always `IDX2`

|uint64_t
|8 bytes
|entries
|The number of entries following this header

|uint64_t
|8 bytes
|crc64
|CRC64-ECMA checksum of the entries following this header
|===

==== Index entries

[source,c]
/**Index entry */
typedef struct IndexEntry
{
    uint32_t blockType;  ///< Block identifier of the referenced block (value from \ref BlockType).
    uint16_t dataType;   ///< Data classification (value from \ref DataType) or unused for untyped blocks.
    uint64_t offset;     ///< Absolute byte offset in the image where the referenced block header begins.
} IndexEntry;

==== Field Descriptions

[cols="2,2,2,6",options="header"]
|===
|Type
|Size
|Name
|Description

|uint32_t
|4 bytes
|blockType
|The type of block this entry points to.

|uint32_t
|2 bytes
|dataType
|The type of data the block pointed by this entry contains.

|uint64_t
|8 bytes
|offset
|The offset in bytes from the start of the file where the block pointed by this entry starts.
|===