* Do an in-memory xunzip operation. This works on a .xz or (legacy) * .lzma file. * @param input Buffer containing the input data. * @return Decompressed buffer. * * When decompressing fails, an empty buffer is returned. */
| 817 | * When decompressing fails, an empty buffer is returned. |
| 818 | */ |
| 819 | static std::vector<char> Xunzip(std::span<char> input) |
| 820 | { |
| 821 | static const int BLOCKSIZE = 8192; |
| 822 | std::vector<char> output; |
| 823 | |
| 824 | lzma_stream z = LZMA_STREAM_INIT; |
| 825 | z.next_in = reinterpret_cast<uint8_t *>(input.data()); |
| 826 | z.avail_in = input.size(); |
| 827 | |
| 828 | int res = lzma_auto_decoder(&z, UINT64_MAX, LZMA_CONCATENATED); |
| 829 | /* Z_BUF_ERROR just means we need more space */ |
| 830 | while (res == LZMA_OK || (res == LZMA_BUF_ERROR && z.avail_out == 0)) { |
| 831 | /* When we get here, we're either just starting, or |
| 832 | * inflate is out of output space - allocate more */ |
| 833 | z.avail_out += BLOCKSIZE; |
| 834 | output.resize(output.size() + BLOCKSIZE); |
| 835 | z.next_out = reinterpret_cast<uint8_t *>(output.data() + output.size() - z.avail_out); |
| 836 | res = lzma_code(&z, LZMA_FINISH); |
| 837 | } |
| 838 | |
| 839 | lzma_end(&z); |
| 840 | if (res != LZMA_STREAM_END) return {}; |
| 841 | |
| 842 | output.resize(output.size() - z.avail_out); |
| 843 | return output; |
| 844 | } |
| 845 | #endif |
| 846 | |
| 847 |
no test coverage detected