Jump to page content

Preferences file format


Skip to the specs if you don’t care about this bit

Unlike Windows and now Mac OS X, classic Mac OS has never provided any built-in means for managing settings files, so programmers are left to devise their own means of recording their settings on disc. Macintosh settings files (known as preferences files) are typically both resource-based and binary, so my best guess is that programs simply dump each internal settings struct into a resource.

When I came to find a method for my own software, I took an interesting route. One of the standard Macintosh resources (for which ResEdit provides a built-in editor) is a string table, or 'STR#'. This contains a string count byte followed by zero or more Pascal strings. This provides a limit of 255 strings of up to 255 bytes each. The strings are binary safe as they are not terminated. This seemed like a nice starting point. I decided to make use of two, to form a map. String table one would hold the map keys and string table two would hold the related values, matched by index within the tables.

After not too long, I realised that this design was inadequate, as I found a need for not only binary-safe storage but also for strings longer than 255 bytes. The main example of this being the Macintosh alias record, storage of which inside a program’s settings permits a program to track a recently accessed file even after it gets moved and renamed! I modified my code to upgrade to 16 bits: each string now had a 64 kilobyte limit and you could have 65,535 of them. This seemed a reasonable limit and has never posed a problem since. I originally wrote this data back into 'STR#' resources, but that made no sense as they were no longer Macintosh string tables. I thus changed the resource type to 'XST#', or eXtended String Table.



The format is a simple string map. A list of binary-safe string keys map to a list of binary-safe string values. The data is considered raw binary and as such no text encoding is expected or checked for.

String tables

The keys list and values list are each Extended [Macintosh] String Tables, and hold up to 65535 entries of 64 k each. The first two bytes indicate the number of strings. The strings follow directly, each one being composed of two length bytes followed by the string itself with no termination. All the 16-bit numbers are stored big-endian.

00: MSB of the string count
01: LSB of the string count
02: Length of first string (if it exists), MSB
03: Length of first string, LSB
04: Beginning of string
And so on

File storage

Storage of the two string tables is different in Windows compared to the Macintosh. On the Macintosh, the keys list string table is 'XST#' resource 128, and the values list string table is 'XST#' resource 128.

When I updated the code to run in Windows, the Windows version became a flat file. The first eight bytes are the lengths of the keys and values string tables as big-endian four-byte words. The two string tables follow directly on in the file, keys first and then values.

A little complicated, that’s why PrefEdit was written and then ported to Windows!