From d7bfcac18a098769917d57c5f52fe8798d2ce35f Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Fri, 10 Feb 2017 11:38:57 -0800 Subject: [PATCH] Expose frameSrcSize to experimental API --- lib/decompress/zstd_decompress.c | 102 +++++++++++++++---------------- lib/legacy/zstd_legacy.h | 16 ++--- lib/legacy/zstd_v01.c | 2 +- lib/legacy/zstd_v01.h | 2 +- lib/legacy/zstd_v02.c | 6 +- lib/legacy/zstd_v02.h | 2 +- lib/legacy/zstd_v03.c | 6 +- lib/legacy/zstd_v03.h | 2 +- lib/legacy/zstd_v04.c | 6 +- lib/legacy/zstd_v04.h | 2 +- lib/legacy/zstd_v05.c | 2 +- lib/legacy/zstd_v05.h | 2 +- lib/legacy/zstd_v06.c | 2 +- lib/legacy/zstd_v06.h | 2 +- lib/legacy/zstd_v07.c | 2 +- lib/legacy/zstd_v07.h | 2 +- lib/zstd.h | 11 ++++ 17 files changed, 89 insertions(+), 80 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 18ee070c..b8670315 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -306,8 +306,6 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t return 0; } -static size_t ZSTD_frameSrcSize(const void* src, size_t srcSize); - /** ZSTD_getFrameContentSize() : * compatible with legacy mode * @return : decompressed size of the single frame pointed to be `src` if known, otherwise @@ -371,17 +369,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) totalDstSize += ret; } { - size_t frameSrcSize; -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) - if (ZSTD_isLegacy(src, srcSize)) - { - frameSrcSize = ZSTD_frameSrcSizeLegacy(src, srcSize); - } - else -#endif - { - frameSrcSize = ZSTD_frameSrcSize(src, srcSize); - } + size_t const frameSrcSize = ZSTD_getFrameCompressedSize(src, srcSize); if (ZSTD_isError(frameSrcSize)) { return ZSTD_CONTENTSIZE_ERROR; } @@ -1449,47 +1437,57 @@ size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t len return length; } -static size_t ZSTD_frameSrcSize(const void *src, size_t srcSize) +/** ZSTD_getFrameCompressedSize() : + * compatible with legacy mode + * `src` must point to the start of a ZSTD or ZSTD legacy frame + * `srcSize` must be at least as large as the frame contained + * @return : the compressed size of the frame starting at `src` */ +size_t ZSTD_getFrameCompressedSize(const void *src, size_t srcSize) { - const BYTE* ip = (const BYTE*)src; - const BYTE* const ipstart = ip; - size_t remainingSize = srcSize; - ZSTD_frameParams fParams; - - size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize); - if (ZSTD_isError(headerSize)) return headerSize; - - /* Frame Header */ +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) + if (ZSTD_isLegacy(src, srcSize)) return ZSTD_getFrameCompressedSizeLegacy(src, srcSize); +#endif { - size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize); - if (ZSTD_isError(ret)) return ret; - if (ret > 0) return ERROR(srcSize_wrong); + const BYTE* ip = (const BYTE*)src; + const BYTE* const ipstart = ip; + size_t remainingSize = srcSize; + ZSTD_frameParams fParams; + + size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize); + if (ZSTD_isError(headerSize)) return headerSize; + + /* Frame Header */ + { + size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize); + if (ZSTD_isError(ret)) return ret; + if (ret > 0) return ERROR(srcSize_wrong); + } + + ip += headerSize; + remainingSize -= headerSize; + + /* Loop on each block */ + while (1) { + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + + if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) return ERROR(srcSize_wrong); + + ip += ZSTD_blockHeaderSize + cBlockSize; + remainingSize -= ZSTD_blockHeaderSize + cBlockSize; + + if (blockProperties.lastBlock) break; + } + + if (fParams.checksumFlag) { /* Frame content checksum */ + if (remainingSize < 4) return ERROR(srcSize_wrong); + ip += 4; + remainingSize -= 4; + } + + return ip - ipstart; } - - ip += headerSize; - remainingSize -= headerSize; - - /* Loop on each block */ - while (1) { - blockProperties_t blockProperties; - size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); - if (ZSTD_isError(cBlockSize)) return cBlockSize; - - if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) return ERROR(srcSize_wrong); - - ip += ZSTD_blockHeaderSize + cBlockSize; - remainingSize -= ZSTD_blockHeaderSize + cBlockSize; - - if (blockProperties.lastBlock) break; - } - - if (fParams.checksumFlag) { /* Frame content checksum verification */ - if (remainingSize < 4) return ERROR(srcSize_wrong); - ip += 4; - remainingSize -= 4; - } - - return ip - ipstart; } /*! ZSTD_decompressFrame() : @@ -1578,7 +1576,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) if (ZSTD_isLegacy(src, srcSize)) { - size_t const frameSize = ZSTD_frameSrcSizeLegacy(src, srcSize); + size_t const frameSize = ZSTD_getFrameCompressedSizeLegacy(src, srcSize); size_t decodedSize; if (ZSTD_isError(frameSize)) return frameSize; diff --git a/lib/legacy/zstd_legacy.h b/lib/legacy/zstd_legacy.h index c0369ab4..b0a7b71d 100644 --- a/lib/legacy/zstd_legacy.h +++ b/lib/legacy/zstd_legacy.h @@ -123,26 +123,26 @@ MEM_STATIC size_t ZSTD_decompressLegacy( } } -MEM_STATIC size_t ZSTD_frameSrcSizeLegacy(const void *src, +MEM_STATIC size_t ZSTD_getFrameCompressedSizeLegacy(const void *src, size_t compressedSize) { U32 const version = ZSTD_isLegacy(src, compressedSize); switch(version) { case 1 : - return ZSTDv01_frameSrcSize(src, compressedSize); + return ZSTDv01_getFrameCompressedSize(src, compressedSize); case 2 : - return ZSTDv02_frameSrcSize(src, compressedSize); + return ZSTDv02_getFrameCompressedSize(src, compressedSize); case 3 : - return ZSTDv03_frameSrcSize(src, compressedSize); + return ZSTDv03_getFrameCompressedSize(src, compressedSize); case 4 : - return ZSTDv04_frameSrcSize(src, compressedSize); + return ZSTDv04_getFrameCompressedSize(src, compressedSize); case 5 : - return ZSTDv05_frameSrcSize(src, compressedSize); + return ZSTDv05_getFrameCompressedSize(src, compressedSize); case 6 : - return ZSTDv06_frameSrcSize(src, compressedSize); + return ZSTDv06_getFrameCompressedSize(src, compressedSize); case 7 : - return ZSTDv07_frameSrcSize(src, compressedSize); + return ZSTDv07_getFrameCompressedSize(src, compressedSize); default : return ERROR(prefix_unknown); } diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index c9b676ad..a0c78a4b 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -1992,7 +1992,7 @@ size_t ZSTDv01_decompress(void* dst, size_t maxDstSize, const void* src, size_t return ZSTDv01_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); } -size_t ZSTDv01_frameSrcSize(const void* src, size_t srcSize) +size_t ZSTDv01_getFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v01.h b/lib/legacy/zstd_v01.h index 9e5d553b..21959fcd 100644 --- a/lib/legacy/zstd_v01.h +++ b/lib/legacy/zstd_v01.h @@ -40,7 +40,7 @@ ZSTDv01_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv01_isError()) */ -size_t ZSTDv01_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv01_getFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv01_isError() : tells if the result of ZSTDv01_decompress() is an error diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index f3b107af..6cbf8023 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -3378,7 +3378,7 @@ static size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, siz return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); } -static size_t ZSTD_frameSrcSize(const void *src, size_t srcSize) +static size_t ZSTD_getFrameCompressedSize(const void *src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; @@ -3524,9 +3524,9 @@ size_t ZSTDv02_decompress( void* dst, size_t maxOriginalSize, return ZSTD_decompress(dst, maxOriginalSize, src, compressedSize); } -size_t ZSTDv02_frameSrcSize(const void *src, size_t compressedSize) +size_t ZSTDv02_getFrameCompressedSize(const void *src, size_t compressedSize) { - return ZSTD_frameSrcSize(src, compressedSize); + return ZSTD_getFrameCompressedSize(src, compressedSize); } ZSTDv02_Dctx* ZSTDv02_createDCtx(void) diff --git a/lib/legacy/zstd_v02.h b/lib/legacy/zstd_v02.h index 45dc5f6c..9542fc0e 100644 --- a/lib/legacy/zstd_v02.h +++ b/lib/legacy/zstd_v02.h @@ -40,7 +40,7 @@ ZSTDv02_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv02_isError()) */ -size_t ZSTDv02_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv02_getFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv02_isError() : tells if the result of ZSTDv02_decompress() is an error diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 2eba77cc..98b93c49 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -3019,7 +3019,7 @@ static size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, siz return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); } -static size_t ZSTD_frameSrcSize(const void* src, size_t srcSize) +static size_t ZSTD_getFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; @@ -3165,9 +3165,9 @@ size_t ZSTDv03_decompress( void* dst, size_t maxOriginalSize, return ZSTD_decompress(dst, maxOriginalSize, src, compressedSize); } -size_t ZSTDv03_frameSrcSize(const void* src, size_t srcSize) +size_t ZSTDv03_getFrameCompressedSize(const void* src, size_t srcSize) { - return ZSTD_frameSrcSize(src, srcSize); + return ZSTD_getFrameCompressedSize(src, srcSize); } ZSTDv03_Dctx* ZSTDv03_createDCtx(void) diff --git a/lib/legacy/zstd_v03.h b/lib/legacy/zstd_v03.h index 24dba1f5..46969410 100644 --- a/lib/legacy/zstd_v03.h +++ b/lib/legacy/zstd_v03.h @@ -40,7 +40,7 @@ ZSTDv03_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv03_isError()) */ -size_t ZSTDv03_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv03_getFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv03_isError() : tells if the result of ZSTDv03_decompress() is an error diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 7c900e1e..8c929b05 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -3326,7 +3326,7 @@ static size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx, return op-ostart; } -static size_t ZSTD_frameSrcSize(const void* src, size_t srcSize) +static size_t ZSTD_getFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; @@ -3782,9 +3782,9 @@ size_t ZSTDv04_decompress(void* dst, size_t maxDstSize, const void* src, size_t #endif } -size_t ZSTDv04_frameSrcSize(const void* src, size_t srcSize) +size_t ZSTDv04_getFrameCompressedSize(const void* src, size_t srcSize) { - return ZSTD_frameSrcSize(src, srcSize); + return ZSTD_getFrameCompressedSize(src, srcSize); } size_t ZSTDv04_resetDCtx(ZSTDv04_Dctx* dctx) { return ZSTD_resetDCtx(dctx); } diff --git a/lib/legacy/zstd_v04.h b/lib/legacy/zstd_v04.h index 671ba6dc..bcef1fe9 100644 --- a/lib/legacy/zstd_v04.h +++ b/lib/legacy/zstd_v04.h @@ -40,7 +40,7 @@ ZSTDv04_getFrameSrcSize() : get the source length of a ZSTD frame compliant with return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv04_isError()) */ -size_t ZSTDv04_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv04_getFrameCompressedSize(const void* src, size_t compressedSize); /** ZSTDv04_isError() : tells if the result of ZSTDv04_decompress() is an error diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index 85c0f0e7..9689b170 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -3583,7 +3583,7 @@ size_t ZSTDv05_decompress(void* dst, size_t maxDstSize, const void* src, size_t #endif } -size_t ZSTDv05_frameSrcSize(const void *src, size_t srcSize) +size_t ZSTDv05_getFrameCompressedSize(const void *src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v05.h b/lib/legacy/zstd_v05.h index ef2d18d1..157dbc57 100644 --- a/lib/legacy/zstd_v05.h +++ b/lib/legacy/zstd_v05.h @@ -38,7 +38,7 @@ ZSTDv05_getFrameSrcSize() : get the source length of a ZSTD frame return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv05_isError()) */ -size_t ZSTDv05_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv05_getFrameCompressedSize(const void* src, size_t compressedSize); /* ************************************* * Helper functions diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 92c1a45c..4c8f0682 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -3729,7 +3729,7 @@ size_t ZSTDv06_decompress(void* dst, size_t dstCapacity, const void* src, size_t #endif } -size_t ZSTDv06_frameSrcSize(const void* src, size_t srcSize) +size_t ZSTDv06_getFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v06.h b/lib/legacy/zstd_v06.h index 1fad7311..ef1feb2f 100644 --- a/lib/legacy/zstd_v06.h +++ b/lib/legacy/zstd_v06.h @@ -47,7 +47,7 @@ ZSTDv06_getFrameSrcSize() : get the source length of a ZSTD frame return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv06_isError()) */ -size_t ZSTDv06_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv06_getFrameCompressedSize(const void* src, size_t compressedSize); /* ************************************* * Helper functions diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 6228ee87..441e4bc3 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -3968,7 +3968,7 @@ size_t ZSTDv07_decompress(void* dst, size_t dstCapacity, const void* src, size_t #endif } -size_t ZSTDv07_frameSrcSize(const void* src, size_t srcSize) +size_t ZSTDv07_getFrameCompressedSize(const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; size_t remainingSize = srcSize; diff --git a/lib/legacy/zstd_v07.h b/lib/legacy/zstd_v07.h index b02b3dce..a79cbb88 100644 --- a/lib/legacy/zstd_v07.h +++ b/lib/legacy/zstd_v07.h @@ -54,7 +54,7 @@ ZSTDv07_getFrameSrcSize() : get the source length of a ZSTD frame return : the number of bytes that would be read to decompress this frame or an errorCode if it fails (which can be tested using ZSTDv07_isError()) */ -size_t ZSTDv07_frameSrcSize(const void* src, size_t compressedSize); +size_t ZSTDv07_getFrameCompressedSize(const void* src, size_t compressedSize); /*====== Helper functions ======*/ ZSTDLIBv07_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ diff --git a/lib/zstd.h b/lib/zstd.h index bbfefb8d..e2f752dd 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -396,6 +396,17 @@ typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); typedef void (*ZSTD_freeFunction) (void* opaque, void* address); typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; +/*************************************** +* Compressed size functions +***************************************/ + +/*! ZSTD_getFrameCompressedSize() : + * `src` should point to the start of a ZSTD encoded frame + * `srcSize` must be at least as large as the frame + * @return : the compressed size of the frame pointed to by `src`, suitable to pass to + * `ZSTD_decompress` or similar, or an error code if given invalid input. */ +ZSTDLIB_API size_t ZSTD_getFrameCompressedSize(const void* src, size_t srcSize); + /*************************************** * Decompressed size functions ***************************************/