rawread.cpp 3.9 KB

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