1370b324cSopenharmony_ci// 7zOut.h 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci#ifndef ZIP7_INC_7Z_OUT_H 4370b324cSopenharmony_ci#define ZIP7_INC_7Z_OUT_H 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci#include "7zCompressionMode.h" 7370b324cSopenharmony_ci#include "7zEncode.h" 8370b324cSopenharmony_ci#include "7zHeader.h" 9370b324cSopenharmony_ci#include "7zItem.h" 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#include "../../Common/OutBuffer.h" 12370b324cSopenharmony_ci#include "../../Common/StreamUtils.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_cinamespace NArchive { 15370b324cSopenharmony_cinamespace N7z { 16370b324cSopenharmony_ci 17370b324cSopenharmony_ciconst unsigned k_StartHeadersRewriteSize = 32; 18370b324cSopenharmony_ci 19370b324cSopenharmony_ciclass CWriteBufferLoc 20370b324cSopenharmony_ci{ 21370b324cSopenharmony_ci Byte *_data; 22370b324cSopenharmony_ci size_t _size; 23370b324cSopenharmony_ci size_t _pos; 24370b324cSopenharmony_cipublic: 25370b324cSopenharmony_ci CWriteBufferLoc(): _size(0), _pos(0) {} 26370b324cSopenharmony_ci void Init(Byte *data, size_t size) 27370b324cSopenharmony_ci { 28370b324cSopenharmony_ci _data = data; 29370b324cSopenharmony_ci _size = size; 30370b324cSopenharmony_ci _pos = 0; 31370b324cSopenharmony_ci } 32370b324cSopenharmony_ci void WriteBytes(const void *data, size_t size) 33370b324cSopenharmony_ci { 34370b324cSopenharmony_ci if (size == 0) 35370b324cSopenharmony_ci return; 36370b324cSopenharmony_ci if (size > _size - _pos) 37370b324cSopenharmony_ci throw 1; 38370b324cSopenharmony_ci memcpy(_data + _pos, data, size); 39370b324cSopenharmony_ci _pos += size; 40370b324cSopenharmony_ci } 41370b324cSopenharmony_ci void WriteByte(Byte b) 42370b324cSopenharmony_ci { 43370b324cSopenharmony_ci if (_size == _pos) 44370b324cSopenharmony_ci throw 1; 45370b324cSopenharmony_ci _data[_pos++] = b; 46370b324cSopenharmony_ci } 47370b324cSopenharmony_ci size_t GetPos() const { return _pos; } 48370b324cSopenharmony_ci}; 49370b324cSopenharmony_ci 50370b324cSopenharmony_ci 51370b324cSopenharmony_cistruct CHeaderOptions 52370b324cSopenharmony_ci{ 53370b324cSopenharmony_ci bool CompressMainHeader; 54370b324cSopenharmony_ci /* 55370b324cSopenharmony_ci bool WriteCTime; 56370b324cSopenharmony_ci bool WriteATime; 57370b324cSopenharmony_ci bool WriteMTime; 58370b324cSopenharmony_ci */ 59370b324cSopenharmony_ci 60370b324cSopenharmony_ci CHeaderOptions(): 61370b324cSopenharmony_ci CompressMainHeader(true) 62370b324cSopenharmony_ci /* 63370b324cSopenharmony_ci , WriteCTime(false) 64370b324cSopenharmony_ci , WriteATime(false) 65370b324cSopenharmony_ci , WriteMTime(true) 66370b324cSopenharmony_ci */ 67370b324cSopenharmony_ci {} 68370b324cSopenharmony_ci}; 69370b324cSopenharmony_ci 70370b324cSopenharmony_ci 71370b324cSopenharmony_cistruct CFileItem2 72370b324cSopenharmony_ci{ 73370b324cSopenharmony_ci UInt64 CTime; 74370b324cSopenharmony_ci UInt64 ATime; 75370b324cSopenharmony_ci UInt64 MTime; 76370b324cSopenharmony_ci UInt64 StartPos; 77370b324cSopenharmony_ci UInt32 Attrib; 78370b324cSopenharmony_ci 79370b324cSopenharmony_ci bool CTimeDefined; 80370b324cSopenharmony_ci bool ATimeDefined; 81370b324cSopenharmony_ci bool MTimeDefined; 82370b324cSopenharmony_ci bool StartPosDefined; 83370b324cSopenharmony_ci bool AttribDefined; 84370b324cSopenharmony_ci bool IsAnti; 85370b324cSopenharmony_ci // bool IsAux; 86370b324cSopenharmony_ci 87370b324cSopenharmony_ci /* 88370b324cSopenharmony_ci void Init() 89370b324cSopenharmony_ci { 90370b324cSopenharmony_ci CTimeDefined = false; 91370b324cSopenharmony_ci ATimeDefined = false; 92370b324cSopenharmony_ci MTimeDefined = false; 93370b324cSopenharmony_ci StartPosDefined = false; 94370b324cSopenharmony_ci AttribDefined = false; 95370b324cSopenharmony_ci IsAnti = false; 96370b324cSopenharmony_ci // IsAux = false; 97370b324cSopenharmony_ci } 98370b324cSopenharmony_ci */ 99370b324cSopenharmony_ci}; 100370b324cSopenharmony_ci 101370b324cSopenharmony_ci 102370b324cSopenharmony_cistruct COutFolders 103370b324cSopenharmony_ci{ 104370b324cSopenharmony_ci CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only. 105370b324cSopenharmony_ci 106370b324cSopenharmony_ci CRecordVector<CNum> NumUnpackStreamsVector; 107370b324cSopenharmony_ci CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders 108370b324cSopenharmony_ci 109370b324cSopenharmony_ci void OutFoldersClear() 110370b324cSopenharmony_ci { 111370b324cSopenharmony_ci FolderUnpackCRCs.Clear(); 112370b324cSopenharmony_ci NumUnpackStreamsVector.Clear(); 113370b324cSopenharmony_ci CoderUnpackSizes.Clear(); 114370b324cSopenharmony_ci } 115370b324cSopenharmony_ci 116370b324cSopenharmony_ci void OutFoldersReserveDown() 117370b324cSopenharmony_ci { 118370b324cSopenharmony_ci FolderUnpackCRCs.ReserveDown(); 119370b324cSopenharmony_ci NumUnpackStreamsVector.ReserveDown(); 120370b324cSopenharmony_ci CoderUnpackSizes.ReserveDown(); 121370b324cSopenharmony_ci } 122370b324cSopenharmony_ci}; 123370b324cSopenharmony_ci 124370b324cSopenharmony_ci 125370b324cSopenharmony_cistruct CArchiveDatabaseOut: public COutFolders 126370b324cSopenharmony_ci{ 127370b324cSopenharmony_ci CRecordVector<UInt64> PackSizes; 128370b324cSopenharmony_ci CUInt32DefVector PackCRCs; 129370b324cSopenharmony_ci CObjectVector<CFolder> Folders; 130370b324cSopenharmony_ci 131370b324cSopenharmony_ci CRecordVector<CFileItem> Files; 132370b324cSopenharmony_ci UStringVector Names; 133370b324cSopenharmony_ci CUInt64DefVector CTime; 134370b324cSopenharmony_ci CUInt64DefVector ATime; 135370b324cSopenharmony_ci CUInt64DefVector MTime; 136370b324cSopenharmony_ci CUInt64DefVector StartPos; 137370b324cSopenharmony_ci CUInt32DefVector Attrib; 138370b324cSopenharmony_ci CBoolVector IsAnti; 139370b324cSopenharmony_ci 140370b324cSopenharmony_ci /* 141370b324cSopenharmony_ci CBoolVector IsAux; 142370b324cSopenharmony_ci 143370b324cSopenharmony_ci CByteBuffer SecureBuf; 144370b324cSopenharmony_ci CRecordVector<UInt32> SecureSizes; 145370b324cSopenharmony_ci CRecordVector<UInt32> SecureIDs; 146370b324cSopenharmony_ci 147370b324cSopenharmony_ci void ClearSecure() 148370b324cSopenharmony_ci { 149370b324cSopenharmony_ci SecureBuf.Free(); 150370b324cSopenharmony_ci SecureSizes.Clear(); 151370b324cSopenharmony_ci SecureIDs.Clear(); 152370b324cSopenharmony_ci } 153370b324cSopenharmony_ci */ 154370b324cSopenharmony_ci 155370b324cSopenharmony_ci void Clear() 156370b324cSopenharmony_ci { 157370b324cSopenharmony_ci OutFoldersClear(); 158370b324cSopenharmony_ci 159370b324cSopenharmony_ci PackSizes.Clear(); 160370b324cSopenharmony_ci PackCRCs.Clear(); 161370b324cSopenharmony_ci Folders.Clear(); 162370b324cSopenharmony_ci 163370b324cSopenharmony_ci Files.Clear(); 164370b324cSopenharmony_ci Names.Clear(); 165370b324cSopenharmony_ci CTime.Clear(); 166370b324cSopenharmony_ci ATime.Clear(); 167370b324cSopenharmony_ci MTime.Clear(); 168370b324cSopenharmony_ci StartPos.Clear(); 169370b324cSopenharmony_ci Attrib.Clear(); 170370b324cSopenharmony_ci IsAnti.Clear(); 171370b324cSopenharmony_ci 172370b324cSopenharmony_ci /* 173370b324cSopenharmony_ci IsAux.Clear(); 174370b324cSopenharmony_ci ClearSecure(); 175370b324cSopenharmony_ci */ 176370b324cSopenharmony_ci } 177370b324cSopenharmony_ci 178370b324cSopenharmony_ci void ReserveDown() 179370b324cSopenharmony_ci { 180370b324cSopenharmony_ci OutFoldersReserveDown(); 181370b324cSopenharmony_ci 182370b324cSopenharmony_ci PackSizes.ReserveDown(); 183370b324cSopenharmony_ci PackCRCs.ReserveDown(); 184370b324cSopenharmony_ci Folders.ReserveDown(); 185370b324cSopenharmony_ci 186370b324cSopenharmony_ci Files.ReserveDown(); 187370b324cSopenharmony_ci Names.ReserveDown(); 188370b324cSopenharmony_ci CTime.ReserveDown(); 189370b324cSopenharmony_ci ATime.ReserveDown(); 190370b324cSopenharmony_ci MTime.ReserveDown(); 191370b324cSopenharmony_ci StartPos.ReserveDown(); 192370b324cSopenharmony_ci Attrib.ReserveDown(); 193370b324cSopenharmony_ci IsAnti.ReserveDown(); 194370b324cSopenharmony_ci 195370b324cSopenharmony_ci /* 196370b324cSopenharmony_ci IsAux.ReserveDown(); 197370b324cSopenharmony_ci */ 198370b324cSopenharmony_ci } 199370b324cSopenharmony_ci 200370b324cSopenharmony_ci bool IsEmpty() const 201370b324cSopenharmony_ci { 202370b324cSopenharmony_ci return ( 203370b324cSopenharmony_ci PackSizes.IsEmpty() && 204370b324cSopenharmony_ci NumUnpackStreamsVector.IsEmpty() && 205370b324cSopenharmony_ci Folders.IsEmpty() && 206370b324cSopenharmony_ci Files.IsEmpty()); 207370b324cSopenharmony_ci } 208370b324cSopenharmony_ci 209370b324cSopenharmony_ci bool CheckNumFiles() const 210370b324cSopenharmony_ci { 211370b324cSopenharmony_ci unsigned size = Files.Size(); 212370b324cSopenharmony_ci return ( 213370b324cSopenharmony_ci CTime.CheckSize(size) 214370b324cSopenharmony_ci && ATime.CheckSize(size) 215370b324cSopenharmony_ci && MTime.CheckSize(size) 216370b324cSopenharmony_ci && StartPos.CheckSize(size) 217370b324cSopenharmony_ci && Attrib.CheckSize(size) 218370b324cSopenharmony_ci && (size == IsAnti.Size() || IsAnti.Size() == 0)); 219370b324cSopenharmony_ci } 220370b324cSopenharmony_ci 221370b324cSopenharmony_ci bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } 222370b324cSopenharmony_ci // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } 223370b324cSopenharmony_ci 224370b324cSopenharmony_ci void SetItem_Anti(unsigned index, bool isAnti) 225370b324cSopenharmony_ci { 226370b324cSopenharmony_ci while (index >= IsAnti.Size()) 227370b324cSopenharmony_ci IsAnti.Add(false); 228370b324cSopenharmony_ci IsAnti[index] = isAnti; 229370b324cSopenharmony_ci } 230370b324cSopenharmony_ci /* 231370b324cSopenharmony_ci void SetItem_Aux(unsigned index, bool isAux) 232370b324cSopenharmony_ci { 233370b324cSopenharmony_ci while (index >= IsAux.Size()) 234370b324cSopenharmony_ci IsAux.Add(false); 235370b324cSopenharmony_ci IsAux[index] = isAux; 236370b324cSopenharmony_ci } 237370b324cSopenharmony_ci */ 238370b324cSopenharmony_ci 239370b324cSopenharmony_ci void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name); 240370b324cSopenharmony_ci}; 241370b324cSopenharmony_ci 242370b324cSopenharmony_ci 243370b324cSopenharmony_ciclass COutArchive 244370b324cSopenharmony_ci{ 245370b324cSopenharmony_ci HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); } 246370b324cSopenharmony_ci 247370b324cSopenharmony_ci UInt64 GetPos() const; 248370b324cSopenharmony_ci void WriteBytes(const void *data, size_t size); 249370b324cSopenharmony_ci void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); } 250370b324cSopenharmony_ci void WriteByte(Byte b); 251370b324cSopenharmony_ci void WriteUInt32(UInt32 value); 252370b324cSopenharmony_ci void WriteUInt64(UInt64 value); 253370b324cSopenharmony_ci void WriteNumber(UInt64 value); 254370b324cSopenharmony_ci void WriteID(UInt64 value) { WriteNumber(value); } 255370b324cSopenharmony_ci 256370b324cSopenharmony_ci void WriteFolder(const CFolder &folder); 257370b324cSopenharmony_ci HRESULT WriteFileHeader(const CFileItem &itemInfo); 258370b324cSopenharmony_ci void WriteBoolVector(const CBoolVector &boolVector); 259370b324cSopenharmony_ci void WritePropBoolVector(Byte id, const CBoolVector &boolVector); 260370b324cSopenharmony_ci 261370b324cSopenharmony_ci void WriteHashDigests(const CUInt32DefVector &digests); 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci void WritePackInfo( 264370b324cSopenharmony_ci UInt64 dataOffset, 265370b324cSopenharmony_ci const CRecordVector<UInt64> &packSizes, 266370b324cSopenharmony_ci const CUInt32DefVector &packCRCs); 267370b324cSopenharmony_ci 268370b324cSopenharmony_ci void WriteUnpackInfo( 269370b324cSopenharmony_ci const CObjectVector<CFolder> &folders, 270370b324cSopenharmony_ci const COutFolders &outFolders); 271370b324cSopenharmony_ci 272370b324cSopenharmony_ci void WriteSubStreamsInfo( 273370b324cSopenharmony_ci const CObjectVector<CFolder> &folders, 274370b324cSopenharmony_ci const COutFolders &outFolders, 275370b324cSopenharmony_ci const CRecordVector<UInt64> &unpackSizes, 276370b324cSopenharmony_ci const CUInt32DefVector &digests); 277370b324cSopenharmony_ci 278370b324cSopenharmony_ci void SkipToAligned(unsigned pos, unsigned alignShifts); 279370b324cSopenharmony_ci void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts); 280370b324cSopenharmony_ci void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); 281370b324cSopenharmony_ci 282370b324cSopenharmony_ci HRESULT EncodeStream( 283370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 284370b324cSopenharmony_ci CEncoder &encoder, const CByteBuffer &data, 285370b324cSopenharmony_ci CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders); 286370b324cSopenharmony_ci void WriteHeader( 287370b324cSopenharmony_ci const CArchiveDatabaseOut &db, 288370b324cSopenharmony_ci // const CHeaderOptions &headerOptions, 289370b324cSopenharmony_ci UInt64 &headerOffset); 290370b324cSopenharmony_ci 291370b324cSopenharmony_ci bool _countMode; 292370b324cSopenharmony_ci bool _writeToStream; 293370b324cSopenharmony_ci bool _useAlign; 294370b324cSopenharmony_ci #ifdef Z7_7Z_VOL 295370b324cSopenharmony_ci bool _endMarker; 296370b324cSopenharmony_ci #endif 297370b324cSopenharmony_ci UInt32 _crc; 298370b324cSopenharmony_ci size_t _countSize; 299370b324cSopenharmony_ci CWriteBufferLoc _outByte2; 300370b324cSopenharmony_ci COutBuffer _outByte; 301370b324cSopenharmony_ci UInt64 _signatureHeaderPos; 302370b324cSopenharmony_ci CMyComPtr<IOutStream> Stream; 303370b324cSopenharmony_ci 304370b324cSopenharmony_ci #ifdef Z7_7Z_VOL 305370b324cSopenharmony_ci HRESULT WriteFinishSignature(); 306370b324cSopenharmony_ci HRESULT WriteFinishHeader(const CFinishHeader &h); 307370b324cSopenharmony_ci #endif 308370b324cSopenharmony_ci HRESULT WriteStartHeader(const CStartHeader &h); 309370b324cSopenharmony_ci 310370b324cSopenharmony_cipublic: 311370b324cSopenharmony_ci CMyComPtr<ISequentialOutStream> SeqStream; 312370b324cSopenharmony_ci 313370b324cSopenharmony_ci COutArchive() { _outByte.Create(1 << 16); } 314370b324cSopenharmony_ci HRESULT Create_and_WriteStartPrefix(ISequentialOutStream *stream /* , bool endMarker */); 315370b324cSopenharmony_ci void Close(); 316370b324cSopenharmony_ci HRESULT WriteDatabase( 317370b324cSopenharmony_ci DECL_EXTERNAL_CODECS_LOC_VARS 318370b324cSopenharmony_ci const CArchiveDatabaseOut &db, 319370b324cSopenharmony_ci const CCompressionMethodMode *options, 320370b324cSopenharmony_ci const CHeaderOptions &headerOptions); 321370b324cSopenharmony_ci 322370b324cSopenharmony_ci #ifdef Z7_7Z_VOL 323370b324cSopenharmony_ci static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); 324370b324cSopenharmony_ci static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); 325370b324cSopenharmony_ci #endif 326370b324cSopenharmony_ci}; 327370b324cSopenharmony_ci 328370b324cSopenharmony_ci}} 329370b324cSopenharmony_ci 330370b324cSopenharmony_ci#endif 331