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
13namespace NArchive {
14namespace N7z {
15
16class CWriteBufferLoc
17{
18  Byte *_data;
19  size_t _size;
20  size_t _pos;
21public:
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
45struct 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
60class 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;
130public:
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