1 // 7zOut.h 2 3 #ifndef __7Z_OUT_H 4 #define __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 13 namespace NArchive { 14 namespace N7z { 15 16 class CWriteBufferLoc 17 { 18 Byte *_data; 19 size_t _size; 20 size_t _pos; 21 public: 22 CWriteBufferLoc(): _size(0), _pos(0) {} 23 void Init(Byte *data, size_t size) 24 { 25 _data = data; 26 _size = size; 27 _pos = 0; 28 } 29 void WriteBytes(const void *data, size_t size) 30 { 31 if (size > _size - _pos) 32 throw 1; 33 memcpy(_data + _pos, data, size); 34 _pos += size; 35 } 36 void WriteByte(Byte b) 37 { 38 if (_size == _pos) 39 throw 1; 40 _data[_pos++] = b; 41 } 42 size_t GetPos() const { return _pos; } 43 }; 44 45 struct CHeaderOptions 46 { 47 bool CompressMainHeader; 48 bool WriteCTime; 49 bool WriteATime; 50 bool WriteMTime; 51 52 CHeaderOptions(): 53 CompressMainHeader(true), 54 WriteCTime(false), 55 WriteATime(false), 56 WriteMTime(true) 57 {} 58 }; 59 60 class COutArchive 61 { 62 UInt64 _prefixHeaderPos; 63 64 HRESULT WriteDirect(const void *data, UInt32 size); 65 66 UInt64 GetPos() const; 67 void WriteBytes(const void *data, size_t size); 68 void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); } 69 void WriteByte(Byte b); 70 void WriteUInt32(UInt32 value); 71 void WriteUInt64(UInt64 value); 72 void WriteNumber(UInt64 value); 73 void WriteID(UInt64 value) { WriteNumber(value); } 74 75 void WriteFolder(const CFolder &folder); 76 HRESULT WriteFileHeader(const CFileItem &itemInfo); 77 void WriteBoolVector(const CBoolVector &boolVector); 78 void WriteHashDigests( 79 const CRecordVector<bool> &digestsDefined, 80 const CRecordVector<UInt32> &hashDigests); 81 82 void WritePackInfo( 83 UInt64 dataOffset, 84 const CRecordVector<UInt64> &packSizes, 85 const CRecordVector<bool> &packCRCsDefined, 86 const CRecordVector<UInt32> &packCRCs); 87 88 void WriteUnpackInfo(const CObjectVector<CFolder> &folders); 89 90 void WriteSubStreamsInfo( 91 const CObjectVector<CFolder> &folders, 92 const CRecordVector<CNum> &numUnpackStreamsInFolders, 93 const CRecordVector<UInt64> &unpackSizes, 94 const CRecordVector<bool> &digestsDefined, 95 const CRecordVector<UInt32> &hashDigests); 96 97 void SkipAlign(unsigned pos, unsigned alignSize); 98 void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize); 99 void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type); 100 101 HRESULT EncodeStream( 102 DECL_EXTERNAL_CODECS_LOC_VARS 103 CEncoder &encoder, const CByteBuffer &data, 104 CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders); 105 void WriteHeader( 106 const CArchiveDatabase &db, 107 const CHeaderOptions &headerOptions, 108 UInt64 &headerOffset); 109 110 bool _countMode; 111 bool _writeToStream; 112 size_t _countSize; 113 UInt32 _crc; 114 COutBuffer _outByte; 115 CWriteBufferLoc _outByte2; 116 117 #ifdef _7Z_VOL 118 bool _endMarker; 119 #endif 120 121 HRESULT WriteSignature(); 122 #ifdef _7Z_VOL 123 HRESULT WriteFinishSignature(); 124 #endif 125 HRESULT WriteStartHeader(const CStartHeader &h); 126 #ifdef _7Z_VOL 127 HRESULT WriteFinishHeader(const CFinishHeader &h); 128 #endif 129 CMyComPtr<IOutStream> Stream; 130 public: 131 132 COutArchive() { _outByte.Create(1 << 16); } 133 CMyComPtr<ISequentialOutStream> SeqStream; 134 HRESULT Create(ISequentialOutStream *stream, bool endMarker); 135 void Close(); 136 HRESULT SkipPrefixArchiveHeader(); 137 HRESULT WriteDatabase( 138 DECL_EXTERNAL_CODECS_LOC_VARS 139 const CArchiveDatabase &db, 140 const CCompressionMethodMode *options, 141 const CHeaderOptions &headerOptions); 142 143 #ifdef _7Z_VOL 144 static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false); 145 static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false); 146 #endif 147 148 }; 149 150 }} 151 152 #endif 153