"Fossies" - the Fresh Open Source Software Archive

Member "unrar/rawread.cpp" (4 May 2022, 3943 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 "rawread.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 RawRead::RawRead()
    4 {
    5   RawRead::SrcFile=NULL;
    6   Reset();
    7 }
    8 
    9 
   10 RawRead::RawRead(File *SrcFile)
   11 {
   12   RawRead::SrcFile=SrcFile;
   13   Reset();
   14 }
   15 
   16 
   17 void RawRead::Reset()
   18 {
   19   Data.SoftReset();
   20   ReadPos=0;
   21   DataSize=0;
   22   Crypt=NULL;
   23 }
   24 
   25 
   26 size_t RawRead::Read(size_t Size)
   27 {
   28   size_t ReadSize=0;
   29 #if !defined(RAR_NOCRYPT)
   30   if (Crypt!=NULL)
   31   {
   32     // Full size of buffer with already read data including data read 
   33     // for encryption block alignment.
   34     size_t FullSize=Data.Size();
   35 
   36     // Data read for alignment and not processed yet.
   37     size_t DataLeft=FullSize-DataSize;
   38 
   39     if (Size>DataLeft) // Need to read more than we already have.
   40     {
   41       size_t SizeToRead=Size-DataLeft;
   42       size_t AlignedReadSize=SizeToRead+((~SizeToRead+1) & CRYPT_BLOCK_MASK);
   43       Data.Add(AlignedReadSize);
   44       ReadSize=SrcFile->Read(&Data[FullSize],AlignedReadSize);
   45       Crypt->DecryptBlock(&Data[FullSize],AlignedReadSize);
   46       DataSize+=ReadSize==0 ? 0:Size;
   47     }
   48     else // Use buffered data, no real read.
   49     {
   50       ReadSize=Size;
   51       DataSize+=Size;
   52     }
   53   }
   54   else
   55 #endif
   56     if (Size!=0)
   57     {
   58       Data.Add(Size);
   59       ReadSize=SrcFile->Read(&Data[DataSize],Size);
   60       DataSize+=ReadSize;
   61     }
   62   return ReadSize;
   63 }
   64 
   65 
   66 void RawRead::Read(byte *SrcData,size_t Size)
   67 {
   68   if (Size!=0)
   69   {
   70     Data.Add(Size);
   71     memcpy(&Data[DataSize],SrcData,Size);
   72     DataSize+=Size;
   73   }
   74 }
   75 
   76 
   77 byte RawRead::Get1()
   78 {
   79   return ReadPos<DataSize ? Data[ReadPos++]:0;
   80 }
   81 
   82 
   83 ushort RawRead::Get2()
   84 {
   85   if (ReadPos+1<DataSize)
   86   {
   87     ushort Result=Data[ReadPos]+(Data[ReadPos+1]<<8);
   88     ReadPos+=2;
   89     return Result;
   90   }
   91   return 0;
   92 }
   93 
   94 
   95 uint RawRead::Get4()
   96 {
   97   if (ReadPos+3<DataSize)
   98   {
   99     uint Result=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
  100                 (Data[ReadPos+3]<<24);
  101     ReadPos+=4;
  102     return Result;
  103   }
  104   return 0;
  105 }
  106 
  107 
  108 uint64 RawRead::Get8()
  109 {
  110   uint Low=Get4(),High=Get4();
  111   return INT32TO64(High,Low);
  112 }
  113 
  114 
  115 uint64 RawRead::GetV()
  116 {
  117   uint64 Result=0;
  118   // Need to check Shift<64, because for shift greater than or equal to
  119   // the width of the promoted left operand, the behavior is undefined.
  120   for (uint Shift=0;ReadPos<DataSize && Shift<64;Shift+=7)
  121   {
  122     byte CurByte=Data[ReadPos++];
  123     Result+=uint64(CurByte & 0x7f)<<Shift;
  124     if ((CurByte & 0x80)==0)
  125       return Result; // Decoded successfully.
  126   }
  127   return 0; // Out of buffer border.
  128 }
  129 
  130 
  131 // Return a number of bytes in current variable length integer.
  132 uint RawRead::GetVSize(size_t Pos)
  133 {
  134   for (size_t CurPos=Pos;CurPos<DataSize;CurPos++)
  135     if ((Data[CurPos] & 0x80)==0)
  136       return int(CurPos-Pos+1);
  137   return 0; // Buffer overflow.
  138 }
  139 
  140 
  141 size_t RawRead::GetB(void *Field,size_t Size)
  142 {
  143   byte *F=(byte *)Field;
  144   size_t CopySize=Min(DataSize-ReadPos,Size);
  145   if (CopySize>0)
  146     memcpy(F,&Data[ReadPos],CopySize);
  147   if (Size>CopySize)
  148     memset(F+CopySize,0,Size-CopySize);
  149   ReadPos+=CopySize;
  150   return CopySize;
  151 }
  152 
  153 
  154 void RawRead::GetW(wchar *Field,size_t Size)
  155 {
  156   if (ReadPos+2*Size-1<DataSize)
  157   {
  158     RawToWide(&Data[ReadPos],Field,Size);
  159     ReadPos+=sizeof(wchar)*Size;
  160   }
  161   else
  162     memset(Field,0,sizeof(wchar)*Size);
  163 }
  164 
  165 
  166 uint RawRead::GetCRC15(bool ProcessedOnly) // RAR 1.5 block CRC.
  167 {
  168   if (DataSize<=2)
  169     return 0;
  170   uint HeaderCRC=CRC32(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2);
  171   return ~HeaderCRC & 0xffff;
  172 }
  173 
  174 
  175 uint RawRead::GetCRC50() // RAR 5.0 block CRC.
  176 {
  177   if (DataSize<=4)
  178     return 0xffffffff;
  179   return CRC32(0xffffffff,&Data[4],DataSize-4) ^ 0xffffffff;
  180 }
  181 
  182 
  183 // Read vint from arbitrary byte array.
  184 uint64 RawGetV(const byte *Data,uint &ReadPos,uint DataSize,bool &Overflow)
  185 {
  186   Overflow=false;
  187   uint64 Result=0;
  188   for (uint Shift=0;ReadPos<DataSize;Shift+=7)
  189   {
  190     byte CurByte=Data[ReadPos++];
  191     Result+=uint64(CurByte & 0x7f)<<Shift;
  192     if ((CurByte & 0x80)==0)
  193       return Result; // Decoded successfully.
  194   }
  195   Overflow=true;
  196   return 0; // Out of buffer border.
  197 }