The header is twelve 32-bit numbers at the start of the file: seven in every file and, from minor revision 1, five more. Every number is in the byte order that the magic number shows. Offsets count from the start of the file.
Fields
| Offset | Size | Field | Meaning |
|---|---|---|---|
0x00 | 4 | magic | 0x950412de in the writer’s byte order: the bytes DE 12 04 95 or 95 04 12 DE. A reader that finds any other value stops. |
0x04 | 4 | revision | The major revision in the high 16 bits and the minor revision in the low 16 bits. |
0x08 | 4 | nstrings (N) | The number of pairs of an original and its translation. |
0x0C | 4 | orig_tab_offset (O) | The offset of the table of original strings. |
0x10 | 4 | trans_tab_offset (T) | The offset of the table of translations. |
0x14 | 4 | hash_tab_size (S) | The number of entries of the hash table. It may be 0, and then there is no table. |
0x18 | 4 | hash_tab_offset (H) | The offset of the first hash table entry. |
0x1C | 4 | n_sysdep_segments | Minor revision 1 and later: the number of system-dependent segments. |
0x20 | 4 | sysdep_segments_offset | Minor revision 1 and later: the offset of the table that describes them. |
0x24 | 4 | n_sysdep_strings | Minor revision 1 and later: the number of system-dependent string pairs. |
0x28 | 4 | orig_sysdep_tab_offset | Minor revision 1 and later: the offset of the table of original sysdep strings. |
0x2C | 4 | trans_sysdep_tab_offset | Minor revision 1 and later: the offset of the table of translated sysdep strings. |
The manual says that further pointer entries may follow offset 0x18, so that the
header can grow without breaking older readers, and that flag bits and an indication
of the character set are possible uses. Nothing read defines any such entry; the
fields of minor revision 1 are the ones the source defines after offset 0x18.
Revision
The revision is split into a major number, revision >> 16, and a minor
number, revision & 0xFFFF. The manual says that each is 0 or 1 for now, that
a reader that finds an unexpected major number stops, and that with an unexpected minor
number it may read the file but sees only what its own revision knows.
| Revision field | Major | Minor | Meaning |
|---|---|---|---|
0 | 0 | 0 | The 28-byte header and the tables above. No system-dependent strings. |
1 | 0 | 1 | The 48-byte header and the system-dependent strings of the sysdep page. This is what msgfmt 1.0 writes for a catalogue with a C format string that names a system-dependent integer type. |
0x10000 and 0x10001 | 1 | 0 or 1 | Major revision 1: the source names it for catalogues that use the system-dependent segment I, a flag character of the C library’s printf. The loader accepts it as it does major 0. |
The loader of gettext stops for any other major number. For the minor number, 0 means no system-dependent strings; any other value is handled as minor revision 1, which needs a hash table, so a loader that finds none stops.
The two string tables
Each table has N entries, 8 bytes each: a 32-bit length and a 32-bit offset of the string in the file.
| Offset in an entry | Size | Field |
|---|---|---|
| 0 | 4 | The length of the string in bytes, not counting the NUL that ends it. |
| 4 | 4 | The offset of the first byte of the string. |
- The original table starts at O and the translation table at T. Entry i of the second is the translation of entry i of the first.
- The originals are sorted in increasing byte order (
strcmpof the string, with the context and the0x04byte in front when there is one), so a reader can search them by halves. The header entry, whose original is empty, is first. - Every string is ended by a NUL byte that the length does not count. A plural entry’s length covers the NULs inside it.
msgfmtcan align each string to a multiple of a number of bytes (--alignment), which can speed up reading on some RISC machines; the offsets then leave gaps.
The loader of gettext does not check the offsets against the size of the file; a reader of untrusted files should.
Not described
Known, not yet covered
- Reference: whether any writer other than
msgfmtproduces major revision 1 files, and what the loader does differently for them; the loader’s source that was read does not tell.