in lib/legacy/zstd_v05.c [1424:1489]
FORCE_INLINE size_t FSEv05_decompress_usingDTable_generic(
void* dst, size_t maxDstSize,
const void* cSrc, size_t cSrcSize,
const FSEv05_DTable* dt, const unsigned fast)
{
BYTE* const ostart = (BYTE*) dst;
BYTE* op = ostart;
BYTE* const omax = op + maxDstSize;
BYTE* const olimit = omax-3;
BITv05_DStream_t bitD;
FSEv05_DState_t state1;
FSEv05_DState_t state2;
size_t errorCode;
/* Init */
errorCode = BITv05_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */
if (FSEv05_isError(errorCode)) return errorCode;
FSEv05_initDState(&state1, &bitD, dt);
FSEv05_initDState(&state2, &bitD, dt);
#define FSEv05_GETSYMBOL(statePtr) fast ? FSEv05_decodeSymbolFast(statePtr, &bitD) : FSEv05_decodeSymbol(statePtr, &bitD)
/* 4 symbols per loop */
for ( ; (BITv05_reloadDStream(&bitD)==BITv05_DStream_unfinished) && (op<olimit) ; op+=4) {
op[0] = FSEv05_GETSYMBOL(&state1);
if (FSEv05_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
BITv05_reloadDStream(&bitD);
op[1] = FSEv05_GETSYMBOL(&state2);
if (FSEv05_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
{ if (BITv05_reloadDStream(&bitD) > BITv05_DStream_unfinished) { op+=2; break; } }
op[2] = FSEv05_GETSYMBOL(&state1);
if (FSEv05_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
BITv05_reloadDStream(&bitD);
op[3] = FSEv05_GETSYMBOL(&state2);
}
/* tail */
/* note : BITv05_reloadDStream(&bitD) >= FSEv05_DStream_partiallyFilled; Ends at exactly BITv05_DStream_completed */
while (1) {
if ( (BITv05_reloadDStream(&bitD)>BITv05_DStream_completed) || (op==omax) || (BITv05_endOfDStream(&bitD) && (fast || FSEv05_endOfDState(&state1))) )
break;
*op++ = FSEv05_GETSYMBOL(&state1);
if ( (BITv05_reloadDStream(&bitD)>BITv05_DStream_completed) || (op==omax) || (BITv05_endOfDStream(&bitD) && (fast || FSEv05_endOfDState(&state2))) )
break;
*op++ = FSEv05_GETSYMBOL(&state2);
}
/* end ? */
if (BITv05_endOfDStream(&bitD) && FSEv05_endOfDState(&state1) && FSEv05_endOfDState(&state2))
return op-ostart;
if (op==omax) return ERROR(dstSize_tooSmall); /* dst buffer is full, but cSrc unfinished */
return ERROR(corruption_detected);
}