-
Notifications
You must be signed in to change notification settings - Fork 4
format
All pointless files start with the header, followed by offset vectors, and finally the heap.
== Header ==
The header comes at the beginning of all pointless files.
{{{ typedef struct { pointless_value_t root; uint32_t n_unicode; uint32_t n_vector; uint32_t n_bitvector; uint32_t n_set; uint32_t n_map; uint32_t padding; } pointless_header_t; }}}
== Offset vectors ==
There is one offset vector for each datatype. The are stored, one after the other, right after the header. Each item is a relative pointer into the heap, where the actual data is stored.
== Value container/reference ==
All generic containers (maps, sets and uncompressed vectors), store multiple pointless_value_t structs. They contain a type field, and (depending of the type) an actual value, or an indice in one of the offset vectors (if the value is too large for 4 bytes).
Values stored completely in a pointless_value_t are referred to as inline values, and other are referred to as heap values.
{{{ typedef struct { uint32_t type; pointless_value_data_t data; } pointless_value_t;
typedef union { int32_t data_i32; uint32_t data_u32; float data_f;
struct {
unsigned int n_bits:5;
unsigned int bits:27;
} bitvector_packed;
struct {
uint16_t n_bits_a;
uint16_t n_bits_b;
} bitvector_01_or_10;
} pointless_value_data_t; }}}
== Inline values ==
Inline values are stored completely inside pointless_value_t. They include:
- 32-bit signed integer
- 32-bit unsigned integers
- 32-bit floating point numbers
- bitvectors if length 32 or less
- bitvectors containing only 0 or 1
- bitvectors containing 216 0/1's followed by 232 1/0's
- empty vectors
- boolean values
- null values
== Heap values ==
Heap values are stored on the heap, and are referenced through the offset vectors, which are in turn referenced by pointless_value_t structs. Each heap value has a header, possibly followed by variable length data.
=== Sets ===
{{{ typedef struct { uint32_t n_items; uint32_t padding; pointless_value_t hash_vector; pointless_value_t key_vector; } pointless_set_header_t; }}}
hash_vector must be a u32 vector. The key_vector can be a vector of any type, but must be equal in length to hash_vector. n_items must be less or equal to the length of the vectors.
=== Maps ===
Similar to sets, but there is an extra value vector, which may be of any type.
{{{ typedef struct { uint32_t n_items; uint32_t padding; pointless_value_t hash_vector; pointless_value_t key_vector; pointless_value_t value_vector; } pointless_map_header_t; }}}
=== Unicode ===
Unicode strings are stored in UCS4, i.e. an array of 32-bit unsigned integers, with the last item being 0.
The header is simple a 32-bit unsigned integer, being the length of the string following it (not including the terminating 0).
=== Value vectors ===
Value vectors store an array of pointless_value_t, preceded by a 32-bit unsigned integer being the length of the array.
=== Compressed vectors ===
There are 7 types of compressed vectors. They are similar to value vectors except that the array stores native types, which must all be the same.
- (un-)signed (8/16/32)-bit integers
- 32-bit floating point values
== Things to fix ==
- there is no magic number in the header
- there is no file checksum stored in the header
- data is not endian-safe
- files can't be larger than 2GB.
- floating point numbers are not architecture-safe