| 2086 | */ |
| 2087 | #define FIO_ERROR_FRAME_DECODING ((unsigned long long)(-2)) |
| 2088 | static unsigned long long |
| 2089 | FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput, |
| 2090 | const FIO_prefs_t* const prefs, |
| 2091 | const char* srcFileName, |
| 2092 | U64 alreadyDecoded) /* for multi-frames streams */ |
| 2093 | { |
| 2094 | U64 frameSize = 0; |
| 2095 | U32 storedSkips = 0; |
| 2096 | |
| 2097 | /* display last 20 characters only */ |
| 2098 | { size_t const srcFileLength = strlen(srcFileName); |
| 2099 | if (srcFileLength>20) srcFileName += srcFileLength-20; |
| 2100 | } |
| 2101 | |
| 2102 | ZSTD_resetDStream(ress->dctx); |
| 2103 | |
| 2104 | /* Header loading : ensures ZSTD_getFrameHeader() will succeed */ |
| 2105 | { size_t const toDecode = ZSTD_FRAMEHEADERSIZE_MAX; |
| 2106 | if (ress->srcBufferLoaded < toDecode) { |
| 2107 | size_t const toRead = toDecode - ress->srcBufferLoaded; |
| 2108 | void* const startPosition = (char*)ress->srcBuffer + ress->srcBufferLoaded; |
| 2109 | ress->srcBufferLoaded += fread(startPosition, 1, toRead, finput); |
| 2110 | } } |
| 2111 | |
| 2112 | /* Main decompression Loop */ |
| 2113 | while (1) { |
| 2114 | ZSTD_inBuffer inBuff = { ress->srcBuffer, ress->srcBufferLoaded, 0 }; |
| 2115 | ZSTD_outBuffer outBuff= { ress->dstBuffer, ress->dstBufferSize, 0 }; |
| 2116 | size_t const readSizeHint = ZSTD_decompressStream(ress->dctx, &outBuff, &inBuff); |
| 2117 | if (ZSTD_isError(readSizeHint)) { |
| 2118 | DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n", |
| 2119 | srcFileName, ZSTD_getErrorName(readSizeHint)); |
| 2120 | FIO_zstdErrorHelp(prefs, ress, readSizeHint, srcFileName); |
| 2121 | return FIO_ERROR_FRAME_DECODING; |
| 2122 | } |
| 2123 | |
| 2124 | /* Write block */ |
| 2125 | storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, prefs, storedSkips); |
| 2126 | frameSize += outBuff.pos; |
| 2127 | if (!fCtx->hasStdoutOutput) { |
| 2128 | if (fCtx->nbFilesTotal > 1) { |
| 2129 | size_t srcFileNameSize = strlen(srcFileName); |
| 2130 | if (srcFileNameSize > 18) { |
| 2131 | const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15; |
| 2132 | DISPLAYUPDATE(2, "\rDecompress: %2u/%2u files. Current: ...%s : %u MB... ", |
| 2133 | fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); |
| 2134 | } else { |
| 2135 | DISPLAYUPDATE(2, "\rDecompress: %2u/%2u files. Current: %s : %u MB... ", |
| 2136 | fCtx->currFileIdx+1, fCtx->nbFilesTotal, srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); |
| 2137 | } |
| 2138 | } else { |
| 2139 | DISPLAYUPDATE(2, "\r%-20.20s : %u MB... ", |
| 2140 | srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); |
| 2141 | } |
| 2142 | } |
| 2143 | |
| 2144 | if (inBuff.pos > 0) { |
| 2145 | memmove(ress->srcBuffer, (char*)ress->srcBuffer + inBuff.pos, inBuff.size - inBuff.pos); |
no test coverage detected