| 2445 | } |
| 2446 | |
| 2447 | size_t Read(uint8_t *buf, size_t ssize) override |
| 2448 | { |
| 2449 | assert(ssize >= LZO_BUFFER_SIZE); |
| 2450 | |
| 2451 | /* Buffer size is from the LZO docs plus the chunk header size. */ |
| 2452 | uint8_t out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32_t) * 2]; |
| 2453 | uint32_t tmp[2]; |
| 2454 | uint32_t size; |
| 2455 | lzo_uint len = ssize; |
| 2456 | |
| 2457 | /* Read header*/ |
| 2458 | if (this->chain->Read((uint8_t*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed"); |
| 2459 | |
| 2460 | /* Check if size is bad */ |
| 2461 | ((uint32_t*)out)[0] = size = tmp[1]; |
| 2462 | |
| 2463 | if (_sl_version != SL_MIN_VERSION) { |
| 2464 | tmp[0] = TO_BE32(tmp[0]); |
| 2465 | size = TO_BE32(size); |
| 2466 | } |
| 2467 | |
| 2468 | if (size >= sizeof(out)) SlErrorCorrupt("Inconsistent size"); |
| 2469 | |
| 2470 | /* Read block */ |
| 2471 | if (this->chain->Read(out + sizeof(uint32_t), size) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); |
| 2472 | |
| 2473 | /* Verify checksum */ |
| 2474 | if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32_t))) SlErrorCorrupt("Bad checksum"); |
| 2475 | |
| 2476 | /* Decompress */ |
| 2477 | int ret = lzo1x_decompress_safe(out + sizeof(uint32_t) * 1, size, buf, &len, nullptr); |
| 2478 | if (ret != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); |
| 2479 | return len; |
| 2480 | } |
| 2481 | }; |
| 2482 | |
| 2483 | /** Filter using LZO compression. */ |
nothing calls this directly
no test coverage detected