diff options
author | XhmikosR <xhmikosr@users.sourceforge.net> | 2013-05-05 11:39:47 +0400 |
---|---|---|
committer | XhmikosR <xhmikosr@users.sourceforge.net> | 2013-05-06 02:56:22 +0400 |
commit | 00f8520475b119d50d40b8a4b2298f04afa821b9 (patch) | |
tree | e389319284c45b5305bb5156e1d8f8310849902a /src/thirdparty/unrar/rawread.cpp | |
parent | b18faab4208d8368d28c7b51afe5a73bbc90b05e (diff) |
update unrar to v5.0.2
Diffstat (limited to 'src/thirdparty/unrar/rawread.cpp')
-rw-r--r-- | src/thirdparty/unrar/rawread.cpp | 144 |
1 files changed, 104 insertions, 40 deletions
diff --git a/src/thirdparty/unrar/rawread.cpp b/src/thirdparty/unrar/rawread.cpp index df90171eb..2daad9119 100644 --- a/src/thirdparty/unrar/rawread.cpp +++ b/src/thirdparty/unrar/rawread.cpp @@ -3,6 +3,13 @@ RawRead::RawRead(File *SrcFile) { RawRead::SrcFile=SrcFile; + Reset(); +} + + +void RawRead::Reset() +{ + Data.SoftReset(); ReadPos=0; DataSize=0; #ifndef SHELL_EXT @@ -11,31 +18,43 @@ RawRead::RawRead(File *SrcFile) } -void RawRead::Read(size_t Size) +size_t RawRead::Read(size_t Size) { + size_t ReadSize=0; #if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT) if (Crypt!=NULL) { - size_t CurSize=Data.Size(); - size_t SizeToRead=Size-(CurSize-DataSize); - if (SizeToRead>0) + // Full size of buffer with already read data including data read + // for encryption block alignment. + size_t FullSize=Data.Size(); + + // Data read for alignment and not processed yet. + size_t DataLeft=FullSize-DataSize; + + if (Size>DataLeft) // Need to read more than we already have. { - size_t AlignedReadSize=SizeToRead+((~SizeToRead+1)&0xf); + size_t SizeToRead=Size-DataLeft; + size_t AlignedReadSize=SizeToRead+((~SizeToRead+1) & CRYPT_BLOCK_MASK); Data.Add(AlignedReadSize); - size_t ReadSize=SrcFile->Read(&Data[CurSize],AlignedReadSize); - Crypt->DecryptBlock(&Data[CurSize],AlignedReadSize); + ReadSize=SrcFile->Read(&Data[FullSize],AlignedReadSize); + Crypt->DecryptBlock(&Data[FullSize],AlignedReadSize); DataSize+=ReadSize==0 ? 0:Size; } - else + else // Use buffered data, no real read. + { + ReadSize=Size; DataSize+=Size; + } } else #endif if (Size!=0) { Data.Add(Size); - DataSize+=SrcFile->Read(&Data[DataSize],Size); + ReadSize=SrcFile->Read(&Data[DataSize],Size); + DataSize+=ReadSize; } + return ReadSize; } @@ -50,65 +69,82 @@ void RawRead::Read(byte *SrcData,size_t Size) } -void RawRead::Get(byte &Field) +byte RawRead::Get1() { - if (ReadPos<DataSize) - { - Field=Data[ReadPos]; - ReadPos++; - } - else - Field=0; + return ReadPos<DataSize ? Data[ReadPos++]:0; } -void RawRead::Get(ushort &Field) +ushort RawRead::Get2() { if (ReadPos+1<DataSize) { - Field=Data[ReadPos]+(Data[ReadPos+1]<<8); + ushort Result=Data[ReadPos]+(Data[ReadPos+1]<<8); ReadPos+=2; + return Result; } - else - Field=0; + return 0; } -void RawRead::Get(uint &Field) +uint RawRead::Get4() { if (ReadPos+3<DataSize) { - Field=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+ - (Data[ReadPos+3]<<24); + uint Result=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+ + (Data[ReadPos+3]<<24); ReadPos+=4; + return Result; } - else - Field=0; + return 0; } -void RawRead::Get8(int64 &Field) +uint64 RawRead::Get8() { - uint Low,High; - Get(Low); - Get(High); - Field=INT32TO64(High,Low); + uint Low=Get4(),High=Get4(); + return INT32TO64(High,Low); } -void RawRead::Get(byte *Field,size_t Size) +uint64 RawRead::GetV() { - if (ReadPos+Size-1<DataSize) + uint64 Result=0; + for (uint Shift=0;ReadPos<DataSize;Shift+=7) { - memcpy(Field,&Data[ReadPos],Size); - ReadPos+=Size; + byte CurByte=Data[ReadPos++]; + Result+=uint64(CurByte & 0x7f)<<Shift; + if ((CurByte & 0x80)==0) + return Result; // Decoded successfully. } - else - memset(Field,0,Size); + return 0; // Out of buffer border. +} + + +// Return a number of bytes in current variable length integer. +uint RawRead::GetVSize(size_t Pos) +{ + for (size_t CurPos=Pos;CurPos<DataSize;CurPos++) + if ((Data[CurPos] & 0x80)==0) + return int(CurPos-Pos+1); + return 0; // Buffer overflow. +} + + +size_t RawRead::GetB(void *Field,size_t Size) +{ + byte *F=(byte *)Field; + size_t CopySize=Min(DataSize-ReadPos,Size); + if (CopySize>0) + memcpy(F,&Data[ReadPos],CopySize); + if (Size>CopySize) + memset(F+CopySize,0,Size-CopySize); + ReadPos+=CopySize; + return CopySize; } -void RawRead::Get(wchar *Field,size_t Size) +void RawRead::GetW(wchar *Field,size_t Size) { if (ReadPos+2*Size-1<DataSize) { @@ -120,7 +156,35 @@ void RawRead::Get(wchar *Field,size_t Size) } -uint RawRead::GetCRC(bool ProcessedOnly) +uint RawRead::GetCRC15(bool ProcessedOnly) // RAR 1.5 block CRC. +{ + if (DataSize<=2) + return 0; + uint HeaderCRC=CRC32(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2); + return ~HeaderCRC & 0xffff; +} + + +uint RawRead::GetCRC50() // RAR 5.0 block CRC. +{ + if (DataSize<=4) + return 0xffffffff; + return CRC32(0xffffffff,&Data[4],DataSize-4) ^ 0xffffffff; +} + + +// Read vint from arbitrary byte array. +uint64 RawGetV(const byte *Data,uint &ReadPos,uint DataSize,bool &Overflow) { - return(DataSize>2 ? CRC(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2):0xffffffff); + Overflow=false; + uint64 Result=0; + for (uint Shift=0;ReadPos<DataSize;Shift+=7) + { + byte CurByte=Data[ReadPos++]; + Result+=uint64(CurByte & 0x7f)<<Shift; + if ((CurByte & 0x80)==0) + return Result; // Decoded successfully. + } + Overflow=true; + return 0; // Out of buffer border. } |