Flehsed out esp walker with callback interface. Implemented header printer using walker.

This commit is contained in:
2022-09-05 19:52:06 +10:00
parent 20d29ea721
commit ab921e5059
3 changed files with 127 additions and 105 deletions

View File

@@ -45,9 +45,9 @@ extern "C" {
typedef union type4 Type4;
typedef struct timestamp Timestamp;
typedef const struct group Group;
typedef const struct record Record;
typedef const struct field Field;
typedef struct group Group;
typedef struct record Record;
typedef struct field Field;
//
// === SIMPLE TYPES ===
@@ -73,7 +73,6 @@ extern "C" {
enum node_type { // NT_ prefix
NT_GROUP,
NT_RECORD,
NT_FIELD
};
// Record type enum
@@ -158,16 +157,15 @@ extern "C" {
//
// Generic node
typedef const struct node Node;
typedef struct node Node;
struct node {
const union {
Group *const group;
Record *const record;
Field *const field;
};
const char *const data;
const enum node_type type;
const uint32_t _pad;
union {
Group *group;
Record *record;
} header;
char *const data;
enum node_type type;
uint32_t _pad;
};
// calculated timestamp
@@ -185,36 +183,36 @@ extern "C" {
// Group header overlay
struct group {
const Type4 grup; // always RT_GRUP
const uint32_t size; // uncludes the 24 byte group header
const union {
const Type4 type; // this may be mangled and should not be relied on
const formid formid;
const int32_t number;
const int16_t coord[2];
Type4 grup; // always RT_GRUP
uint32_t size; // uncludes the 24 byte group header
union {
Type4 type; // this may be mangled and should not be relied on
formid formid;
int32_t number;
int16_t coord[2];
} label; // access determined by the `type` below
const int32_t type; // group_type enum
const uint16_t timestamp;
const uint16_t vcinfo;
const uint32_t unknown;
int32_t type; // group_type enum
uint16_t timestamp;
uint16_t vcinfo;
uint32_t unknown;
};
// Record header overlay
struct record {
const Type4 type;
const uint32_t size;
const uint32_t flags;
const uint32_t formid;
const uint16_t timestamp;
const uint16_t vcinfo;
const uint16_t version;
const uint16_t unknown;
Type4 type;
uint32_t size;
uint32_t flags;
uint32_t formid;
uint16_t timestamp;
uint16_t vcinfo;
uint16_t version;
uint16_t unknown;
};
// Field header overlay
struct field {
const Type4 type;
const uint16_t size;
Type4 type;
uint16_t size;
};
#pragma pack(pop)
@@ -253,10 +251,23 @@ extern "C" {
return uint32_t_msh(type, RT_HASH_BITS, RT_HASH_SEED);
}
// Walks the nodes of the esp/esm structured data at `data`
void walk(const char *data, size_t size);
/* `espr_walk` walks through the tree structure of the esp/esm binary data
* starting at `data` of `size` bytes.
*
* `cb` is a callback that takes a `Node` to process. `pt` is a pointer to
* arbitrary data that is passed on to `cb` whenever it is called.
*
* Data is walked sequentially. Nodes passed to `cb` will be strictly increasing
* in terms of memory location within the buffer.
*/
void espr_walk(char *data, size_t size, void (*cb)(Node n, void *pt), void *pt);
// End C++ guard
/* `espr_print` prints the header of every group and record in the given
* esp/esm binary data.
*/
void espr_print(char *data, size_t size);
// End C++ guard
#ifdef __cplusplus
}
#endif