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