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

Function zstdCompress

src/openrct2/core/Compression.cpp:153–222  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

151 }
152
153 bool zstdCompress(IStream& source, uint64_t sourceLength, IStream& dest, ZstdMetadata metadata, int16_t level)
154 {
155 if (sourceLength > source.GetLength() - source.GetPosition())
156 throw IOException("Not Enough Data to Compress");
157
158 StreamReadBuffer sourceBuf(source, sourceLength, ZSTD_CStreamInSize());
159 StreamWriteBuffer destBuf(dest, zstdCompressBound(sourceLength), ZSTD_CStreamOutSize());
160 unsigned metaFlags = static_cast<unsigned>(metadata);
161
162 const auto deleter = [](ZSTD_CCtx* ptr) { ZSTD_freeCCtx(ptr); };
163 std::unique_ptr<ZSTD_CCtx, decltype(deleter)> ctx(ZSTD_createCCtx(), deleter);
164 if (ctx == nullptr)
165 {
166 LOG_ERROR("Failed to create zstd context");
167 return false;
168 }
169
170 size_t ret = ZSTD_CCtx_setParameter(ctx.get(), ZSTD_c_compressionLevel, level);
171 if (ZSTD_isError(ret))
172 {
173 LOG_ERROR("Failed to set compression level with error: %s", ZSTD_getErrorName(ret));
174 return false;
175 }
176 // set options for content size (default on) and checksum (default off)
177 ret = ZSTD_CCtx_setParameter(ctx.get(), ZSTD_c_contentSizeFlag, (metaFlags & 1) != 0);
178 if (ZSTD_isError(ret))
179 {
180 LOG_ERROR("Failed to set content size flag with error: %s", ZSTD_getErrorName(ret));
181 return false;
182 }
183 ret = ZSTD_CCtx_setParameter(ctx.get(), ZSTD_c_checksumFlag, (metaFlags & 2) != 0);
184 if (ZSTD_isError(ret))
185 {
186 LOG_ERROR("Failed to set checksum flag with error: %s", ZSTD_getErrorName(ret));
187 return false;
188 }
189 // unlike gzip, zstd puts the decompressed content size at the start of the file,
190 // so we need to tell zstd how big the input is before we start compressing.
191 ret = ZSTD_CCtx_setPledgedSrcSize(ctx.get(), sourceLength);
192 if (ZSTD_isError(ret))
193 {
194 LOG_ERROR("Failed to set file length with error: %s", ZSTD_getErrorName(ret));
195 return false;
196 }
197
198 do
199 {
200 auto readBlock = sourceBuf.ReadBlock(source);
201 ZSTD_inBuffer input = { readBlock.first, readBlock.second, 0 };
202
203 do
204 {
205 Guard::Assert(destBuf, "Compression Overruns Ouput Size");
206
207 auto writeBlock = destBuf.WriteBlockStart();
208 ZSTD_outBuffer output = { writeBlock.first, writeBlock.second, 0 };
209
210 ret = ZSTD_compressStream2(ctx.get(), &output, &input, sourceBuf ? ZSTD_e_continue : ZSTD_e_end);

Callers 2

StopRecordingMethod · 0.85
~OrcaStreamMethod · 0.85

Calls 9

IOExceptionClass · 0.85
zstdCompressBoundFunction · 0.85
AssertFunction · 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