1 // 7zIn.h 2 3 #ifndef __7Z_IN_H 4 #define __7Z_IN_H 5 6 #include "../../../Common/MyCom.h" 7 8 #include "../../IPassword.h" 9 #include "../../IStream.h" 10 11 #include "../../Common/CreateCoder.h" 12 #include "../../Common/InBuffer.h" 13 14 #include "7zItem.h" 15 16 namespace NArchive { 17 namespace N7z { 18 19 struct CInArchiveInfo 20 { 21 CArchiveVersion Version; 22 UInt64 StartPosition; 23 UInt64 StartPositionAfterHeader; 24 UInt64 DataStartPosition; 25 UInt64 DataStartPosition2; 26 CRecordVector<UInt64> FileInfoPopIDs; 27 void Clear() 28 { 29 FileInfoPopIDs.Clear(); 30 } 31 }; 32 33 struct CArchiveDatabaseEx: public CArchiveDatabase 34 { 35 CInArchiveInfo ArchiveInfo; 36 CRecordVector<UInt64> PackStreamStartPositions; 37 CRecordVector<CNum> FolderStartPackStreamIndex; 38 CRecordVector<CNum> FolderStartFileIndex; 39 CRecordVector<CNum> FileIndexToFolderIndexMap; 40 41 UInt64 HeadersSize; 42 UInt64 PhySize; 43 44 void Clear() 45 { 46 CArchiveDatabase::Clear(); 47 ArchiveInfo.Clear(); 48 PackStreamStartPositions.Clear(); 49 FolderStartPackStreamIndex.Clear(); 50 FolderStartFileIndex.Clear(); 51 FileIndexToFolderIndexMap.Clear(); 52 53 HeadersSize = 0; 54 PhySize = 0; 55 } 56 57 void FillFolderStartPackStream(); 58 void FillStartPos(); 59 void FillFolderStartFileIndex(); 60 61 void Fill() 62 { 63 FillFolderStartPackStream(); 64 FillStartPos(); 65 FillFolderStartFileIndex(); 66 } 67 68 UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const 69 { 70 return ArchiveInfo.DataStartPosition + 71 PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder]; 72 } 73 74 UInt64 GetFolderFullPackSize(int folderIndex) const 75 { 76 CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; 77 const CFolder &folder = Folders[folderIndex]; 78 UInt64 size = 0; 79 for (int i = 0; i < folder.PackStreams.Size(); i++) 80 size += PackSizes[packStreamIndex + i]; 81 return size; 82 } 83 84 UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const 85 { 86 return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; 87 } 88 89 UInt64 GetFilePackSize(CNum fileIndex) const 90 { 91 CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; 92 if (folderIndex != kNumNoIndex) 93 if (FolderStartFileIndex[folderIndex] == fileIndex) 94 return GetFolderFullPackSize(folderIndex); 95 return 0; 96 } 97 }; 98 99 class CInByte2 100 { 101 const Byte *_buffer; 102 size_t _size; 103 public: 104 size_t _pos; 105 void Init(const Byte *buffer, size_t size) 106 { 107 _buffer = buffer; 108 _size = size; 109 _pos = 0; 110 } 111 Byte ReadByte(); 112 void ReadBytes(Byte *data, size_t size); 113 void SkipData(UInt64 size); 114 void SkipData(); 115 UInt64 ReadNumber(); 116 CNum ReadNum(); 117 UInt32 ReadUInt32(); 118 UInt64 ReadUInt64(); 119 void ReadString(UString &s); 120 }; 121 122 class CStreamSwitch; 123 124 const UInt32 kHeaderSize = 32; 125 126 class CInArchive 127 { 128 friend class CStreamSwitch; 129 130 CMyComPtr<IInStream> _stream; 131 132 CObjectVector<CInByte2> _inByteVector; 133 CInByte2 *_inByteBack; 134 135 UInt64 _arhiveBeginStreamPosition; 136 137 Byte _header[kHeaderSize]; 138 139 UInt64 HeadersSize; 140 141 void AddByteStream(const Byte *buffer, size_t size) 142 { 143 _inByteVector.Add(CInByte2()); 144 _inByteBack = &_inByteVector.Back(); 145 _inByteBack->Init(buffer, size); 146 } 147 148 void DeleteByteStream() 149 { 150 _inByteVector.DeleteBack(); 151 if (!_inByteVector.IsEmpty()) 152 _inByteBack = &_inByteVector.Back(); 153 } 154 155 private: 156 HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); 157 158 void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } 159 Byte ReadByte() { return _inByteBack->ReadByte(); } 160 UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } 161 CNum ReadNum() { return _inByteBack->ReadNum(); } 162 UInt64 ReadID() { return _inByteBack->ReadNumber(); } 163 UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } 164 UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } 165 void SkipData(UInt64 size) { _inByteBack->SkipData(size); } 166 void SkipData() { _inByteBack->SkipData(); } 167 void WaitAttribute(UInt64 attribute); 168 169 void ReadArchiveProperties(CInArchiveInfo &archiveInfo); 170 void GetNextFolderItem(CFolder &itemInfo); 171 void ReadHashDigests(int numItems, 172 CBoolVector &digestsDefined, CRecordVector<UInt32> &digests); 173 174 void ReadPackInfo( 175 UInt64 &dataOffset, 176 CRecordVector<UInt64> &packSizes, 177 CBoolVector &packCRCsDefined, 178 CRecordVector<UInt32> &packCRCs); 179 180 void ReadUnpackInfo( 181 const CObjectVector<CByteBuffer> *dataVector, 182 CObjectVector<CFolder> &folders); 183 184 void ReadSubStreamsInfo( 185 const CObjectVector<CFolder> &folders, 186 CRecordVector<CNum> &numUnpackStreamsInFolders, 187 CRecordVector<UInt64> &unpackSizes, 188 CBoolVector &digestsDefined, 189 CRecordVector<UInt32> &digests); 190 191 void ReadStreamsInfo( 192 const CObjectVector<CByteBuffer> *dataVector, 193 UInt64 &dataOffset, 194 CRecordVector<UInt64> &packSizes, 195 CBoolVector &packCRCsDefined, 196 CRecordVector<UInt32> &packCRCs, 197 CObjectVector<CFolder> &folders, 198 CRecordVector<CNum> &numUnpackStreamsInFolders, 199 CRecordVector<UInt64> &unpackSizes, 200 CBoolVector &digestsDefined, 201 CRecordVector<UInt32> &digests); 202 203 204 void ReadBoolVector(int numItems, CBoolVector &v); 205 void ReadBoolVector2(int numItems, CBoolVector &v); 206 void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, 207 CUInt64DefVector &v, int numFiles); 208 HRESULT ReadAndDecodePackedStreams( 209 DECL_EXTERNAL_CODECS_LOC_VARS 210 UInt64 baseOffset, UInt64 &dataOffset, 211 CObjectVector<CByteBuffer> &dataVector 212 #ifndef _NO_CRYPTO 213 , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined 214 #endif 215 ); 216 HRESULT ReadHeader( 217 DECL_EXTERNAL_CODECS_LOC_VARS 218 CArchiveDatabaseEx &db 219 #ifndef _NO_CRYPTO 220 ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined 221 #endif 222 ); 223 HRESULT ReadDatabase2( 224 DECL_EXTERNAL_CODECS_LOC_VARS 225 CArchiveDatabaseEx &db 226 #ifndef _NO_CRYPTO 227 ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined 228 #endif 229 ); 230 public: 231 HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive 232 void Close(); 233 234 HRESULT ReadDatabase( 235 DECL_EXTERNAL_CODECS_LOC_VARS 236 CArchiveDatabaseEx &db 237 #ifndef _NO_CRYPTO 238 ,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined 239 #endif 240 ); 241 }; 242 243 }} 244 245 #endif 246