| // 7zIn.h | |
| #ifndef __7Z_IN_H | |
| #define __7Z_IN_H | |
| #include "../../../Common/MyCom.h" | |
| #include "../../../Windows/PropVariant.h" | |
| #include "../../IPassword.h" | |
| #include "../../IStream.h" | |
| #include "../../Common/CreateCoder.h" | |
| #include "../../Common/InBuffer.h" | |
| #include "7zItem.h" | |
| namespace NArchive { | |
| namespace N7z { | |
| /* | |
| We don't need to init isEncrypted and passwordIsDefined | |
| We must upgrade them only */ | |
| #ifdef _NO_CRYPTO | |
| #define _7Z_DECODER_CRYPRO_VARS_DECL | |
| #define _7Z_DECODER_CRYPRO_VARS | |
| #else | |
| #define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined | |
| #define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined | |
| #endif | |
| struct CParsedMethods | |
| { | |
| Byte Lzma2Prop; | |
| UInt32 LzmaDic; | |
| CRecordVector<UInt64> IDs; | |
| CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {} | |
| }; | |
| struct CFolders | |
| { | |
| CNum NumPackStreams; | |
| CNum NumFolders; | |
| CObjArray<UInt64> PackPositions; // NumPackStreams + 1 | |
| // CUInt32DefVector PackCRCs; // we don't use PackCRCs now | |
| CUInt32DefVector FolderCRCs; // NumFolders | |
| CObjArray<CNum> NumUnpackStreamsVector; // NumFolders | |
| CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders | |
| CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1 | |
| CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1 | |
| CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders | |
| CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1 | |
| CByteBuffer CodersData; | |
| CParsedMethods ParsedMethods; | |
| void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const; | |
| unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const | |
| { | |
| return FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]; | |
| } | |
| UInt64 GetFolderUnpackSize(unsigned folderIndex) const | |
| { | |
| return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]]; | |
| } | |
| UInt64 GetStreamPackSize(unsigned index) const | |
| { | |
| return PackPositions[index + 1] - PackPositions[index]; | |
| } | |
| void Clear() | |
| { | |
| NumPackStreams = 0; | |
| PackPositions.Free(); | |
| // PackCRCs.Clear(); | |
| NumFolders = 0; | |
| FolderCRCs.Clear(); | |
| NumUnpackStreamsVector.Free(); | |
| CoderUnpackSizes.Free(); | |
| FoToCoderUnpackSizes.Free(); | |
| FoStartPackStreamIndex.Free(); | |
| FoToMainUnpackSizeIndex.Free(); | |
| FoCodersDataOffset.Free(); | |
| CodersData.Free(); | |
| } | |
| }; | |
| struct CDatabase: public CFolders | |
| { | |
| CRecordVector<CFileItem> Files; | |
| CUInt64DefVector CTime; | |
| CUInt64DefVector ATime; | |
| CUInt64DefVector MTime; | |
| CUInt64DefVector StartPos; | |
| CRecordVector<bool> IsAnti; | |
| /* | |
| CRecordVector<bool> IsAux; | |
| CByteBuffer SecureBuf; | |
| CRecordVector<UInt32> SecureIDs; | |
| */ | |
| CByteBuffer NamesBuf; | |
| CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols | |
| /* | |
| void ClearSecure() | |
| { | |
| SecureBuf.Free(); | |
| SecureIDs.Clear(); | |
| } | |
| */ | |
| void Clear() | |
| { | |
| CFolders::Clear(); | |
| // ClearSecure(); | |
| NamesBuf.Free(); | |
| NameOffsets.Free(); | |
| Files.Clear(); | |
| CTime.Clear(); | |
| ATime.Clear(); | |
| MTime.Clear(); | |
| StartPos.Clear(); | |
| IsAnti.Clear(); | |
| // IsAux.Clear(); | |
| } | |
| bool IsSolid() const | |
| { | |
| for (CNum i = 0; i < NumFolders; i++) | |
| if (NumUnpackStreamsVector[i] > 1) | |
| return true; | |
| return false; | |
| } | |
| bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } | |
| // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } | |
| const void * GetName(unsigned index) const | |
| { | |
| if (!NameOffsets || !NamesBuf) | |
| return NULL; | |
| return (const void *)((const Byte *)NamesBuf + NameOffsets[index] * 2); | |
| }; | |
| void GetPath(unsigned index, UString &path) const; | |
| HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); | |
| }; | |
| struct CInArchiveInfo | |
| { | |
| CArchiveVersion Version; | |
| UInt64 StartPosition; | |
| UInt64 StartPositionAfterHeader; | |
| UInt64 DataStartPosition; | |
| UInt64 DataStartPosition2; | |
| CRecordVector<UInt64> FileInfoPopIDs; | |
| void Clear() | |
| { | |
| StartPosition = 0; | |
| StartPositionAfterHeader = 0; | |
| DataStartPosition = 0; | |
| DataStartPosition2 = 0; | |
| FileInfoPopIDs.Clear(); | |
| } | |
| }; | |
| struct CDbEx: public CDatabase | |
| { | |
| CInArchiveInfo ArcInfo; | |
| CRecordVector<CNum> FolderStartFileIndex; | |
| CRecordVector<CNum> FileIndexToFolderIndexMap; | |
| UInt64 HeadersSize; | |
| UInt64 PhySize; | |
| /* | |
| CRecordVector<size_t> SecureOffsets; | |
| bool IsTree; | |
| bool ThereAreAltStreams; | |
| */ | |
| bool IsArc; | |
| bool PhySizeWasConfirmed; | |
| bool ThereIsHeaderError; | |
| bool UnexpectedEnd; | |
| // bool UnsupportedVersion; | |
| bool StartHeaderWasRecovered; | |
| bool UnsupportedFeatureWarning; | |
| bool UnsupportedFeatureError; | |
| /* | |
| void ClearSecureEx() | |
| { | |
| ClearSecure(); | |
| SecureOffsets.Clear(); | |
| } | |
| */ | |
| void Clear() | |
| { | |
| IsArc = false; | |
| PhySizeWasConfirmed = false; | |
| ThereIsHeaderError = false; | |
| UnexpectedEnd = false; | |
| // UnsupportedVersion = false; | |
| StartHeaderWasRecovered = false; | |
| UnsupportedFeatureError = false; | |
| UnsupportedFeatureWarning = false; | |
| /* | |
| IsTree = false; | |
| ThereAreAltStreams = false; | |
| */ | |
| CDatabase::Clear(); | |
| // SecureOffsets.Clear(); | |
| ArcInfo.Clear(); | |
| FolderStartFileIndex.Clear(); | |
| FileIndexToFolderIndexMap.Clear(); | |
| HeadersSize = 0; | |
| PhySize = 0; | |
| } | |
| void FillLinks(); | |
| UInt64 GetFolderStreamPos(unsigned folderIndex, unsigned indexInFolder) const | |
| { | |
| return ArcInfo.DataStartPosition + | |
| PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder]; | |
| } | |
| UInt64 GetFolderFullPackSize(unsigned folderIndex) const | |
| { | |
| return | |
| PackPositions[FoStartPackStreamIndex[folderIndex + 1]] - | |
| PackPositions[FoStartPackStreamIndex[folderIndex]]; | |
| } | |
| UInt64 GetFolderPackStreamSize(unsigned folderIndex, unsigned streamIndex) const | |
| { | |
| unsigned i = FoStartPackStreamIndex[folderIndex] + streamIndex; | |
| return PackPositions[i + 1] - PackPositions[i]; | |
| } | |
| UInt64 GetFilePackSize(CNum fileIndex) const | |
| { | |
| CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; | |
| if (folderIndex != kNumNoIndex) | |
| if (FolderStartFileIndex[folderIndex] == fileIndex) | |
| return GetFolderFullPackSize(folderIndex); | |
| return 0; | |
| } | |
| }; | |
| const unsigned kNumBufLevelsMax = 4; | |
| struct CInByte2 | |
| { | |
| const Byte *_buffer; | |
| public: | |
| size_t _size; | |
| size_t _pos; | |
| size_t GetRem() const { return _size - _pos; } | |
| const Byte *GetPtr() const { return _buffer + _pos; } | |
| void Init(const Byte *buffer, size_t size) | |
| { | |
| _buffer = buffer; | |
| _size = size; | |
| _pos = 0; | |
| } | |
| Byte ReadByte(); | |
| void ReadBytes(Byte *data, size_t size); | |
| void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; } | |
| void SkipData(UInt64 size); | |
| void SkipData(); | |
| void SkipRem() { _pos = _size; } | |
| UInt64 ReadNumber(); | |
| CNum ReadNum(); | |
| UInt32 ReadUInt32(); | |
| UInt64 ReadUInt64(); | |
| void ParseFolder(CFolder &folder); | |
| }; | |
| class CStreamSwitch; | |
| const UInt32 kHeaderSize = 32; | |
| class CInArchive | |
| { | |
| friend class CStreamSwitch; | |
| CMyComPtr<IInStream> _stream; | |
| unsigned _numInByteBufs; | |
| CInByte2 _inByteVector[kNumBufLevelsMax]; | |
| CInByte2 *_inByteBack; | |
| bool ThereIsHeaderError; | |
| UInt64 _arhiveBeginStreamPosition; | |
| UInt64 _fileEndPosition; | |
| Byte _header[kHeaderSize]; | |
| UInt64 HeadersSize; | |
| void AddByteStream(const Byte *buffer, size_t size); | |
| void DeleteByteStream(bool needUpdatePos) | |
| { | |
| _numInByteBufs--; | |
| if (_numInByteBufs > 0) | |
| { | |
| _inByteBack = &_inByteVector[_numInByteBufs - 1]; | |
| if (needUpdatePos) | |
| _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos; | |
| } | |
| } | |
| private: | |
| HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); | |
| void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } | |
| Byte ReadByte() { return _inByteBack->ReadByte(); } | |
| UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } | |
| CNum ReadNum() { return _inByteBack->ReadNum(); } | |
| UInt64 ReadID() { return _inByteBack->ReadNumber(); } | |
| UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } | |
| UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } | |
| void SkipData(UInt64 size) { _inByteBack->SkipData(size); } | |
| void SkipData() { _inByteBack->SkipData(); } | |
| void WaitId(UInt64 id); | |
| void ReadArchiveProperties(CInArchiveInfo &archiveInfo); | |
| void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); | |
| void ReadPackInfo(CFolders &f); | |
| void ReadUnpackInfo( | |
| const CObjectVector<CByteBuffer> *dataVector, | |
| CFolders &folders); | |
| void ReadSubStreamsInfo( | |
| CFolders &folders, | |
| CRecordVector<UInt64> &unpackSizes, | |
| CUInt32DefVector &digests); | |
| void ReadStreamsInfo( | |
| const CObjectVector<CByteBuffer> *dataVector, | |
| UInt64 &dataOffset, | |
| CFolders &folders, | |
| CRecordVector<UInt64> &unpackSizes, | |
| CUInt32DefVector &digests); | |
| void ReadBoolVector(unsigned numItems, CBoolVector &v); | |
| void ReadBoolVector2(unsigned numItems, CBoolVector &v); | |
| void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, | |
| CUInt64DefVector &v, unsigned numItems); | |
| HRESULT ReadAndDecodePackedStreams( | |
| DECL_EXTERNAL_CODECS_LOC_VARS | |
| UInt64 baseOffset, UInt64 &dataOffset, | |
| CObjectVector<CByteBuffer> &dataVector | |
| _7Z_DECODER_CRYPRO_VARS_DECL | |
| ); | |
| HRESULT ReadHeader( | |
| DECL_EXTERNAL_CODECS_LOC_VARS | |
| CDbEx &db | |
| _7Z_DECODER_CRYPRO_VARS_DECL | |
| ); | |
| HRESULT ReadDatabase2( | |
| DECL_EXTERNAL_CODECS_LOC_VARS | |
| CDbEx &db | |
| _7Z_DECODER_CRYPRO_VARS_DECL | |
| ); | |
| public: | |
| CInArchive(): _numInByteBufs(0) { } | |
| HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive | |
| void Close(); | |
| HRESULT ReadDatabase( | |
| DECL_EXTERNAL_CODECS_LOC_VARS | |
| CDbEx &db | |
| _7Z_DECODER_CRYPRO_VARS_DECL | |
| ); | |
| }; | |
| }} | |
| #endif |