1 // 7zIn.h 2 3 #ifndef __7Z_IN_H 4 #define __7Z_IN_H 5 6 #include "../../IStream.h" 7 #include "../../IPassword.h" 8 #include "../../../Common/MyCom.h" 9 #include "../../Common/InBuffer.h" 10 11 #include "7zHeader.h" 12 #include "7zItem.h" 13 14 namespace NArchive { 15 namespace N7z { 16 17 class CInArchiveException 18 { 19 public: 20 enum CCauseType 21 { 22 kUnsupportedVersion = 0, 23 kUnexpectedEndOfArchive = 0, 24 kIncorrectHeader, 25 } Cause; 26 CInArchiveException(CCauseType cause); 27 }; 28 29 struct CInArchiveInfo 30 { 31 CArchiveVersion Version; 32 UInt64 StartPosition; 33 UInt64 StartPositionAfterHeader; 34 UInt64 DataStartPosition; 35 UInt64 DataStartPosition2; 36 CRecordVector<UInt64> FileInfoPopIDs; ClearCInArchiveInfo37 void Clear() 38 { 39 FileInfoPopIDs.Clear(); 40 } 41 }; 42 43 44 struct CArchiveDatabaseEx: public CArchiveDatabase 45 { 46 CInArchiveInfo ArchiveInfo; 47 CRecordVector<UInt64> PackStreamStartPositions; 48 CRecordVector<CNum> FolderStartPackStreamIndex; 49 CRecordVector<CNum> FolderStartFileIndex; 50 CRecordVector<CNum> FileIndexToFolderIndexMap; 51 ClearCArchiveDatabaseEx52 void Clear() 53 { 54 CArchiveDatabase::Clear(); 55 ArchiveInfo.Clear(); 56 PackStreamStartPositions.Clear(); 57 FolderStartPackStreamIndex.Clear(); 58 FolderStartFileIndex.Clear(); 59 FileIndexToFolderIndexMap.Clear(); 60 } 61 62 void FillFolderStartPackStream(); 63 void FillStartPos(); 64 void FillFolderStartFileIndex(); 65 FillCArchiveDatabaseEx66 void Fill() 67 { 68 FillFolderStartPackStream(); 69 FillStartPos(); 70 FillFolderStartFileIndex(); 71 } 72 GetFolderStreamPosCArchiveDatabaseEx73 UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const 74 { 75 return ArchiveInfo.DataStartPosition + 76 PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + 77 indexInFolder]; 78 } 79 GetFolderFullPackSizeCArchiveDatabaseEx80 UInt64 GetFolderFullPackSize(int folderIndex) const 81 { 82 CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex]; 83 const CFolder &folder = Folders[folderIndex]; 84 UInt64 size = 0; 85 for (int i = 0; i < folder.PackStreams.Size(); i++) 86 size += PackSizes[packStreamIndex + i]; 87 return size; 88 } 89 GetFolderPackStreamSizeCArchiveDatabaseEx90 UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const 91 { 92 return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; 93 } 94 GetFilePackSizeCArchiveDatabaseEx95 UInt64 GetFilePackSize(CNum fileIndex) const 96 { 97 CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; 98 if (folderIndex >= 0) 99 { 100 if (FolderStartFileIndex[folderIndex] == fileIndex) 101 return GetFolderFullPackSize(folderIndex); 102 } 103 return 0; 104 } 105 }; 106 107 class CInByte2 108 { 109 const Byte *_buffer; 110 size_t _size; 111 size_t _pos; 112 public: Init(const Byte * buffer,size_t size)113 void Init(const Byte *buffer, size_t size) 114 { 115 _buffer = buffer; 116 _size = size; 117 _pos = 0; 118 } ReadByte(Byte & b)119 bool ReadByte(Byte &b) 120 { 121 if(_pos >= _size) 122 return false; 123 b = _buffer[_pos++]; 124 return true; 125 } ReadBytes(void * data,size_t size,size_t & processedSize)126 void ReadBytes(void *data, size_t size, size_t &processedSize) 127 { 128 for(processedSize = 0; processedSize < size && _pos < _size; processedSize++) 129 ((Byte *)data)[processedSize] = _buffer[_pos++]; 130 } 131 ReadBytes(void * data,size_t size)132 bool ReadBytes(void *data, size_t size) 133 { 134 size_t processedSize; 135 ReadBytes(data, size, processedSize); 136 return (processedSize == size); 137 } 138 GetProcessedSize()139 size_t GetProcessedSize() const { return _pos; } 140 }; 141 142 class CStreamSwitch; 143 class CInArchive 144 { 145 friend class CStreamSwitch; 146 147 CMyComPtr<IInStream> _stream; 148 #ifdef _7Z_VOL 149 bool _finishSignature; 150 #endif 151 152 CObjectVector<CInByte2> _inByteVector; 153 CInByte2 *_inByteBack; 154 155 UInt64 _arhiveBeginStreamPosition; 156 UInt64 _position; 157 AddByteStream(const Byte * buffer,size_t size)158 void AddByteStream(const Byte *buffer, size_t size) 159 { 160 _inByteVector.Add(CInByte2()); 161 _inByteBack = &_inByteVector.Back(); 162 _inByteBack->Init(buffer, size); 163 } 164 DeleteByteStream()165 void DeleteByteStream() 166 { 167 _inByteVector.DeleteBack(); 168 if (!_inByteVector.IsEmpty()) 169 _inByteBack = &_inByteVector.Back(); 170 } 171 172 private: 173 HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive 174 #ifdef _7Z_VOL 175 HRESULT FindFinishSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive 176 #endif 177 178 HRESULT ReadFileNames(CObjectVector<CFileItem> &files); 179 180 HRESULT ReadDirect(IInStream *stream, void *data, UInt32 size, 181 UInt32 *processedSize); 182 HRESULT ReadDirect(void *data, UInt32 size, UInt32 *processedSize); 183 HRESULT SafeReadDirect(void *data, UInt32 size); 184 HRESULT SafeReadDirectByte(Byte &b); 185 HRESULT SafeReadDirectUInt32(UInt32 &value); 186 HRESULT SafeReadDirectUInt64(UInt64 &value); 187 ReadBytes(void * data,size_t size)188 HRESULT ReadBytes(void *data, size_t size) 189 { 190 if (!_inByteBack->ReadBytes(data, size)) 191 return E_FAIL; 192 return S_OK; 193 } 194 ReadByte(Byte & b)195 HRESULT ReadByte(Byte &b) 196 { 197 if (!_inByteBack->ReadByte(b)) 198 return E_FAIL; 199 return S_OK; 200 } 201 ReadWideCharLE(wchar_t & c)202 HRESULT ReadWideCharLE(wchar_t &c) 203 { 204 Byte b1; 205 if (!_inByteBack->ReadByte(b1)) 206 return E_FAIL; 207 Byte b2; 208 if (!_inByteBack->ReadByte(b2)) 209 return E_FAIL; 210 c = (wchar_t(b2) << 8) + b1; 211 return S_OK; 212 } 213 214 HRESULT ReadNumber(UInt64 &value); 215 HRESULT ReadNum(CNum &value); ReadID(UInt64 & value)216 HRESULT ReadID(UInt64 &value) { return ReadNumber(value); } 217 HRESULT ReadUInt32(UInt32 &value); 218 HRESULT ReadUInt64(UInt64 &value); 219 220 HRESULT SkeepData(UInt64 size); 221 HRESULT SkeepData(); 222 HRESULT WaitAttribute(UInt64 attribute); 223 224 HRESULT ReadArchiveProperties(CInArchiveInfo &archiveInfo); 225 HRESULT GetNextFolderItem(CFolder &itemInfo); 226 HRESULT ReadHashDigests(int numItems, 227 CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests); 228 229 HRESULT ReadPackInfo( 230 UInt64 &dataOffset, 231 CRecordVector<UInt64> &packSizes, 232 CRecordVector<bool> &packCRCsDefined, 233 CRecordVector<UInt32> &packCRCs); 234 235 HRESULT ReadUnPackInfo( 236 const CObjectVector<CByteBuffer> *dataVector, 237 CObjectVector<CFolder> &folders); 238 239 HRESULT ReadSubStreamsInfo( 240 const CObjectVector<CFolder> &folders, 241 CRecordVector<CNum> &numUnPackStreamsInFolders, 242 CRecordVector<UInt64> &unPackSizes, 243 CRecordVector<bool> &digestsDefined, 244 CRecordVector<UInt32> &digests); 245 246 HRESULT ReadStreamsInfo( 247 const CObjectVector<CByteBuffer> *dataVector, 248 UInt64 &dataOffset, 249 CRecordVector<UInt64> &packSizes, 250 CRecordVector<bool> &packCRCsDefined, 251 CRecordVector<UInt32> &packCRCs, 252 CObjectVector<CFolder> &folders, 253 CRecordVector<CNum> &numUnPackStreamsInFolders, 254 CRecordVector<UInt64> &unPackSizes, 255 CRecordVector<bool> &digestsDefined, 256 CRecordVector<UInt32> &digests); 257 258 259 HRESULT GetNextFileItem(CFileItem &itemInfo); 260 HRESULT ReadBoolVector(int numItems, CBoolVector &v); 261 HRESULT ReadBoolVector2(int numItems, CBoolVector &v); 262 HRESULT ReadTime(const CObjectVector<CByteBuffer> &dataVector, 263 CObjectVector<CFileItem> &files, UInt64 type); 264 HRESULT ReadAndDecodePackedStreams(UInt64 baseOffset, UInt64 &dataOffset, 265 CObjectVector<CByteBuffer> &dataVector 266 #ifndef _NO_CRYPTO 267 , ICryptoGetTextPassword *getTextPassword 268 #endif 269 ); 270 HRESULT ReadHeader(CArchiveDatabaseEx &database 271 #ifndef _NO_CRYPTO 272 ,ICryptoGetTextPassword *getTextPassword 273 #endif 274 ); 275 public: 276 HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive 277 void Close(); 278 279 HRESULT ReadDatabase(CArchiveDatabaseEx &database 280 #ifndef _NO_CRYPTO 281 ,ICryptoGetTextPassword *getTextPassword 282 #endif 283 ); 284 }; 285 286 }} 287 288 #endif 289