diff --git a/NavmeshList/main.c b/NavmeshList/main.c index d754482..c9602b6 100644 --- a/NavmeshList/main.c +++ b/NavmeshList/main.c @@ -23,8 +23,8 @@ int main(void) { size_t read = fread(buffer, sizeof(char), size, fp); assert(read == size); - size_t decompressed = espr_decompressed_size(buffer, size); - printf("%llu -> %llu\n", size, decompressed); + size_t formids = espr_formid_count(buffer, size); + printf("FormID Count: %zu\n", formids); return 0; } diff --git a/espReader/ESPReader.h b/espReader/ESPReader.h index df4b336..17a1240 100644 --- a/espReader/ESPReader.h +++ b/espReader/ESPReader.h @@ -272,6 +272,11 @@ extern "C" { */ size_t espr_decompressed_size(char *data, size_t size); + /* Counts the number of formids present in the esp/esm data. This should be + * equal to the number of records. + */ + size_t espr_formid_count(char *data, size_t size); + // End C++ guard #ifdef __cplusplus } diff --git a/espReader/Reader.c b/espReader/Reader.c index 182c93f..36b00bb 100644 --- a/espReader/Reader.c +++ b/espReader/Reader.c @@ -44,6 +44,7 @@ void print_type4(Type4 val); Timestamp convert_ts(uint16_t ts); void print_callback(Node n, void *_); void dc_size_cb(Node n, void *dc_size_ptr); +void formid_count_cb(Node n, void *count_ptr); // // === FUNCTIONS === @@ -95,6 +96,7 @@ size_t espr_decompressed_size(char *data, size_t size) { return dc_size; } +// Adds the size of every node up, reading decompressed size from compressed records. void dc_size_cb(Node n, void *dc_size_ptr) { size_t *dcsp = dc_size_ptr; switch (n.type) { @@ -116,6 +118,23 @@ void dc_size_cb(Node n, void *dc_size_ptr) { } } +size_t espr_formid_count(char *data, size_t size) { + size_t count = 0; + espr_walk(data, size, formid_count_cb, &count); + return count; +} + +/* FormID <-> Record relationship should be bijective. I do not believe + * groups have formids, and every record should have a unique formid, + * otherwise there would be clashes in the id space. + */ +void formid_count_cb(Node n, void *count_ptr) { + size_t *c = count_ptr; + if (n.type == NT_RECORD) { + (*c)++; + } +} + /* Unknown data will be some concatenation of groups and records. * * `walk_concat` will call the appropriate walking function