]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
long decoder compatible with round and separate buffers
authorYann Collet <cyan@fb.com>
Tue, 29 Nov 2016 03:59:11 +0000 (19:59 -0800)
committerYann Collet <cyan@fb.com>
Tue, 29 Nov 2016 03:59:11 +0000 (19:59 -0800)
lib/common/mem.h
lib/decompress/zstd_decompress.c

index 681dd35d2dacbeda07733458f84d6b22ef44c975..32c63dd1763c17819eae402fe9691b7bfe383d05 100644 (file)
@@ -55,14 +55,16 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size
   typedef  int32_t S32;
   typedef uint64_t U64;
   typedef  int64_t S64;
+  typedef intptr_t iPtrDiff;
 #else
-  typedef unsigned char       BYTE;
+  typedef unsigned char      BYTE;
   typedef unsigned short      U16;
   typedef   signed short      S16;
   typedef unsigned int        U32;
   typedef   signed int        S32;
   typedef unsigned long long  U64;
   typedef   signed long long  S64;
+  typedef ptrdiff_t      iPtrDiff;
 #endif
 
 
index 2d40873350afe8a52c0793a361e7970aeef5e454..da3cf56e275f281679b245c1c7dbd5884a72ff22 100644 (file)
@@ -794,6 +794,8 @@ typedef struct {
     FSE_DState_t stateML;
     size_t prevOffset[ZSTD_REP_NUM];
     const BYTE* ptr;
+    const BYTE* base;
+    iPtrDiff gotoDict;
 } seqState_t;
 
 
@@ -862,7 +864,8 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState)
     if (MEM_32bits() ||
        (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
 
-    seq.match = seqState->ptr + seq.litLength - seq.offset;   /* only for single memory segment ! */
+    seq.match = seqState->ptr + seq.litLength - seq.offset;    /* single memory segment ! */
+    if (seq.match < seqState->base) seq.match += seqState->gotoDict;   /* what if seq.match underflows ? prefetch is a non issue, but match has now a wrong address */
 
     /* ANS state update */
     FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
@@ -954,7 +957,6 @@ size_t ZSTD_execSequenceLong(BYTE* op,
     if (sequence.offset > (size_t)(oLitEnd - base)) {
         /* offset beyond prefix */
         if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
-        match = dictEnd - (base-match);
         if (match + sequence.matchLength <= dictEnd) {
             memmove(oLitEnd, match, sequence.matchLength);
             return sequenceLength;
@@ -1041,6 +1043,8 @@ static size_t ZSTD_decompressSequencesLong(
         dctx->fseEntropy = 1;
         { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
         seqState.ptr = op;
+        seqState.base = base;
+        seqState.gotoDict = (iPtrDiff)(dictEnd - base);
         CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
         FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
         FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);