FixedHash: Difference between revisions

From ZeldaMods (Link's Awakening)
Jump to navigation Jump to search
imported>Leoetlino
(→‎Format: alignment)
imported>Leoetlino
(→‎Entry: data size)
 
(3 intermediate revisions by the same user not shown)
Line 29: Line 29:
| 0x6 || u16 || Padding? {{check}}
| 0x6 || u16 || Padding? {{check}}
|-
|-
| 0x8 || u32[N + 1] || '''Offsets to the first entry in each bucket''' (relative to the Entries section)
| 0x8 || u32[N + 1] || '''Offsets to the first entry in each bucket''' (relative to the Entries section)<br>0xFFFFFFFF for empty buckets.
|-
|-
| X = (0x8 + 4*(N+1) + 3) & -8 || u64 || Entries section size
| X = (0x8 + 4*(N+1) + 3) & -8 || u64 || '''Entries section size'''
|-
|-
| X + 8 || Entry[...] || '''Entries'''
| X + 8 || Entry[...] || '''Entries'''
|-
|-
| Y = align(X + entries section size, 8) || u64 || Entry offsets section size
| Y = align(X + entries section size, 8) || u64 || '''Entry offsets section size'''
|-
|-
| Y + 8 || u32[...] || '''Entry offsets''' (relative to the Entries section)
| Y + 8 || u32[...] || '''Entry offsets''' (relative to the Entries section)
|-
|-
| Z = align(Y + entry offset section size, 8) || u64 || Data section size
| Z = align(Y + entry offset section size, 8) || u64 || '''Data section size'''
|-
|-
| Z + 8 || any || '''Data'''
| Z + 8 || any || '''Data'''
|-
|-
| A = align(Z + data section size, 4) || u32 || Name section size
| A = align(Z + data section size, 4) || u32 || '''Names section size'''
|-
|-
| A + 4 || C strings || '''Names'''
| A + 4 || C strings || '''Names'''
Line 49: Line 49:
|}
|}


=== Entry ===
{|class="wikitable"
! Offset !! Type !! Description
|-
| 0x0 || u16 || '''Node index''' if this describes a FixedHash child node (if so, it must be <= 0xFFED)
Otherwise, must be >= 0xFFF0 for non-node data.
|-
| 0x2 || u16 || '''Name offset''' (relative to the Name section)
|-
| 0x4 || u32 || '''Name hash'''
|-
| 0x8 || u32 || '''Next entry offset''' (relative to the Entries section) for hash table collision resolution.<br>0xFFFFFFFF if there is no other entry in the bucket.
|-
| 0xC || u32 || '''Data offset''' (relative to the Data section)
For non-node data, the data size is stored at offset+0 as a u64 and the actual data is at offset+8.
|-
|}
[[Category:File formats]]
[[Category:File formats]]

Latest revision as of 08:52, 18 April 2020

FixedHash
File format
Endianness little
Version 1
This article is about the file format in general. For actual values, check the game RomFS.

FixedHash is a custom Grezzo format for serializing hash tables that map string keys to arbitrary binary blobs.

Hash function

String keys are hashed using the following hash function:

u32 Hash(const char* key) {
  u32 hash = 0;
  while (*key) {
    hash ^= *key++ + (h >> 2) + (h << 5);
  }
  return hash;
}

Format

Offset Type Description
0x0 u8 Magic (must be 0x3D)
0x1 u8 Version (must be 1)
0x2 u16 Number of hash table buckets (N)
0x4 u16 Number of child FixedHash nodes
0x6 u16 Padding? [check]
0x8 u32[N + 1] Offsets to the first entry in each bucket (relative to the Entries section)
0xFFFFFFFF for empty buckets.
X = (0x8 + 4*(N+1) + 3) & -8 u64 Entries section size
X + 8 Entry[...] Entries
Y = align(X + entries section size, 8) u64 Entry offsets section size
Y + 8 u32[...] Entry offsets (relative to the Entries section)
Z = align(Y + entry offset section size, 8) u64 Data section size
Z + 8 any Data
A = align(Z + data section size, 4) u32 Names section size
A + 4 C strings Names

Entry

Offset Type Description
0x0 u16 Node index if this describes a FixedHash child node (if so, it must be <= 0xFFED)

Otherwise, must be >= 0xFFF0 for non-node data.

0x2 u16 Name offset (relative to the Name section)
0x4 u32 Name hash
0x8 u32 Next entry offset (relative to the Entries section) for hash table collision resolution.
0xFFFFFFFF if there is no other entry in the bucket.
0xC u32 Data offset (relative to the Data section)

For non-node data, the data size is stored at offset+0 as a u64 and the actual data is at offset+8.