• 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 
49 struct CHeaderOptions
50 {
51   bool CompressMainHeader;
52   /*
53   bool WriteCTime;
54   bool WriteATime;
55   bool WriteMTime;
56   */
57 
CHeaderOptionsCHeaderOptions58   CHeaderOptions():
59       CompressMainHeader(true)
60       /*
61       , WriteCTime(false)
62       , WriteATime(false)
63       , WriteMTime(true)
64       */
65       {}
66 };
67 
68 
69 struct CFileItem2
70 {
71   UInt64 CTime;
72   UInt64 ATime;
73   UInt64 MTime;
74   UInt64 StartPos;
75   UInt32 Attrib;
76 
77   bool CTimeDefined;
78   bool ATimeDefined;
79   bool MTimeDefined;
80   bool StartPosDefined;
81   bool AttribDefined;
82   bool IsAnti;
83   // bool IsAux;
84 
85   /*
86   void Init()
87   {
88     CTimeDefined = false;
89     ATimeDefined = false;
90     MTimeDefined = false;
91     StartPosDefined = false;
92     AttribDefined = false;
93     IsAnti = false;
94     // IsAux = false;
95   }
96   */
97 };
98 
99 
100 struct COutFolders
101 {
102   CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
103 
104   CRecordVector<CNum> NumUnpackStreamsVector;
105   CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
106 
OutFoldersClearCOutFolders107   void OutFoldersClear()
108   {
109     FolderUnpackCRCs.Clear();
110     NumUnpackStreamsVector.Clear();
111     CoderUnpackSizes.Clear();
112   }
113 
OutFoldersReserveDownCOutFolders114   void OutFoldersReserveDown()
115   {
116     FolderUnpackCRCs.ReserveDown();
117     NumUnpackStreamsVector.ReserveDown();
118     CoderUnpackSizes.ReserveDown();
119   }
120 };
121 
122 
123 struct CArchiveDatabaseOut: public COutFolders
124 {
125   CRecordVector<UInt64> PackSizes;
126   CUInt32DefVector PackCRCs;
127   CObjectVector<CFolder> Folders;
128 
129   CRecordVector<CFileItem> Files;
130   UStringVector Names;
131   CUInt64DefVector CTime;
132   CUInt64DefVector ATime;
133   CUInt64DefVector MTime;
134   CUInt64DefVector StartPos;
135   CUInt32DefVector Attrib;
136   CBoolVector IsAnti;
137 
138   /*
139   CBoolVector IsAux;
140 
141   CByteBuffer SecureBuf;
142   CRecordVector<UInt32> SecureSizes;
143   CRecordVector<UInt32> SecureIDs;
144 
145   void ClearSecure()
146   {
147     SecureBuf.Free();
148     SecureSizes.Clear();
149     SecureIDs.Clear();
150   }
151   */
152 
ClearCArchiveDatabaseOut153   void Clear()
154   {
155     OutFoldersClear();
156 
157     PackSizes.Clear();
158     PackCRCs.Clear();
159     Folders.Clear();
160 
161     Files.Clear();
162     Names.Clear();
163     CTime.Clear();
164     ATime.Clear();
165     MTime.Clear();
166     StartPos.Clear();
167     Attrib.Clear();
168     IsAnti.Clear();
169 
170     /*
171     IsAux.Clear();
172     ClearSecure();
173     */
174   }
175 
ReserveDownCArchiveDatabaseOut176   void ReserveDown()
177   {
178     OutFoldersReserveDown();
179 
180     PackSizes.ReserveDown();
181     PackCRCs.ReserveDown();
182     Folders.ReserveDown();
183 
184     Files.ReserveDown();
185     Names.ReserveDown();
186     CTime.ReserveDown();
187     ATime.ReserveDown();
188     MTime.ReserveDown();
189     StartPos.ReserveDown();
190     Attrib.ReserveDown();
191     IsAnti.ReserveDown();
192 
193     /*
194     IsAux.ReserveDown();
195     */
196   }
197 
IsEmptyCArchiveDatabaseOut198   bool IsEmpty() const
199   {
200     return (
201       PackSizes.IsEmpty() &&
202       NumUnpackStreamsVector.IsEmpty() &&
203       Folders.IsEmpty() &&
204       Files.IsEmpty());
205   }
206 
CheckNumFilesCArchiveDatabaseOut207   bool CheckNumFiles() const
208   {
209     unsigned size = Files.Size();
210     return (
211            CTime.CheckSize(size)
212         && ATime.CheckSize(size)
213         && MTime.CheckSize(size)
214         && StartPos.CheckSize(size)
215         && Attrib.CheckSize(size)
216         && (size == IsAnti.Size() || IsAnti.Size() == 0));
217   }
218 
IsItemAntiCArchiveDatabaseOut219   bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
220   // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
221 
SetItem_AntiCArchiveDatabaseOut222   void SetItem_Anti(unsigned index, bool isAnti)
223   {
224     while (index >= IsAnti.Size())
225       IsAnti.Add(false);
226     IsAnti[index] = isAnti;
227   }
228   /*
229   void SetItem_Aux(unsigned index, bool isAux)
230   {
231     while (index >= IsAux.Size())
232       IsAux.Add(false);
233     IsAux[index] = isAux;
234   }
235   */
236 
237   void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
238 };
239 
240 
241 class COutArchive
242 {
243   UInt64 _prefixHeaderPos;
244 
WriteDirect(const void * data,UInt32 size)245   HRESULT WriteDirect(const void *data, UInt32 size) { return WriteStream(SeqStream, data, size); }
246 
247   UInt64 GetPos() const;
248   void WriteBytes(const void *data, size_t size);
WriteBytes(const CByteBuffer & data)249   void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.Size()); }
250   void WriteByte(Byte b);
251   void WriteUInt32(UInt32 value);
252   void WriteUInt64(UInt64 value);
253   void WriteNumber(UInt64 value);
WriteID(UInt64 value)254   void WriteID(UInt64 value) { WriteNumber(value); }
255 
256   void WriteFolder(const CFolder &folder);
257   HRESULT WriteFileHeader(const CFileItem &itemInfo);
258   void WriteBoolVector(const CBoolVector &boolVector);
259   void WritePropBoolVector(Byte id, const CBoolVector &boolVector);
260 
261   void WriteHashDigests(const CUInt32DefVector &digests);
262 
263   void WritePackInfo(
264       UInt64 dataOffset,
265       const CRecordVector<UInt64> &packSizes,
266       const CUInt32DefVector &packCRCs);
267 
268   void WriteUnpackInfo(
269       const CObjectVector<CFolder> &folders,
270       const COutFolders &outFolders);
271 
272   void WriteSubStreamsInfo(
273       const CObjectVector<CFolder> &folders,
274       const COutFolders &outFolders,
275       const CRecordVector<UInt64> &unpackSizes,
276       const CUInt32DefVector &digests);
277 
278   void SkipToAligned(unsigned pos, unsigned alignShifts);
279   void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
280   void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
281 
282   HRESULT EncodeStream(
283       DECL_EXTERNAL_CODECS_LOC_VARS
284       CEncoder &encoder, const CByteBuffer &data,
285       CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders);
286   void WriteHeader(
287       const CArchiveDatabaseOut &db,
288       // const CHeaderOptions &headerOptions,
289       UInt64 &headerOffset);
290 
291   bool _countMode;
292   bool _writeToStream;
293   size_t _countSize;
294   UInt32 _crc;
295   COutBuffer _outByte;
296   CWriteBufferLoc _outByte2;
297 
298   #ifdef _7Z_VOL
299   bool _endMarker;
300   #endif
301 
302   bool _useAlign;
303 
304   HRESULT WriteSignature();
305   #ifdef _7Z_VOL
306   HRESULT WriteFinishSignature();
307   #endif
308   HRESULT WriteStartHeader(const CStartHeader &h);
309   #ifdef _7Z_VOL
310   HRESULT WriteFinishHeader(const CFinishHeader &h);
311   #endif
312   CMyComPtr<IOutStream> Stream;
313 public:
314 
COutArchive()315   COutArchive() { _outByte.Create(1 << 16); }
316   CMyComPtr<ISequentialOutStream> SeqStream;
317   HRESULT Create(ISequentialOutStream *stream, bool endMarker);
318   void Close();
319   HRESULT SkipPrefixArchiveHeader();
320   HRESULT WriteDatabase(
321       DECL_EXTERNAL_CODECS_LOC_VARS
322       const CArchiveDatabaseOut &db,
323       const CCompressionMethodMode *options,
324       const CHeaderOptions &headerOptions);
325 
326   #ifdef _7Z_VOL
327   static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
328   static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
329   #endif
330 
331 };
332 
333 }}
334 
335 #endif
336