xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/7z/7zOut.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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