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