| 706 | } |
| 707 | |
| 708 | bool path_read_compressed_binary(const string &path, vector<uint8_t> &binary) |
| 709 | { |
| 710 | if (!string_endswith(path, ".zst")) { |
| 711 | return path_read_binary(path, binary); |
| 712 | } |
| 713 | |
| 714 | vector<uint8_t> compressed; |
| 715 | if (!path_read_binary(path, compressed)) { |
| 716 | return false; |
| 717 | } |
| 718 | |
| 719 | const size_t full_size = ZSTD_getFrameContentSize(compressed.data(), compressed.size()); |
| 720 | |
| 721 | if (full_size == ZSTD_CONTENTSIZE_ERROR) { |
| 722 | /* Potentially corrupted file? */ |
| 723 | return false; |
| 724 | } |
| 725 | if (full_size == ZSTD_CONTENTSIZE_UNKNOWN) { |
| 726 | /* Technically this is an optional field, but we can expect it to be set for now. |
| 727 | * Otherwise we'd need streaming decompression and repeated resizing of the vector. */ |
| 728 | return false; |
| 729 | } |
| 730 | |
| 731 | binary.resize(full_size); |
| 732 | |
| 733 | const size_t err = ZSTD_decompress( |
| 734 | binary.data(), binary.size(), compressed.data(), compressed.size()); |
| 735 | |
| 736 | return ZSTD_isError(err) == 0; |
| 737 | } |
| 738 | |
| 739 | bool path_read_text(const string &path, string &text) |
| 740 | { |
no test coverage detected