MCPcopy Create free account
hub / github.com/OpenRCT2/OpenRCT2 / zstdDecompress

Function zstdDecompress

src/openrct2/core/Compression.cpp:224–275  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

222 }
223
224 bool zstdDecompress(IStream& source, uint64_t sourceLength, IStream& dest, uint64_t decompressLength)
225 {
226 if (sourceLength > source.GetLength() - source.GetPosition())
227 throw IOException("Not Enough Data to Decompress");
228
229 size_t ret;
230 StreamReadBuffer sourceBuf(source, sourceLength, ZSTD_DStreamInSize());
231 StreamWriteBuffer destBuf(dest, decompressLength, ZSTD_DStreamOutSize());
232
233 const auto deleter = [](ZSTD_DCtx* ptr) { ZSTD_freeDCtx(ptr); };
234 std::unique_ptr<ZSTD_DCtx, decltype(deleter)> ctx(ZSTD_createDCtx(), deleter);
235 if (ctx == nullptr)
236 {
237 LOG_ERROR("Failed to create zstd context");
238 return false;
239 }
240
241 do
242 {
243 auto readBlock = sourceBuf.ReadBlock(source);
244 ZSTD_inBuffer input = { readBlock.first, readBlock.second, 0 };
245
246 do
247 {
248 if (!destBuf)
249 {
250 LOG_ERROR("Decompressed data larger than expected");
251 return false;
252 }
253
254 auto writeBlock = destBuf.WriteBlockStart();
255 ZSTD_outBuffer output = { writeBlock.first, writeBlock.second, 0 };
256
257 ret = ZSTD_decompressStream(ctx.get(), &output, &input);
258 if (ZSTD_isError(ret))
259 {
260 LOG_ERROR("Failed to compress data with error: %s", ZSTD_getErrorName(ret));
261 return false;
262 }
263
264 destBuf.WriteBlockCommit(dest, output.pos);
265 } while (input.pos < input.size || (!sourceBuf && ret > 0));
266 } while (sourceBuf);
267
268 if (destBuf)
269 {
270 LOG_ERROR("Decompressed data smaller than expected");
271 return false;
272 }
273
274 return true;
275 }
276} // namespace OpenRCT2::Compression

Callers 2

DecompressFileMethod · 0.85
OrcaStreamMethod · 0.85

Calls 7

IOExceptionClass · 0.85
ReadBlockMethod · 0.80
WriteBlockStartMethod · 0.80
WriteBlockCommitMethod · 0.80
getMethod · 0.65
GetLengthMethod · 0.45
GetPositionMethod · 0.45

Tested by

no test coverage detected