1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zOut.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/7zCrc.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/AutoPtr.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamObjects.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zOut.h"
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (size > 0)
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 processedSize;
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(stream->Write(data, curSize, &processedSize));
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (processedSize == 0)
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    data = (const void *)((const Byte *)data + processedSize);
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size -= processedSize;
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive {
29baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z {
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
31baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteDirect(const void *data, UInt32 size)
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return ::WriteBytes(SeqStream, data, size);
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
36baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteSignature()
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte buf[8];
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  memcpy(buf, kSignature, kSignatureSize);
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  buf[kSignatureSize] = kMajorVersion;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  buf[kSignatureSize + 1] = 3;
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return WriteDirect(buf, 8);
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _7Z_VOL
46baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteFinishSignature()
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirect(kFinishSignature, kSignatureSize));
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CArchiveVersion av;
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  av.Major = kMajorVersion;
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  av.Minor = 2;
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirectByte(av.Major));
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return WriteDirectByte(av.Minor);
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
57baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SetUInt32(Byte *p, UInt32 d)
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < 4; i++, d >>= 8)
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p[i] = (Byte)d;
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
63baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void SetUInt64(Byte *p, UInt64 d)
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < 8; i++, d >>= 8)
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p[i] = (Byte)d;
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
69baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte buf[24];
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SetUInt64(buf + 4, h.NextHeaderOffset);
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SetUInt64(buf + 12, h.NextHeaderSize);
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SetUInt32(buf + 20, h.NextHeaderCRC);
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SetUInt32(buf, CrcCalc(buf + 4, 20));
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return WriteDirect(buf, 24);
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _7Z_VOL
80baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CCRC crc;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  crc.UpdateUInt64(h.NextHeaderOffset);
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  crc.UpdateUInt64(h.NextHeaderSize);
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  crc.UpdateUInt32(h.NextHeaderCRC);
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  crc.UpdateUInt64(h.ArchiveStartOffset);
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  crc.UpdateUInt64(h.AdditionalStartBlockSize);
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirectUInt32(crc.GetDigest()));
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirectUInt64(h.NextHeaderOffset));
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirectUInt64(h.NextHeaderSize));
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirectUInt32(h.NextHeaderCRC));
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(WriteDirectUInt64(h.ArchiveStartOffset));
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return WriteDirectUInt64(h.AdditionalStartBlockSize);
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
97baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Close();
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _7Z_VOL
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // endMarker = false;
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _endMarker = endMarker;
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SeqStream = stream;
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!endMarker)
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SeqStream.QueryInterface(IID_IOutStream, &Stream);
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!Stream)
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_NOTIMPL;
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // endMarker = true;
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _7Z_VOL
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (endMarker)
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CStartHeader sh;
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    sh.NextHeaderOffset = (UInt32)(Int32)-1;
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    sh.NextHeaderSize = (UInt32)(Int32)-1;
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    sh.NextHeaderCRC = 0;
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteStartHeader(sh);
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!Stream)
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return E_FAIL;
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(WriteSignature());
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
136baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::Close()
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SeqStream.Release();
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Stream.Release();
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
142baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::SkipPrefixArchiveHeader()
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _7Z_VOL
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_endMarker)
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return Stream->Seek(24, STREAM_SEEK_CUR, NULL);
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
151baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 COutArchive::GetPos() const
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_countMode)
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return _countSize;
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_writeToStream)
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return _outByte.GetProcessedSize();
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _outByte2.GetPos();
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
160baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteBytes(const void *data, size_t size)
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_countMode)
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _countSize += size;
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (_writeToStream)
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outByte.WriteBytes(data, size);
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crc = CrcUpdate(_crc, data, size);
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outByte2.WriteBytes(data, size);
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
173baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteByte(Byte b)
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_countMode)
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _countSize++;
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (_writeToStream)
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outByte.WriteByte(b);
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crc = CRC_UPDATE_BYTE(_crc, b);
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outByte2.WriteByte(b);
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
186baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUInt32(UInt32 value)
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < 4; i++)
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte((Byte)value);
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    value >>= 8;
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
195baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUInt64(UInt64 value)
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < 8; i++)
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte((Byte)value);
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    value >>= 8;
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
204baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteNumber(UInt64 value)
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte firstByte = 0;
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte mask = 0x80;
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < 8; i++)
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (value < ((UInt64(1) << ( 7  * (i + 1)))))
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      firstByte |= Byte(value >> (8 * i));
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    firstByte |= mask;
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mask >>= 1;
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(firstByte);
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;i > 0; i--)
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte((Byte)value);
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    value >>= 8;
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
227baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UInt32 GetBigNumberSize(UInt64 value)
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 1; i < 9; i++)
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (value < (((UInt64)1 << (i * 7))))
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return i;
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef _7Z_VOL
237baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (nameLength != 0)
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    nameLength = (nameLength + 1) * 2;
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result += nameLength + GetBigNumberSize(nameLength) + 2;
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (props)
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result += 20;
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (result >= 128)
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result++;
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  result += kSignatureSize + 2 + kFinishHeaderSize;
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return result;
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
255baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props);
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int testSize;
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (volSize > headersSizeBase)
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    testSize = volSize - headersSizeBase;
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    testSize = 1;
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props);
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 pureSize = 1;
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (volSize > headersSize)
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pureSize = volSize - headersSize;
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return pureSize;
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
271baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteFolder(const CFolder &folder)
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteNumber(folder.Coders.Size());
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < folder.Coders.Size(); i++)
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CCoderInfo &coder = folder.Coders[i];
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      size_t propsSize = coder.Props.GetCapacity();
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 id = coder.MethodID;
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      int idSize;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (idSize = 1; idSize < sizeof(id); idSize++)
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if ((id >> (8 * idSize)) == 0)
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      BYTE longID[15];
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        longID[t] = (Byte)(id & 0xFF);
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte b;
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      b = (Byte)(idSize & 0xF);
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bool isComplex = !coder.IsSimpleCoder();
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      b |= (isComplex ? 0x10 : 0);
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      b |= ((propsSize != 0) ? 0x20 : 0 );
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(b);
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteBytes(longID, idSize);
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (isComplex)
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        WriteNumber(coder.NumInStreams);
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        WriteNumber(coder.NumOutStreams);
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (propsSize == 0)
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        continue;
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteNumber(propsSize);
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteBytes(coder.Props, propsSize);
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < folder.BindPairs.Size(); i++)
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CBindPair &bindPair = folder.BindPairs[i];
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteNumber(bindPair.InIndex);
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteNumber(bindPair.OutIndex);
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (folder.PackStreams.Size() > 1)
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < folder.PackStreams.Size(); i++)
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteNumber(folder.PackStreams[i]);
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
320baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteBoolVector(const CBoolVector &boolVector)
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte b = 0;
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte mask = 0x80;
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < boolVector.Size(); i++)
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (boolVector[i])
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      b |= mask;
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mask >>= 1;
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (mask == 0)
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(b);
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      mask = 0x80;
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      b = 0;
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (mask != 0x80)
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(b);
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
341baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteHashDigests(
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<bool> &digestsDefined,
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<UInt32> &digests)
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int numDefined = 0;
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < digestsDefined.Size(); i++)
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (digestsDefined[i])
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numDefined++;
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numDefined == 0)
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kCRC);
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numDefined == digestsDefined.Size())
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(1);
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(0);
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteBoolVector(digestsDefined);
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < digests.Size(); i++)
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (digestsDefined[i])
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteUInt32(digests[i]);
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
366baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WritePackInfo(
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 dataOffset,
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<UInt64> &packSizes,
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<bool> &packCRCsDefined,
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<UInt32> &packCRCs)
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (packSizes.IsEmpty())
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kPackInfo);
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteNumber(dataOffset);
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteNumber(packSizes.Size());
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kSize);
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < packSizes.Size(); i++)
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteNumber(packSizes[i]);
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteHashDigests(packCRCsDefined, packCRCs);
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kEnd);
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
386baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUnpackInfo(const CObjectVector<CFolder> &folders)
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (folders.IsEmpty())
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kUnpackInfo);
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kFolder);
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteNumber(folders.Size());
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(0);
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int i = 0; i < folders.Size(); i++)
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteFolder(folders[i]);
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kCodersUnpackSize);
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < folders.Size(); i++)
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CFolder &folder = folders[i];
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int j = 0; j < folder.UnpackSizes.Size(); j++)
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteNumber(folder.UnpackSizes[j]);
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<bool> unpackCRCsDefined;
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<UInt32> unpackCRCs;
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < folders.Size(); i++)
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CFolder &folder = folders[i];
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    unpackCRCsDefined.Add(folder.UnpackCRCDefined);
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    unpackCRCs.Add(folder.UnpackCRC);
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteHashDigests(unpackCRCsDefined, unpackCRCs);
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kEnd);
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
423baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteSubStreamsInfo(
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CObjectVector<CFolder> &folders,
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<CNum> &numUnpackStreamsInFolders,
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<UInt64> &unpackSizes,
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<bool> &digestsDefined,
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CRecordVector<UInt32> &digests)
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kSubStreamsInfo);
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numUnpackStreamsInFolders[i] != 1)
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(NID::kNumUnpackStream);
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        WriteNumber(numUnpackStreamsInFolders[i]);
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool needFlag = true;
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum index = 0;
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (CNum j = 0; j < numUnpackStreamsInFolders[i]; j++)
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (j + 1 != numUnpackStreamsInFolders[i])
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (needFlag)
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          WriteByte(NID::kSize);
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        needFlag = false;
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        WriteNumber(unpackSizes[index]);
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      index++;
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<bool> digestsDefined2;
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<UInt32> digests2;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int digestIndex = 0;
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < folders.Size(); i++)
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int numSubStreams = (int)numUnpackStreamsInFolders[i];
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numSubStreams == 1 && folders[i].UnpackCRCDefined)
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      digestIndex++;
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (int j = 0; j < numSubStreams; j++, digestIndex++)
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digestsDefined2.Add(digestsDefined[digestIndex]);
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digests2.Add(digests[digestIndex]);
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteHashDigests(digestsDefined2, digests2);
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kEnd);
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
480baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::SkipAlign(unsigned /* pos */, unsigned /* alignSize */)
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return;
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
488baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pos += (unsigned)GetPos();
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pos &= (alignSize - 1);
492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (pos == 0)
493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  unsigned skip = alignSize - pos;
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (skip < 2)
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    skip += alignSize;
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  skip -= 2;
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kDummy);
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte((Byte)skip);
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (unsigned i = 0; i < skip; i++)
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(0);
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
505baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline unsigned Bv_GetSizeInBytes(const CBoolVector &v) { return ((unsigned)v.Size() + 7) / 8; }
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
507baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize)
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(type);
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteNumber(dataSize);
515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numDefined == v.Size())
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(1);
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(0);
520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteBoolVector(v);
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(0);
523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
525baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int numDefined = 0;
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < v.Defined.Size(); i++)
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (v.Defined[i])
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numDefined++;
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numDefined == 0)
535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteAlignedBoolHeader(v.Defined, numDefined, type, 8);
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < v.Defined.Size(); i++)
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (v.Defined[i])
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteUInt64(v.Values[i]);
542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
544baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::EncodeStream(
545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CEncoder &encoder, const CByteBuffer &data,
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBufInStream *streamSpec = new CBufInStream;
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> stream = streamSpec;
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  streamSpec->Init(data, data.GetCapacity());
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CFolder folderItem;
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folderItem.UnpackCRCDefined = true;
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folderItem.UnpackCRC = CrcCalc(data, data.GetCapacity());
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 dataSize64 = data.GetCapacity();
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(encoder.Encode(
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      EXTERNAL_CODECS_LOC_VARS
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folders.Add(folderItem);
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
563baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid COutArchive::WriteHeader(
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CArchiveDatabase &db,
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CHeaderOptions &headerOptions,
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 &headerOffset)
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 packedSize = 0;
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < db.PackSizes.Size(); i++)
572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    packedSize += db.PackSizes[i];
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  headerOffset = packedSize;
575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kHeader);
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // Archive Properties
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (db.Folders.Size() > 0)
581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(NID::kMainStreamsInfo);
583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WritePackInfo(0, db.PackSizes,
584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        db.PackCRCsDefined,
585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        db.PackCRCs);
586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteUnpackInfo(db.Folders);
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<UInt64> unpackSizes;
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<bool> digestsDefined;
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<UInt32> digests;
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < db.Files.Size(); i++)
593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const CFileItem &file = db.Files[i];
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!file.HasStream)
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        continue;
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      unpackSizes.Add(file.Size);
598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      digestsDefined.Add(file.CrcDefined);
599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      digests.Add(file.Crc);
600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteSubStreamsInfo(
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        db.Folders,
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        db.NumUnpackStreamsVector,
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        unpackSizes,
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digestsDefined,
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digests);
608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(NID::kEnd);
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (db.Files.IsEmpty())
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(NID::kEnd);
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kFilesInfo);
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteNumber(db.Files.Size());
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  /* ---------- Empty Streams ---------- */
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBoolVector emptyStreamVector;
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  emptyStreamVector.Reserve(db.Files.Size());
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int numEmptyStreams = 0;
625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < db.Files.Size(); i++)
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (db.Files[i].HasStream)
627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      emptyStreamVector.Add(false);
628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      emptyStreamVector.Add(true);
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numEmptyStreams++;
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numEmptyStreams > 0)
634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteByte(NID::kEmptyStream);
636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteNumber(Bv_GetSizeInBytes(emptyStreamVector));
637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteBoolVector(emptyStreamVector);
638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CBoolVector emptyFileVector, antiVector;
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    emptyFileVector.Reserve(numEmptyStreams);
641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    antiVector.Reserve(numEmptyStreams);
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CNum numEmptyFiles = 0, numAntiItems = 0;
643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < db.Files.Size(); i++)
644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const CFileItem &file = db.Files[i];
646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!file.HasStream)
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        emptyFileVector.Add(!file.IsDir);
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!file.IsDir)
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          numEmptyFiles++;
651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        bool isAnti = db.IsItemAnti(i);
652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        antiVector.Add(isAnti);
653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (isAnti)
654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          numAntiItems++;
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numEmptyFiles > 0)
659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(NID::kEmptyFile);
661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteNumber(Bv_GetSizeInBytes(emptyFileVector));
662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteBoolVector(emptyFileVector);
663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numAntiItems > 0)
666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(NID::kAnti);
668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteNumber(Bv_GetSizeInBytes(antiVector));
669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteBoolVector(antiVector);
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /* ---------- Names ---------- */
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int numDefined = 0;
679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t namesDataSize = 0;
680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int i = 0; i < db.Files.Size(); i++)
681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const UString &name = db.Files[i].Name;
683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!name.IsEmpty())
684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        numDefined++;
685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      namesDataSize += (name.Length() + 1) * 2;
686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numDefined > 0)
689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      namesDataSize++;
691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SkipAlign(2 + GetBigNumberSize(namesDataSize), 2);
692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(NID::kName);
694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteNumber(namesDataSize);
695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(0);
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (int i = 0; i < db.Files.Size(); i++)
697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        const UString &name = db.Files[i].Name;
699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (int t = 0; t <= name.Length(); t++)
700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          wchar_t c = name[t];
702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          WriteByte((Byte)c);
703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          WriteByte((Byte)(c >> 8));
704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (headerOptions.WriteCTime) WriteUInt64DefVector(db.CTime, NID::kCTime);
710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (headerOptions.WriteATime) WriteUInt64DefVector(db.ATime, NID::kATime);
711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (headerOptions.WriteMTime) WriteUInt64DefVector(db.MTime, NID::kMTime);
712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteUInt64DefVector(db.StartPos, NID::kStartPos);
713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /* ---------- Write Attrib ---------- */
716baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CBoolVector boolVector;
717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    boolVector.Reserve(db.Files.Size());
718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int numDefined = 0;
719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < db.Files.Size(); i++)
720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bool defined = db.Files[i].AttribDefined;
722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      boolVector.Add(defined);
723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (defined)
724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        numDefined++;
725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numDefined > 0)
727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttributes, 4);
729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (i = 0; i < db.Files.Size(); i++)
730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        const CFileItem &file = db.Files[i];
732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (file.AttribDefined)
733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          WriteUInt32(file.Attrib);
734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kEnd); // for files
739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteByte(NID::kEnd); // for headers
740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
742baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT COutArchive::WriteDatabase(
743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CArchiveDatabase &db,
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CCompressionMethodMode *options,
746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CHeaderOptions &headerOptions)
747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!db.CheckNumFiles())
749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return E_FAIL;
750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 headerOffset;
752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 headerCRC;
753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 headerSize;
754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (db.IsEmpty())
755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    headerSize = 0;
757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    headerOffset = 0;
758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    headerCRC = CrcCalc(0, 0);
759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool encodeHeaders = false;
763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (options != 0)
764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (options->IsEmpty())
765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        options = 0;
766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (options != 0)
767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        encodeHeaders = true;
769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outByte.SetStream(SeqStream);
771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _outByte.Init();
772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _crc = CRC_INIT_VAL;
773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _countMode = encodeHeaders;
774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _writeToStream = true;
775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _countSize = 0;
776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WriteHeader(db, headerOptions, headerOffset);
777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (encodeHeaders)
779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CByteBuffer buf;
781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      buf.SetCapacity(_countSize);
782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _outByte2.Init((Byte *)buf, _countSize);
783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _countMode = false;
785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _writeToStream = false;
786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteHeader(db, headerOptions, headerOffset);
787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (_countSize != _outByte2.GetPos())
789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return E_FAIL;
790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CCompressionMethodMode encryptOptions;
792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      encryptOptions.Password = options->Password;
794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CRecordVector<UInt64> packSizes;
796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CObjectVector<CFolder> folders;
797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(EncodeStream(
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          EXTERNAL_CODECS_LOC_VARS
799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          encoder, buf,
800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          packSizes, folders));
801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      _writeToStream = true;
803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (folders.Size() == 0)
805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw 1;
806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteID(NID::kEncodedHeader);
808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WritePackInfo(headerOffset, packSizes,
809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CRecordVector<bool>(), CRecordVector<UInt32>());
810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteUnpackInfo(folders);
811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      WriteByte(NID::kEnd);
812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (int i = 0; i < packSizes.Size(); i++)
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        headerOffset += packSizes[i];
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_outByte.Flush());
816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    headerCRC = CRC_GET_DIGEST(_crc);
817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    headerSize = _outByte.GetProcessedSize();
818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _7Z_VOL
820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_endMarker)
821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CFinishHeader h;
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.NextHeaderSize = headerSize;
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.NextHeaderCRC = headerCRC;
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.NextHeaderOffset =
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt64(0) - (headerSize +
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        4 + kFinishHeaderSize);
828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset;
829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.AdditionalStartBlockSize = 0;
830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(WriteFinishHeader(h));
831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return WriteFinishSignature();
832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CStartHeader h;
837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.NextHeaderSize = headerSize;
838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.NextHeaderCRC = headerCRC;
839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    h.NextHeaderOffset = headerOffset;
840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return WriteStartHeader(h);
842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
845baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveDatabase::GetFile(int index, CFileItem &file, CFileItem2 &file2) const
846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  file = Files[index];
848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  file2.CTimeDefined = CTime.GetItem(index, file2.CTime);
849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  file2.ATimeDefined = ATime.GetItem(index, file2.ATime);
850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  file2.MTimeDefined = MTime.GetItem(index, file2.MTime);
851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  file2.StartPosDefined = StartPos.GetItem(index, file2.StartPos);
852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  file2.IsAnti = IsItemAnti(index);
853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
855baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CArchiveDatabase::AddFile(const CFileItem &file, const CFileItem2 &file2)
856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index = Files.Size();
858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CTime.SetItem(index, file2.CTimeDefined, file2.CTime);
859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
862baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SetItemAnti(index, file2.IsAnti);
863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Files.Add(file);
864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
867