"Fossies" - the Fresh Open Source Software Archive

Member "unrar/unpackinline.cpp" (4 May 2022, 3789 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "unpackinline.cpp" see the Fossies "Dox" file reference documentation.

    1 _forceinline void Unpack::InsertOldDist(uint Distance)
    2 {
    3   OldDist[3]=OldDist[2];
    4   OldDist[2]=OldDist[1];
    5   OldDist[1]=OldDist[0];
    6   OldDist[0]=Distance;
    7 }
    8 
    9 #ifdef _MSC_VER
   10 #define FAST_MEMCPY
   11 #endif
   12 
   13 _forceinline void Unpack::CopyString(uint Length,uint Distance)
   14 {
   15   size_t SrcPtr=UnpPtr-Distance;
   16   if (SrcPtr<MaxWinSize-MAX_INC_LZ_MATCH && UnpPtr<MaxWinSize-MAX_INC_LZ_MATCH)
   17   {
   18     // If we are not close to end of window, we do not need to waste time
   19     // to "& MaxWinMask" pointer protection.
   20 
   21     byte *Src=Window+SrcPtr;
   22     byte *Dest=Window+UnpPtr;
   23     UnpPtr+=Length;
   24 
   25 #ifdef FAST_MEMCPY
   26     if (Distance<Length) // Overlapping strings
   27 #endif
   28       while (Length>=8)
   29       {
   30         Dest[0]=Src[0];
   31         Dest[1]=Src[1];
   32         Dest[2]=Src[2];
   33         Dest[3]=Src[3];
   34         Dest[4]=Src[4];
   35         Dest[5]=Src[5];
   36         Dest[6]=Src[6];
   37         Dest[7]=Src[7];
   38 
   39         Src+=8;
   40         Dest+=8;
   41         Length-=8;
   42       }
   43 #ifdef FAST_MEMCPY
   44     else
   45       while (Length>=8)
   46       {
   47         // In theory we still could overlap here.
   48         // Supposing Distance == MaxWinSize - 1 we have memcpy(Src, Src + 1, 8).
   49         // But for real RAR archives Distance <= MaxWinSize - MAX_INC_LZ_MATCH
   50         // always, so overlap here is impossible.
   51 
   52         // This memcpy expanded inline by MSVC. We could also use uint64
   53         // assignment, which seems to provide about the same speed.
   54         memcpy(Dest,Src,8); 
   55 
   56         Src+=8;
   57         Dest+=8;
   58         Length-=8;
   59       }
   60 #endif
   61 
   62     // Unroll the loop for 0 - 7 bytes left. Note that we use nested "if"s.
   63     if (Length>0) { Dest[0]=Src[0];
   64     if (Length>1) { Dest[1]=Src[1];
   65     if (Length>2) { Dest[2]=Src[2];
   66     if (Length>3) { Dest[3]=Src[3];
   67     if (Length>4) { Dest[4]=Src[4];
   68     if (Length>5) { Dest[5]=Src[5];
   69     if (Length>6) { Dest[6]=Src[6]; } } } } } } } // Close all nested "if"s.
   70   }
   71   else
   72     while (Length-- > 0) // Slow copying with all possible precautions.
   73     {
   74       Window[UnpPtr]=Window[SrcPtr++ & MaxWinMask];
   75       // We need to have masked UnpPtr after quit from loop, so it must not
   76       // be replaced with 'Window[UnpPtr++ & MaxWinMask]'
   77       UnpPtr=(UnpPtr+1) & MaxWinMask;
   78     }
   79 }
   80 
   81 
   82 _forceinline uint Unpack::DecodeNumber(BitInput &Inp,DecodeTable *Dec)
   83 {
   84   // Left aligned 15 bit length raw bit field.
   85   uint BitField=Inp.getbits() & 0xfffe;
   86 
   87   if (BitField<Dec->DecodeLen[Dec->QuickBits])
   88   {
   89     uint Code=BitField>>(16-Dec->QuickBits);
   90     Inp.addbits(Dec->QuickLen[Code]);
   91     return Dec->QuickNum[Code];
   92   }
   93 
   94   // Detect the real bit length for current code.
   95   uint Bits=15;
   96   for (uint I=Dec->QuickBits+1;I<15;I++)
   97     if (BitField<Dec->DecodeLen[I])
   98     {
   99       Bits=I;
  100       break;
  101     }
  102 
  103   Inp.addbits(Bits);
  104   
  105   // Calculate the distance from the start code for current bit length.
  106   uint Dist=BitField-Dec->DecodeLen[Bits-1];
  107 
  108   // Start codes are left aligned, but we need the normal right aligned
  109   // number. So we shift the distance to the right.
  110   Dist>>=(16-Bits);
  111 
  112   // Now we can calculate the position in the code list. It is the sum
  113   // of first position for current bit length and right aligned distance
  114   // between our bit field and start code for current bit length.
  115   uint Pos=Dec->DecodePos[Bits]+Dist;
  116 
  117   // Out of bounds safety check required for damaged archives.
  118   if (Pos>=Dec->MaxNum)
  119     Pos=0;
  120 
  121   // Convert the position in the code list to position in alphabet
  122   // and return it.
  123   return Dec->DecodeNum[Pos];
  124 }
  125 
  126 
  127 _forceinline uint Unpack::SlotToLength(BitInput &Inp,uint Slot)
  128 {
  129   uint LBits,Length=2;
  130   if (Slot<8)
  131   {
  132     LBits=0;
  133     Length+=Slot;
  134   }
  135   else
  136   {
  137     LBits=Slot/4-1;
  138     Length+=(4 | (Slot & 3)) << LBits;
  139   }
  140 
  141   if (LBits>0)
  142   {
  143     Length+=Inp.getbits()>>(16-LBits);
  144     Inp.addbits(LBits);
  145   }
  146   return Length;
  147 }