Asobo File Format Idioms - widberg/fmtk GitHub Wiki
This page contains various common structures found across many of the file formats. Be on the lookout for these. Consider this a quick reference.
struct PascalString {
std::uint32_t size;
char string[size];
};
Non-null terminated Pascal string.
struct PascalStringNULL {
std::uint32_t size;
char string[size - 1];
char null;
};
Null terminated Pascal string.
template<std::size_t size>
struct FixedStringNULL {
char string[size];
};
Null terminated fixed-size string buffer.
template<class T, class U = std::uint32_t>
struct PascalArray {
U size;
T data[size];
};
A Pascal array is any contiguous array of data prefixed by its length. This terminology is a generalization of the commonly used Pascal string which serves an identical function although limits itself to arrays of characters. By prefixing the array with its length the application reading the file may allocate sufficient space for the array before reading it from the file making it more efficient than scanning for a sentinel and seeking back to the beginning of the data after calculating the length of the array using the difference in file pointers from the beginning and end of the array.
template<class T, class U, class V>
struct AssociativeArray {
PascalArray<T> values;
PascalArray<U> indices;
PascalArray<V> associatedValues;
};
The indices
array contains information mapping values in values
to an associated value in associatedValues
this mapping may be 1-to-1 or many-to-1. The associated value for a value at index i
in values
is associatedValues[indices[i]]
. U
is usually either std::uint32_t
or std::uint8_t
depending on the anticipated size of the associatedValues
array.
template<class T, class U>
struct Pair {
T key;
U value;
};
template<class T, class U>
using Map = PascalArray<Pair<T, U>>;
T
is usually a crc32_t
. Sometimes it is a std::uint32_t
representing an index or unique ID of some kind. 1-to-1 map.
template<class T, class U = std::uint8_t>
struct Optional {
U isSome;
if (isSome != 0)
{
T data;
}
};
using crc32_t = std::uint32_t;
Same as a std::uint32_t with the semantic distinction that the value must be a valid object path hash or 0.