decompress and return a string */
| 77 | decompress and return a string |
| 78 | */ |
| 79 | const char *ROMFS::find_string(const char *name) |
| 80 | { |
| 81 | const auto *f = find(name); |
| 82 | if (!f) { |
| 83 | return nullptr; |
| 84 | } |
| 85 | |
| 86 | // last 4 bytes of gzip file are length of decompressed data |
| 87 | const uint8_t *p = &f->contents[f->size-4]; |
| 88 | uint32_t decompressed_size = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; |
| 89 | |
| 90 | uint8_t *decompressed_data = (uint8_t *)malloc(decompressed_size + 1); |
| 91 | if (!decompressed_data) { |
| 92 | return nullptr; |
| 93 | } |
| 94 | |
| 95 | // explicitly null terimnate the data |
| 96 | decompressed_data[decompressed_size] = 0; |
| 97 | |
| 98 | TINF_DATA *d = (TINF_DATA *)malloc(sizeof(TINF_DATA)); |
| 99 | if (!d) { |
| 100 | ::free(decompressed_data); |
| 101 | return nullptr; |
| 102 | } |
| 103 | uzlib_uncompress_init(d, NULL, 0); |
| 104 | |
| 105 | d->source = f->contents; |
| 106 | d->source_limit = f->contents + f->size - 4; |
| 107 | |
| 108 | // assume gzip format |
| 109 | int res = uzlib_gzip_parse_header(d); |
| 110 | if (res != TINF_OK) { |
| 111 | ::free(decompressed_data); |
| 112 | ::free(d); |
| 113 | return nullptr; |
| 114 | } |
| 115 | |
| 116 | d->dest = decompressed_data; |
| 117 | d->destSize = decompressed_size; |
| 118 | |
| 119 | // we don't check CRC, as it just wastes flash space for constant |
| 120 | // ROMFS data |
| 121 | res = uzlib_uncompress(d); |
| 122 | |
| 123 | ::free(d); |
| 124 | |
| 125 | if (res != TINF_OK) { |
| 126 | ::free(decompressed_data); |
| 127 | return nullptr; |
| 128 | } |
| 129 | |
| 130 | return (const char *)decompressed_data; |
| 131 | } |
nothing calls this directly
no test coverage detected