This just loads the directory part of a pakfile such that subsequent LoadFile calls know how to load from it.
| 289 | // This just loads the directory part of a pakfile such that subsequent LoadFile calls know how |
| 290 | // to load from it. |
| 291 | bool LoadPakDir(const char *lpak, uint64_t &src_hash_dest) { |
| 292 | // This supports reading from a pakfile > 4GB even on a 32bit system! (as long as individual |
| 293 | // files in it are <= 4GB). |
| 294 | auto plen = LoadFile(lpak, nullptr, 0, 0); |
| 295 | if (plen < 0) return false; |
| 296 | string header; |
| 297 | if (LoadFile(lpak, &header, plen - (int64_t)header_size, header_size) < 0 || |
| 298 | memcmp(header.c_str() + header_size - magic_size, magic, magic_size)) return false; |
| 299 | auto read_unaligned64 = [](const void *p) { |
| 300 | int64_t r; |
| 301 | memcpy(&r, p, sizeof(int64_t)); |
| 302 | return LE(r); |
| 303 | }; |
| 304 | auto src_hash = (uint64_t)read_unaligned64((int64_t *)header.c_str()); |
| 305 | auto num = read_unaligned64((int64_t *)header.c_str() + 1); |
| 306 | auto dirstart = read_unaligned64((int64_t *)header.c_str() + 2); |
| 307 | auto version = read_unaligned64((int64_t *)header.c_str() + 3); |
| 308 | if (version != current_version) return false; |
| 309 | if (dirstart > plen) return false; |
| 310 | string dir; |
| 311 | if (LoadFile(lpak, &dir, dirstart, plen - dirstart - (int64_t)header_size) < 0) |
| 312 | return false; |
| 313 | auto namestarts = (int64_t *)(dir.c_str() + dir.length()) - num; |
| 314 | auto filestarts = namestarts - num; |
| 315 | auto uncompressed = filestarts - num; |
| 316 | for (int64_t i = 0; i < num; i++) { |
| 317 | auto name = string_view(dir.c_str() + (read_unaligned64(namestarts + i) - dirstart)); |
| 318 | auto off = read_unaligned64(filestarts + i); |
| 319 | auto end = i < num + 1 ? read_unaligned64(filestarts + i + 1) : dirstart; |
| 320 | auto len = end - off; |
| 321 | LOG_INFO("pakfile dir: ", name, " : ", len); |
| 322 | AddPakFileEntry(lpak, name, off, len, read_unaligned64(uncompressed + i)); |
| 323 | } |
| 324 | src_hash_dest = src_hash; |
| 325 | return true; |
| 326 | } |
| 327 | |
| 328 | bool LoadMetaDataAndCode(string &metadata, string &c_codegen) { |
| 329 | if (LoadFile(mdname, &metadata) < 0) return false; |