/** ZSTD_decodeLiteralsBlock
@return : nb of bytes read from src (< srcSize )*/
size_t ZSTD_decodeLiteralsBlock(void* ctx,
- const void* src, size_t srcSize)
+ const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
{
ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx;
- const BYTE* const istart = (const BYTE* const)src;
+ const BYTE* const istart = (const BYTE*) src;
/* any compressed block with literals segment must be at least this size */
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
switch(*istart & 3)
{
+ /* compressed */
case 0:
{
size_t litSize = BLOCKSIZE;
const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);
dctx->litPtr = dctx->litBuffer;
- dctx->litBufSize = BLOCKSIZE;
+ dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize;
return readSize; /* works if it's an error too */
}
{
if (litSize > srcSize-3) return ERROR(corruption_detected);
memcpy(dctx->litBuffer, istart, litSize);
- dctx->litBufSize = BLOCKSIZE;
+ dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize;
return litSize+3;
}
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
memset(dctx->litBuffer, istart[3], litSize);
dctx->litPtr = dctx->litBuffer;
- dctx->litBufSize = BLOCKSIZE;
+ dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize;
return 4;
}
static size_t ZSTD_execSequence(BYTE* op,
seq_t sequence,
- const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE** litPtr, const BYTE* const litLimit_8,
BYTE* const base, BYTE* const oend)
{
static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
/* check */
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
- if (litEnd > litLimit-8) return ERROR(corruption_detected); /* overRead beyond lit buffer */
+ if (litEnd > litLimit_8) return ERROR(corruption_detected); /* overRead beyond lit buffer */
/* copy Literals */
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
BYTE* const oend = ostart + maxDstSize;
size_t errorCode, dumpsLength;
const BYTE* litPtr = dctx->litPtr;
- const BYTE* const litMax = litPtr + dctx->litBufSize;
+ const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
const BYTE* const litEnd = litPtr + dctx->litSize;
int nbSeq;
const BYTE* dumps;
size_t oneSeqSize;
nbSeq--;
ZSTD_decodeSequence(&sequence, &seqState);
- oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litMax, base, oend);
+ oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litLimit_8, base, oend);
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
op += oneSeqSize;
}
{
seqStore_t* seqStorePtr = &(ctx->seqStore);
const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart + 1;
+ const BYTE* ip = istart;
const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - 8;
- size_t offset_2=4, offset_1=4;
+ size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE;
const U32 maxSearches = 1 << ctx->compressionLevel;
/* init */
ZSTD_resetSeqStore(seqStorePtr);
+ if (((ip-ctx->base) - ctx->dictLimit) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
- /* Main Search Loop */
+ /* Match Loop */
while (ip < ilimit)
{
- const BYTE* match;
- size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, ilimit, &match, maxSearches);
- if (!matchLength) { ip++; continue; }
- /* save match */
+ /* repcode */
+ if (MEM_read32(ip) == MEM_read32(ip - offset_2))
+ /* store sequence */
{
+ size_t matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend);
size_t litLength = ip-anchor;
- size_t offset = ip-match;
- if (litLength) offset_2 = offset_1;
- if (offset == offset_2) offset = 0;
+ size_t offset = offset_2;
offset_2 = offset_1;
- offset_1 = ip-match;
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH);
- ip += matchLength;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, 0, matchLength);
+ ip += matchLength+MINMATCH;
anchor = ip;
+ continue;
+ }
+
+ /* search */
+ {
+ const BYTE* match;
+ size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, iend, &match, maxSearches);
+ if (!matchLength) { ip++; offset_2 = offset_1; continue; }
+ /* store sequence */
+ {
+ size_t litLength = ip-anchor;
+ size_t offset = ip-match;
+ if (offset == offset_2) offset = 0;
+ offset_2 = offset_1;
+ offset_1 = ip-match;
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH);
+ ip += matchLength;
+ anchor = ip;
+ }
}
}