1 // 7zOut.h 2 3 #ifndef ZIP7_INC_7Z_OUT_H 4 #define ZIP7_INC_7Z_OUT_H 5 6 #include "7zCompressionMode.h" 7 #include "7zEncode.h" 8 #include "7zHeader.h" 9 #include "7zItem.h" 10 11 #include "../../Common/OutBuffer.h" 12 #include "../../Common/StreamUtils.h" 13 14 namespace NArchive { 15 namespace N7z { 16 17 const unsigned k_StartHeadersRewriteSize = 32; 18 19 class CWriteBufferLoc 20 { 21 Byte *_data; 22 Byte *_dataLim; 23 Byte *_dataBase; 24 public: 25 // CWriteBufferLoc(): _data(NULL), _dataLim(NULL), _dataBase(NULL) {} Init(Byte * data,size_t size)26 void Init(Byte *data, size_t size) 27 { 28 _data = data; 29 _dataBase = data; 30 _dataLim = data + size; 31 } 32 GetDest_and_Update(size_t size)33 Byte *GetDest_and_Update(size_t size) 34 { 35 Byte *dest = _data; 36 if (size > (size_t)(_dataLim - dest)) 37 throw 1; 38 _data = dest + size; 39 return dest; 40 } WriteBytes(const void * data,size_t size)41 void WriteBytes(const void *data, size_t size) 42 { 43 if (size == 0) 44 return; 45 Byte *dest = GetDest_and_Update(size); 46 memcpy(dest, data, size); 47 } WriteByte(Byte b)48 void WriteByte(Byte b) 49 { 50 Byte *dest = _data; 51 if (dest == _dataLim) 52 throw 1; 53 *dest++ = b; 54 _data = dest; 55 } GetPos()56 size_t GetPos() const { return (size_t)(_data - _dataBase); } 57 }; 58 59 60 struct CHeaderOptions 61 { 62 bool CompressMainHeader; 63 /* 64 bool WriteCTime; 65 bool WriteATime; 66 bool WriteMTime; 67 */ 68 CHeaderOptionsCHeaderOptions69 CHeaderOptions(): 70 CompressMainHeader(true) 71 /* 72 , WriteCTime(false) 73 , WriteATime(false) 74 , WriteMTime(true) 75 */ 76 {} 77 }; 78 79 80 struct CFileItem2 81 { 82 UInt64 CTime; 83 UInt64 ATime; 84 UInt64 MTime; 85 UInt64 StartPos; 86 UInt32 Attrib; 87 88 bool CTimeDefined; 89 bool ATimeDefined; 90 bool MTimeDefined; 91 bool StartPosDefined; 92 bool AttribDefined; 93 bool IsAnti; 94 // bool IsAux; 95 96 /* 97 void Init() 98 { 99 CTimeDefined = false; 100 ATimeDefined = false; 101 MTimeDefined = false; 102 StartPosDefined = false; 103 AttribDefined = false; 104 IsAnti = false; 105 // IsAux = false; 106 } 107 */ 108 }; 109 110 111 struct COutFolders 112 { 113 CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only. 114 115 CRecordVector<CNum> NumUnpackStreamsVector; 116 CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders 117 OutFoldersClearCOutFolders118 void OutFoldersClear() 119 { 120 FolderUnpackCRCs.Clear(); 121 NumUnpackStreamsVector.Clear(); 122 CoderUnpackSizes.Clear(); 123 } 124 OutFoldersReserveDownCOutFolders125 void OutFoldersReserveDown() 126 { 127 FolderUnpackCRCs.ReserveDown(); 128 NumUnpackStreamsVector.ReserveDown(); 129 CoderUnpackSizes.ReserveDown(); 130 } 131 }; 132 133 134 struct CArchiveDatabaseOut: public COutFolders 135 { 136 CRecordVector<UInt64> PackSizes; 137 CUInt32DefVector PackCRCs; 138 CObjectVector<CFolder> Folders; 139 140 CRecordVector<CFileItem> Files; 141 UStringVector Names; 142 CUInt64DefVector CTime; 143 CUInt64DefVector ATime; 144 CUInt64DefVector MTime; 145 CUInt64DefVector StartPos; 146 CUInt32DefVector Attrib; 147 CBoolVector IsAnti; 148 149 /* 150 CBoolVector IsAux; 151 152 CByteBuffer SecureBuf; 153 CRecordVector<UInt32> SecureSizes; 154 CRecordVector<UInt32> SecureIDs; 155 156 void ClearSecure() 157 { 158 SecureBuf.Free(); 159 SecureSizes.Clear(); 160 SecureIDs.Clear(); 161 } 162 */ 163 ClearCArchiveDatabaseOut164 void Clear() 165 { 166 OutFoldersClear(); 167 168 PackSizes.Clear(); 169 PackCRCs.Clear(); 170 Folders.Clear(); 171 172 Files.Clear(); 173 Names.Clear(); 174 CTime.Clear(); 175 ATime.Clear(); 176 MTime.Clear(); 177 StartPos.Clear(); 178 Attrib.Clear(); 179 IsAnti.Clear(); 180 181 /* 182 IsAux.Clear(); 183 ClearSecure(); 184 */ 185 } 186 ReserveDownCArchiveDatabaseOut187 void ReserveDown() 188 { 189 OutFoldersReserveDown(); 190 191 PackSizes.ReserveDown(); 192 PackCRCs.ReserveDown(); 193 Folders.ReserveDown(); 194 195 Files.ReserveDown(); 196 Names.ReserveDown(); 197 CTime.ReserveDown(); 198 ATime.ReserveDown(); 199 MTime.ReserveDown(); 200 StartPos.ReserveDown(); 201 Attrib.ReserveDown(); 202 IsAnti.ReserveDown(); 203 204 /* 205 IsAux.ReserveDown(); 206 */ 207 } 208 IsEmptyCArchiveDatabaseOut209 bool IsEmpty() const 210 { 211 return ( 212 PackSizes.IsEmpty() && 213 NumUnpackStreamsVector.IsEmpty() && 214 Folders.IsEmpty() && 215 Files.IsEmpty()); 216 } 217 CheckNumFilesCArchiveDatabaseOut218 bool CheckNumFiles() const 219 { 220 unsigned size = Files.Size(); 221 return ( 222 CTime.CheckSize(size) 223 && ATime.CheckSize(size) 224 && MTime.CheckSize(size) 225 && StartPos.CheckSize(size) 226 && Attrib.CheckSize(size) 227 && (size == IsAnti.Size() || IsAnti.Size() == 0)); 228 } 229 IsItemAntiCArchiveDatabaseOut230 bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } 231 // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } 232 SetItem_AntiCArchiveDatabaseOut233 void SetItem_Anti(unsigned index, bool isAnti) 234 { 235 while (index >= IsAnti.Size()) 236 IsAnti.Add(false); 237 IsAnti[index] = isAnti; 238 } 239 /* 240 void SetItem_Aux(unsigned index, bool isAux) 241 { 242 while (index >= IsAux.Size()) 243 IsAux.Add(false); 244 IsAux[index] = isAux; 245 } 246 */ 247 248 void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name); 249 }; 250 251 252 class COutArchive 253 { WriteDirect(const void * data,UInt32 size)254 HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } 255 256 UInt64 GetPos() const; 257 void WriteBytes(const void *data, size_t size); WriteBytes(const CByteBuffer & data)258 void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); } 259 void WriteByte(Byte b); WriteByte_ToStream(Byte b)260 void WriteByte_ToStream(Byte b) 261 { 262 _outByte.WriteByte(b); 263 // _crc = CRC_UPDATE_BYTE(_crc, b); 264 } 265 // void WriteUInt32(UInt32 value); 266 // void WriteUInt64(UInt64 value); 267 void WriteNumber(UInt64 value); WriteID(UInt64 value)268 void WriteID(UInt64 value) { WriteNumber(value); } 269 270 void WriteFolder(const CFolder &folder); 271 HRESULT WriteFileHeader(const CFileItem &itemInfo); 272 void Write_BoolVector(const CBoolVector &boolVector); 273 void Write_BoolVector_numDefined(const CBoolVector &boolVector, unsigned numDefined); 274 void WritePropBoolVector(Byte id, const CBoolVector &boolVector); 275 276 void WriteHashDigests(const CUInt32DefVector &digests); 277 278 void WritePackInfo( 279 UInt64 dataOffset, 280 const CRecordVector<UInt64> &packSizes, 281 const CUInt32DefVector &packCRCs); 282 283 void WriteUnpackInfo( 284 const CObjectVector<CFolder> &folders, 285 const COutFolders &outFolders); 286 287 void WriteSubStreamsInfo( 288 const CObjectVector<CFolder> &folders, 289 const COutFolders &outFolders, 290 const CRecordVector<UInt64> &unpackSizes, 291 const CUInt32DefVector &digests); 292 293 void SkipToAligned(unsigned pos, unsigned alignShifts); 294 void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts); 295 void Write_UInt32DefVector_numDefined(const CUInt32DefVector &v, unsigned numDefined); 296 void Write_UInt64DefVector_type(const CUInt64DefVector &v, Byte type); 297 298 HRESULT EncodeStream( 299 DECL_EXTERNAL_CODECS_LOC_VARS 300 CEncoder &encoder, const CByteBuffer &data, 301 CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders); 302 void WriteHeader( 303 const CArchiveDatabaseOut &db, 304 // const CHeaderOptions &headerOptions, 305 UInt64 &headerOffset); 306 307 bool _countMode; 308 bool _writeToStream; 309 bool _useAlign; 310 #ifdef Z7_7Z_VOL 311 bool _endMarker; 312 #endif 313 // UInt32 _crc; 314 size_t _countSize; 315 CWriteBufferLoc _outByte2; 316 COutBuffer _outByte; 317 UInt64 _signatureHeaderPos; 318 CMyComPtr<IOutStream> Stream; 319 320 #ifdef Z7_7Z_VOL 321 HRESULT WriteFinishSignature(); 322 HRESULT WriteFinishHeader(const CFinishHeader &h); 323 #endif 324 HRESULT WriteStartHeader(const CStartHeader &h); 325 326 public: 327 CMyComPtr<ISequentialOutStream> SeqStream; 328 329 // COutArchive(); 330 HRESULT Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */); 331 void Close(); 332 HRESULT WriteDatabase( 333 DECL_EXTERNAL_CODECS_LOC_VARS 334 const CArchiveDatabaseOut &db, 335 const CCompressionMethodMode *options, 336 const CHeaderOptions &headerOptions); 337 338 #ifdef Z7_7Z_VOL 339 static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); 340 static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); 341 #endif 342 }; 343 344 }} 345 346 #endif 347