1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zIn.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef _WIN32
6cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include <wchar.h>
7cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#else
8cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include <ctype.h>
9cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/7zCrc.h"
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/CpuArch.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamObjects.h"
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamUtils.h"
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zDecode.h"
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zIn.h"
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define Get16(p) GetUi16(p)
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define Get32(p) GetUi32(p)
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define Get64(p) GetUi64(p)
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _SFX
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define FORMAT_7Z_RECOVERY
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NWindows;
30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NCOM;
31cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
32baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive {
33baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z {
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void BoolVector_Fill_False(CBoolVector &v, unsigned size)
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
37cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  v.ClearAndSetSize(size);
38cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool *p = &v[0];
39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < size; i++)
40cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p[i] = false;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CInArchiveException {};
44cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyclass CUnsupportedFeatureException: public CInArchiveException {};
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
46baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void ThrowException() { throw CInArchiveException(); }
47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline void ThrowEndOfData()   { ThrowException(); }
48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); }
49baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline void ThrowIncorrect()   { ThrowException(); }
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
51baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CStreamSwitch
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CInArchive *_archive;
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool _needRemove;
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool _needUpdatePos;
56baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic:
57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {}
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ~CStreamSwitch() { Remove(); }
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Remove();
60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos);
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
65baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamSwitch::Remove()
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_needRemove)
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
69cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_archive->_inByteBack->GetRem() != 0)
70cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _archive->ThereIsHeaderError = true;
71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _archive->DeleteByteStream(_needUpdatePos);
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _needRemove = false;
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos)
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Remove();
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _archive = archive;
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _archive->AddByteStream(data, size);
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _needRemove = true;
82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _needUpdatePos = needUpdatePos;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
85baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  Set(archive, byteBuffer, byteBuffer.Size(), false);
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
90baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Remove();
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte external = archive->ReadByte();
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (external != 0)
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
96f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (!dataVector)
97f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      ThrowIncorrect();
98cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CNum dataIndex = archive->ReadNum();
99cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (dataIndex >= dataVector->Size())
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowIncorrect();
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Set(archive, (*dataVector)[dataIndex]);
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
105cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::AddByteStream(const Byte *buf, size_t size)
106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_numInByteBufs == kNumBufLevelsMax)
108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ThrowIncorrect();
109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _inByteBack = &_inByteVector[_numInByteBufs++];
110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _inByteBack->Init(buf, size);
111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
114baa3858d3f5d128a5c8466b700098109edcad5f2repo syncByte CInByte2::ReadByte()
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_pos >= _size)
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowEndOfData();
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return _buffer[_pos++];
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
121baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInByte2::ReadBytes(Byte *data, size_t size)
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
123f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (size == 0)
124f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    return;
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (size > _size - _pos)
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowEndOfData();
127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  memcpy(data, _buffer + _pos, size);
128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _pos += size;
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
131baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInByte2::SkipData(UInt64 size)
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (size > _size - _pos)
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowEndOfData();
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _pos += (size_t)size;
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
138baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInByte2::SkipData()
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SkipData(ReadNumber());
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size == 0)
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    processed = 0;
148cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 0;
149cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
150f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
151f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  unsigned b = *p++;
152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size--;
153f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
154f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if ((b & 0x80) == 0)
155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    processed = 1;
157f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    return b;
158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
159f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size == 0)
161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
162cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    processed = 0;
163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 0;
164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
165f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 value = (UInt64)*p;
167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  p++;
168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size--;
169f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 1; i < 8; i++)
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
172f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    unsigned mask = (unsigned)0x80 >> i;
173f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if ((b & mask) == 0)
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
175f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      UInt64 high = b & (mask - 1);
176f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      value |= (high << (i * 8));
177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      processed = i + 1;
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return value;
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
180f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (size == 0)
182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      processed = 0;
184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 0;
185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
186f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    value |= ((UInt64)*p << (i * 8));
188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p++;
189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size--;
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
191f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
192cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  processed = 9;
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return value;
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CInByte2::ReadNumber()
197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size_t processed;
199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed);
200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (processed == 0)
201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ThrowEndOfData();
202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _pos += processed;
203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return res;
204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
206baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCNum CInByte2::ReadNum()
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_pos < _size)
210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Byte val = _buffer[_pos];
212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if ((unsigned)val < 0x80)
213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _pos++;
215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return (unsigned)val;
216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 value = ReadNumber();
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (value > kNumMax)
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowUnsupported();
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (CNum)value;
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
225baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt32 CInByte2::ReadUInt32()
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_pos + 4 > _size)
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowEndOfData();
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 res = Get32(_buffer + _pos);
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _pos += 4;
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
234baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 CInByte2::ReadUInt64()
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (_pos + 8 > _size)
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowEndOfData();
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 res = Get64(_buffer + _pos);
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _pos += 8;
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false;
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
245baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline bool TestSignature(const Byte *p)
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CHECK_SIGNATURE
248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return CrcCalc(p + 12, 20) == Get32(p + 8);
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef FORMAT_7Z_RECOVERY
252baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline bool TestSignature2(const Byte *p)
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CHECK_SIGNATURE;
255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (CrcCalc(p + 12, 20) == Get32(p + 8))
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 8; i < kHeaderSize; i++)
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (p[i] != 0)
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (p[6] != 0 || p[7] != 0);
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define TestSignature2(p) TestSignature(p)
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
266baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (TestSignature2(_header))
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_FALSE;
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const UInt32 kBufSize = 1 << 15;
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CByteArr buf(kBufSize);
277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  memcpy(buf, _header, kHeaderSize);
278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 offset = 0;
279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 readSize = kBufSize - kHeaderSize;
283f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (searchHeaderSizeLimit)
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 rem = *searchHeaderSizeLimit - offset;
286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (readSize > rem)
287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        readSize = (UInt32)rem;
288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (readSize == 0)
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return S_FALSE;
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
291f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 processed = 0;
293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (processed == 0)
295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_FALSE;
296f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (UInt32 pos = 0;;)
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const Byte *p = buf + pos + 1;
300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const Byte *lim = buf + processed;
301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (; p <= lim; p += 4)
302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (p[0] == '7') break;
304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (p[1] == '7') { p += 1; break; }
305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (p[2] == '7') { p += 2; break; }
306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (p[3] == '7') { p += 3; break; }
307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      };
308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (p > lim)
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      pos = (UInt32)(p - buf);
311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (TestSignature(p))
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        memcpy(_header, p, kHeaderSize);
314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        _arhiveBeginStreamPosition += offset + pos;
315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
318f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    offset += processed;
320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    memmove(buf, buf + processed, kHeaderSize);
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// S_FALSE means that file is not archive
325baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HeadersSize = 0;
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Close();
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _stream = stream;
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
337baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::Close()
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  _numInByteBufs = 0;
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _stream.Release();
341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ThereIsHeaderError = false;
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
344baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ReadID() == NID::kEnd)
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SkipData();
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky// CFolder &folder can be non empty. So we must set all fields
355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInByte2::ParseFolder(CFolder &folder)
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
358f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numCoders = ReadNum();
359f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
360f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (numCoders == 0)
361f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    ThrowUnsupported();
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
363cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folder.Coders.SetSize(numCoders);
364cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
365f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numInStreams = 0;
366f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 i;
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numCoders; i++)
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
369cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CCoderInfo &coder = folder.Coders[i];
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte mainByte = ReadByte();
372cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if ((mainByte & 0xC0) != 0)
373cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ThrowUnsupported();
374cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unsigned idSize = (mainByte & 0xF);
375cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (idSize > 8 || idSize > GetRem())
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ThrowUnsupported();
377cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      const Byte *longID = GetPtr();
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 id = 0;
379cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (unsigned j = 0; j < idSize; j++)
380cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        id = ((id << 8) | longID[j]);
381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      SkipDataNoCheck(idSize);
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      coder.MethodID = id;
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if ((mainByte & 0x10) != 0)
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
386f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        coder.NumStreams = ReadNum();
387f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        /* numOutStreams = */ ReadNum();
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
391f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        coder.NumStreams = 1;
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
393f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if ((mainByte & 0x20) != 0)
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CNum propsSize = ReadNum();
397cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        coder.Props.Alloc((size_t)propsSize);
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ReadBytes((Byte *)coder.Props, (size_t)propsSize);
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
400cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
401cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        coder.Props.Free();
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
403f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    numInStreams += coder.NumStreams;
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
406f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numBonds = numCoders - 1;
407f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  folder.Bonds.SetSize(numBonds);
408f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  for (i = 0; i < numBonds; i++)
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
410f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    CBond &bp = folder.Bonds[i];
411f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bp.PackIndex = ReadNum();
412f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    bp.UnpackIndex = ReadNum();
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
415f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (numInStreams < numBonds)
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowUnsupported();
417f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  UInt32 numPackStreams = numInStreams - numBonds;
418cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folder.PackStreams.SetSize(numPackStreams);
419f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numPackStreams == 1)
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numInStreams; i++)
423f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (folder.FindBond_for_PackStream(i) < 0)
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        folder.PackStreams[0] = i;
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (i == numInStreams)
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowUnsupported();
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numPackStreams; i++)
433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      folder.PackStreams[i] = ReadNum();
434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const
437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size_t startPos = FoCodersDataOffset[folderIndex];
439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CInByte2 inByte;
440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos);
441cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  inByte.ParseFolder(folder);
442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (inByte.GetRem() != 0)
443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    throw 20120424;
444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CDatabase::GetPath(unsigned index, UString &path) const
448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  path.Empty();
450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!NameOffsets || !NamesBuf)
451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size_t offset = NameOffsets[index];
454f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  size_t size = NameOffsets[index + 1] - offset;
455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
456f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (size >= (1 << 28))
457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
459f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  wchar_t *s = path.GetBuf((unsigned)size - 1);
460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const Byte *p = ((const Byte *)NamesBuf + offset * 2);
462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #if defined(_WIN32) && defined(MY_CPU_LE)
464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  wmemcpy(s, (const wchar_t *)p, size);
466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #else
468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (size_t i = 0; i < size; i++)
470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    *s = Get16(p);
472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p += 2;
473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s++;
474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
475cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  #endif
477cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
478f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  path.ReleaseBuf_SetLen((unsigned)size - 1);
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  PropVariant_Clear(path);
484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!NameOffsets || !NamesBuf)
485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_OK;
486cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size_t offset = NameOffsets[index];
488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size_t size = NameOffsets[index + 1] - offset;
489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
490cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size >= (1 << 14))
491cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_OK;
492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
494cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  wchar_t *s = path->bstrVal;
495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
496cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const Byte *p = ((const Byte *)NamesBuf + offset * 2);
497cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
498cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (size_t i = 0; i < size; i++)
499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    wchar_t c = Get16(p);
501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p += 2;
502cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #if WCHAR_PATH_SEPARATOR != L'/'
503cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (c == L'/')
504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      c = WCHAR_PATH_SEPARATOR;
505cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    #endif
506cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    *s++ = c;
507cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
508cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
510cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned cur = index;
513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned size = 0;
514cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (int i = 0;; i++)
516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size_t len = NameOffsets[cur + 1] - NameOffsets[cur];
518cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size += (unsigned)len;
519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (i > 256 || len > (1 << 14) || size > (1 << 14))
520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return PropVarEm_Set_Str(path, "[TOO-LONG]");
521cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    cur = Files[cur].Parent;
522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (cur < 0)
523cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      break;
524cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size--;
526cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
527cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(PropVarEm_Alloc_Bstr(path, size));
528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  wchar_t *s = path->bstrVal;
529cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += size;
530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  *s = 0;
531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  cur = index;
532cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
533cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (;;)
534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1);
536cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2;
537f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    for (; len != 0; len--)
538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
539cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      p -= 2;
540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      --s;
541cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      wchar_t c = Get16(p);
542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (c == '/')
543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        c = WCHAR_PATH_SEPARATOR;
544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      *s = c;
545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
546f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const CFileItem &file = Files[cur];
548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    cur = file.Parent;
549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (cur < 0)
550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_OK;
551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR);
552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
555cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
556cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::WaitId(UInt64 id)
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type = ReadID();
561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (type == id)
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return;
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kEnd)
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowIncorrect();
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SkipData();
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
569cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ReadBoolVector2(numItems, crcs.Defs);
572cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  crcs.Vals.ClearAndSetSize(numItems);
573cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 *p = &crcs.Vals[0];
574cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const bool *defs = &crcs.Defs[0];
575cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < numItems; i++)
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 crc = 0;
578cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (defs[i])
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      crc = ReadUInt32();
580cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p[i] = crc;
581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
584f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#define k_Scan_NumCoders_MAX 64
585f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#define k_Scan_NumCodersStreams_in_Folder_MAX 64
586f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadPackInfo(CFolders &f)
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum numPackStreams = ReadNum();
590cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
591cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  WaitId(NID::kSize);
592cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.PackPositions.Alloc(numPackStreams + 1);
593cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.NumPackStreams = numPackStreams;
594cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 sum = 0;
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (CNum i = 0; i < numPackStreams; i++)
596cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
597cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    f.PackPositions[i] = sum;
598cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 packSize = ReadNumber();
599cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    sum += packSize;
600cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (sum < packSize)
601cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ThrowIncorrect();
602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  f.PackPositions[numPackStreams] = sum;
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 type;
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    type = ReadID();
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kEnd)
610cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kCRC)
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
613cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CUInt32DefVector PackCRCs;
614cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ReadHashDigests(numPackStreams, PackCRCs);
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SkipData();
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
621baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadUnpackInfo(
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CObjectVector<CByteBuffer> *dataVector,
623cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CFolders &folders)
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
625cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  WaitId(NID::kFolder);
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum numFolders = ReadNum();
627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
628cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CNum numCodersOutStreams = 0;
629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CStreamSwitch streamSwitch;
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    streamSwitch.Set(this, dataVector);
632cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const Byte *startBufPtr = _inByteBack->GetPtr();
633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.NumFolders = numFolders;
634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoStartPackStreamIndex.Alloc(numFolders + 1);
636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoToMainUnpackSizeIndex.Alloc(numFolders);
637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoCodersDataOffset.Alloc(numFolders + 1);
638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoToCoderUnpackSizes.Alloc(numFolders + 1);
639cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
640f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    CBoolVector StreamUsed;
641f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    CBoolVector CoderUsed;
642cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
643cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CNum packStreamIndex = 0;
644cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CNum fo;
645cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CInByte2 *inByte = _inByteBack;
646f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
647cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (fo = 0; fo < numFolders; fo++)
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
649cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt32 indexOfMainStream = 0;
650cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt32 numPackStreams = 0;
651cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
652cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
653cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CNum numInStreams = 0;
654cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CNum numCoders = inByte->ReadNum();
655f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
656f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
657f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        ThrowUnsupported();
658f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
659cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (CNum ci = 0; ci < numCoders; ci++)
660cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
661cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        Byte mainByte = inByte->ReadByte();
662cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if ((mainByte & 0xC0) != 0)
663cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowUnsupported();
664f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
665cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        unsigned idSize = (mainByte & 0xF);
666cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (idSize > 8)
667cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowUnsupported();
668cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (idSize > inByte->GetRem())
669cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowEndOfData();
670cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        const Byte *longID = inByte->GetPtr();
671cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt64 id = 0;
672cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        for (unsigned j = 0; j < idSize; j++)
673cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          id = ((id << 8) | longID[j]);
674cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        inByte->SkipDataNoCheck(idSize);
675cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (folders.ParsedMethods.IDs.Size() < 128)
676cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          folders.ParsedMethods.IDs.AddToUniqueSorted(id);
677f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
678cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        CNum coderInStreams = 1;
679cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if ((mainByte & 0x10) != 0)
680cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
681cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          coderInStreams = inByte->ReadNum();
682f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
683f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            ThrowUnsupported();
684f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (inByte->ReadNum() != 1)
685f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            ThrowUnsupported();
686cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
687f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
688cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numInStreams += coderInStreams;
689f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
690cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowUnsupported();
691f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
692cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if ((mainByte & 0x20) != 0)
693cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
694cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          CNum propsSize = inByte->ReadNum();
695cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (propsSize > inByte->GetRem())
696cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            ThrowEndOfData();
697cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (id == k_LZMA2 && propsSize == 1)
698cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
699cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            Byte v = *_inByteBack->GetPtr();
700cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            if (folders.ParsedMethods.Lzma2Prop < v)
701cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              folders.ParsedMethods.Lzma2Prop = v;
702cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
703cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          else if (id == k_LZMA && propsSize == 5)
704cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
705cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1);
706cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            if (folders.ParsedMethods.LzmaDic < dicSize)
707cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              folders.ParsedMethods.LzmaDic = dicSize;
708cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
709cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          inByte->SkipDataNoCheck((size_t)propsSize);
710cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
711cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
712cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
713f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (numCoders == 1 && numInStreams == 1)
714cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
715cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        indexOfMainStream = 0;
716cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numPackStreams = 1;
717cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
718cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else
719cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
720cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        UInt32 i;
721f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        CNum numBonds = numCoders - 1;
722f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (numInStreams < numBonds)
723cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowUnsupported();
724cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
725f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        BoolVector_Fill_False(StreamUsed, numInStreams);
726f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        BoolVector_Fill_False(CoderUsed, numCoders);
727cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
728f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        for (i = 0; i < numBonds; i++)
729cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
730cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          CNum index = ReadNum();
731f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (index >= numInStreams || StreamUsed[index])
732cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            ThrowUnsupported();
733f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          StreamUsed[index] = true;
734f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
735cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          index = ReadNum();
736f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (index >= numCoders || CoderUsed[index])
737cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            ThrowUnsupported();
738f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          CoderUsed[index] = true;
739cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
740cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
741f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        numPackStreams = numInStreams - numBonds;
742cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
743cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (numPackStreams != 1)
744cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          for (i = 0; i < numPackStreams; i++)
745f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          {
746f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            CNum index = inByte->ReadNum(); // PackStreams
747f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            if (index >= numInStreams || StreamUsed[index])
748f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka              ThrowUnsupported();
749f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka            StreamUsed[index] = true;
750f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          }
751cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
752f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        for (i = 0; i < numCoders; i++)
753f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          if (!CoderUsed[i])
754cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
755cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            indexOfMainStream = i;
756cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            break;
757cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
758f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
759f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        if (i == numCoders)
760cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowUnsupported();
761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
762f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
764f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      numCodersOutStreams += numCoders;
765cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      folders.FoStartPackStreamIndex[fo] = packStreamIndex;
766f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka      if (numPackStreams > folders.NumPackStreams - packStreamIndex)
767f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        ThrowIncorrect();
768cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      packStreamIndex += numPackStreams;
769cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
771f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
773cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
774cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoStartPackStreamIndex[fo] = packStreamIndex;
775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
776cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.CodersData.CopyFrom(startBufPtr, dataSize);
777f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
778f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
781cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  WaitId(NID::kCodersUnpackSize);
782cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folders.CoderUnpackSizes.Alloc(numCodersOutStreams);
783cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (CNum i = 0; i < numCodersOutStreams; i++)
784cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.CoderUnpackSizes[i] = ReadNumber();
785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type = ReadID();
789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kEnd)
790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return;
791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kCRC)
792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
793cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ReadHashDigests(numFolders, folders.FolderCRCs);
794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SkipData();
797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
800baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadSubStreamsInfo(
801cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CFolders &folders,
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<UInt64> &unpackSizes,
803cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CUInt32DefVector &digests)
804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
805cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  folders.NumUnpackStreamsVector.Alloc(folders.NumFolders);
806cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CNum i;
807cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < folders.NumFolders; i++)
808cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.NumUnpackStreamsVector[i] = 1;
809cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 type;
811cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    type = ReadID();
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kNumUnpackStream)
816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
817cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (i = 0; i < folders.NumFolders; i++)
818cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        folders.NumUnpackStreamsVector[i] = ReadNum();
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
821cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd)
822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SkipData();
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
826cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type == NID::kSize)
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
828cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < folders.NumFolders; i++)
829cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // v3.13 incorrectly worked with empty folders
831cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // v4.07: we check that folder is empty
832cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CNum numSubstreams = folders.NumUnpackStreamsVector[i];
833cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (numSubstreams == 0)
834cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        continue;
835cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 sum = 0;
836cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (CNum j = 1; j < numSubstreams; j++)
837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt64 size = ReadNumber();
839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        unpackSizes.Add(size);
840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        sum += size;
841cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (sum < size)
842cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThrowIncorrect();
843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
844cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i);
845cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (folderUnpackSize < sum)
846cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ThrowIncorrect();
847cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unpackSizes.Add(folderUnpackSize - sum);
848cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    type = ReadID();
850cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
851cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
852cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
853cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < folders.NumFolders; i++)
854cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
855cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /* v9.26 - v9.29 incorrectly worked:
856cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky         if (folders.NumUnpackStreamsVector[i] == 0), it threw error */
857cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CNum val = folders.NumUnpackStreamsVector[i];
858cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (val > 1)
859cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ThrowIncorrect();
860cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (val == 1)
861cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        unpackSizes.Add(folders.GetFolderUnpackSize(i));
862cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
863cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned numDigests = 0;
866cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < folders.NumFolders; i++)
867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
868cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CNum numSubstreams = folders.NumUnpackStreamsVector[i];
869cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i))
870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numDigests += numSubstreams;
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
875cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (type == NID::kEnd)
876cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      break;
877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == NID::kCRC)
878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
879cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // CUInt32DefVector digests2;
880cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // ReadHashDigests(numDigests, digests2);
881cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CBoolVector digests2;
882cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ReadBoolVector2(numDigests, digests2);
883cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
884cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      digests.ClearAndSetSize(unpackSizes.Size());
885cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
886cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unsigned k = 0;
887cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unsigned k2 = 0;
888cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
889cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (i = 0; i < folders.NumFolders; i++)
890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
891cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        CNum numSubstreams = folders.NumUnpackStreamsVector[i];
892cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
894cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          digests.Defs[k] = true;
895cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          digests.Vals[k] = folders.FolderCRCs.Vals[i];
896cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          k++;
897cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
898cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        else for (CNum j = 0; j < numSubstreams; j++)
899cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
900cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          bool defined = digests2[k2++];
901cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          digests.Defs[k] = defined;
902cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          UInt32 crc = 0;
903cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (defined)
904cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            crc = ReadUInt32();
905cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          digests.Vals[k] = crc;
906cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          k++;
907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
909cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // if (k != unpackSizes.Size()) throw 1234567;
910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
911cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    else
912cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      SkipData();
913cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
914cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    type = ReadID();
915cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
916cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
917cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (digests.Defs.Size() != unpackSizes.Size())
918cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
919cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    digests.ClearAndSetSize(unpackSizes.Size());
920cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned k = 0;
921cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = 0; i < folders.NumFolders; i++)
922baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
923cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      CNum numSubstreams = folders.NumUnpackStreamsVector[i];
924cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i))
925baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
926cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        digests.Defs[k] = true;
927cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        digests.Vals[k] = folders.FolderCRCs.Vals[i];
928cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        k++;
929cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
930cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      else for (CNum j = 0; j < numSubstreams; j++)
931cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
932cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        digests.Defs[k] = false;
933cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        digests.Vals[k] = 0;
934cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        k++;
935baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
936baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
937baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
938baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
939baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
940baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadStreamsInfo(
941baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CObjectVector<CByteBuffer> *dataVector,
942baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 &dataOffset,
943cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CFolders &folders,
944baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CRecordVector<UInt64> &unpackSizes,
945cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CUInt32DefVector &digests)
946baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
947cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 type = ReadID();
948cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
949cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type == NID::kPackInfo)
950baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
951cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    dataOffset = ReadNumber();
952cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ReadPackInfo(folders);
953cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    type = ReadID();
954cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
955cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
956cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type == NID::kUnpackInfo)
957cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
958cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ReadUnpackInfo(dataVector, folders);
959cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    type = ReadID();
960cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
961cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
962cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (folders.NumFolders != 0 && !folders.PackPositions)
963cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
964cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // if there are folders, we need PackPositions also
965cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.PackPositions.Alloc(1);
966cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.PackPositions[0] = 0;
967cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
968cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
969cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type == NID::kSubStreamsInfo)
970cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
971cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ReadSubStreamsInfo(folders, unpackSizes, digests);
972cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    type = ReadID();
973cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
974cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
975cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
976cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folders.NumUnpackStreamsVector.Alloc(folders.NumFolders);
977cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /* If digests.Defs.Size() == 0, it means that there are no crcs.
978cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky       So we don't need to fill digests with values. */
979cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // digests.Vals.ClearAndSetSize(folders.NumFolders);
980cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // BoolVector_Fill_False(digests.Defs, folders.NumFolders);
981cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (CNum i = 0; i < folders.NumFolders; i++)
982baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
983cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      folders.NumUnpackStreamsVector[i] = 1;
984cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      unpackSizes.Add(folders.GetFolderUnpackSize(i));
985cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // digests.Vals[i] = 0;
986baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
987baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
988cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
989cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type != NID::kEnd)
990cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ThrowIncorrect();
991baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
992baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
993cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v)
994baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
995cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  v.ClearAndSetSize(numItems);
996baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte b = 0;
997baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte mask = 0;
998cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool *p = &v[0];
999cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < numItems; i++)
1000baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1001baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (mask == 0)
1002baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1003baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      b = ReadByte();
1004baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      mask = 0x80;
1005baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1006cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p[i] = ((b & mask) != 0);
1007baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mask >>= 1;
1008baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1009baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1010baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1011cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v)
1012baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1013baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte allAreDefined = ReadByte();
1014baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (allAreDefined == 0)
1015baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1016baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ReadBoolVector(numItems, v);
1017baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
1018baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1019cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  v.ClearAndSetSize(numItems);
1020cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  bool *p = &v[0];
1021cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < numItems; i++)
1022cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p[i] = true;
1023baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1024baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1025baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
1026cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CUInt64DefVector &v, unsigned numItems)
1027baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1028cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ReadBoolVector2(numItems, v.Defs);
1029baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1030baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CStreamSwitch streamSwitch;
1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  streamSwitch.Set(this, &dataVector);
1032cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1033cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  v.Vals.ClearAndSetSize(numItems);
1034cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 *p = &v.Vals[0];
1035cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const bool *defs = &v.Defs[0];
1036baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1037cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (unsigned i = 0; i < numItems; i++)
1038baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1039baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 t = 0;
1040cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (defs[i])
1041baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t = ReadUInt64();
1042cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p[i] = t;
1043baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1044baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1045baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1046baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadAndDecodePackedStreams(
1047baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
1048baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 baseOffset,
1049baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
1050cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _7Z_DECODER_CRYPRO_VARS_DECL
1051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    )
1052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1053cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CFolders folders;
1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<UInt64> unpackSizes;
1055cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CUInt32DefVector  digests;
1056baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1057baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ReadStreamsInfo(NULL,
1058baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dataOffset,
1059baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    folders,
1060baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    unpackSizes,
1061baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    digests);
1062baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1063f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  CDecoder decoder(_useMixerMT);
1064cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1065cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (CNum i = 0; i < folders.NumFolders; i++)
1066baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1067cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CByteBuffer &data = dataVector.AddNew();
1068cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
1069baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t unpackSize = (size_t)unpackSize64;
1070baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (unpackSize != unpackSize64)
1071baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowUnsupported();
1072cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    data.Alloc(unpackSize);
1073baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1074baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
1075baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
1076baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outStreamSpec->Init(data, unpackSize);
1077baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1078baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = decoder.Decode(
1079f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        EXTERNAL_CODECS_LOC_VARS
1080f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        _stream, baseOffset + dataOffset,
1081f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        folders, i,
1082f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        NULL, // *unpackSize
1083f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1084f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        outStream,
1085f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        NULL, // *compressProgress
1086f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        NULL  // **inStreamMainRes
1087f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1088f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        _7Z_DECODER_CRYPRO_VARS
1089f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        #if !defined(_7ZIP_ST) && !defined(_SFX)
1090f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          , false // mtMode
1091f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka          , 1     // numThreads
1092f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        #endif
1093baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      );
1094baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(result);
1095baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1096cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (folders.FolderCRCs.ValidAndDefined(i))
1097cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
1098baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ThrowIncorrect();
1099baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1100f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1101f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (folders.PackPositions)
1102f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    HeadersSize += folders.PackPositions[folders.NumPackStreams];
1103f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
1105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1107baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadHeader(
1108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
1109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CDbEx &db
1110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _7Z_DECODER_CRYPRO_VARS_DECL
1111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    )
1112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 type = ReadID();
1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == NID::kArchiveProperties)
1116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ReadArchiveProperties(db.ArcInfo);
1118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    type = ReadID();
1119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CByteBuffer> dataVector;
1122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == NID::kAdditionalStreamsInfo)
1124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = ReadAndDecodePackedStreams(
1126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        EXTERNAL_CODECS_LOC_VARS
1127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.ArcInfo.StartPositionAfterHeader,
1128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.ArcInfo.DataStartPosition2,
1129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        dataVector
1130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        _7Z_DECODER_CRYPRO_VARS
1131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        );
1132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(result);
1133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader;
1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    type = ReadID();
1135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRecordVector<UInt64> unpackSizes;
1138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CUInt32DefVector digests;
1139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == NID::kMainStreamsInfo)
1141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ReadStreamsInfo(&dataVector,
1143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.ArcInfo.DataStartPosition,
1144cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        (CFolders &)db,
1145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        unpackSizes,
1146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digests);
1147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader;
1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    type = ReadID();
1149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  db.Files.Clear();
1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type == NID::kFilesInfo)
1154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1156f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  const CNum numFiles = ReadNum();
1157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.Files.ClearAndSetSize(numFiles);
1158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
1159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  db.Files.Reserve(numFiles);
1160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum i;
1161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFiles; i++)
1162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    db.Files.Add(CFileItem());
1163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
1164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
1166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // if (!db.PackSizes.IsEmpty())
1167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo);
1168f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (numFiles > 0 && !digests.Defs.IsEmpty())
1169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
1170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBoolVector emptyStreamVector;
1172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
1173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBoolVector emptyFileVector;
1174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBoolVector antiFileVector;
1175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum numEmptyStreams = 0;
1176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
1178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1179f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    const UInt64 type2 = ReadID();
1180f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (type2 == NID::kEnd)
1181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
1182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 size = ReadNumber();
1183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (size > _inByteBack->GetRem())
1184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ThrowIncorrect();
1185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CStreamSwitch switchProp;
1186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
1187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool addPropIdToList = true;
1188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool isKnownType = true;
1189f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    if (type2 > ((UInt32)1 << 30))
1190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      isKnownType = false;
1191f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    else switch ((UInt32)type2)
1192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NID::kName:
1194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CStreamSwitch streamSwitch;
1196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        streamSwitch.Set(this, &dataVector);
1197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        size_t rem = _inByteBack->GetRem();
1198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.NamesBuf.Alloc(rem);
1199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ReadBytes(db.NamesBuf, rem);
1200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.NameOffsets.Alloc(db.Files.Size() + 1);
1201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        size_t pos = 0;
1202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        unsigned i;
1203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        for (i = 0; i < db.Files.Size(); i++)
1204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          size_t curRem = (rem - pos) / 2;
1206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
1207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          size_t j;
1208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          for (j = 0; j < curRem && buf[j] != 0; j++);
1209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (j == curRem)
1210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            ThrowEndOfData();
1211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          db.NameOffsets[i] = pos / 2;
1212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          pos += j * 2 + 2;
1213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.NameOffsets[i] = pos / 2;
1215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (pos != rem)
1216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThereIsHeaderError = true;
1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kWinAttrib:
1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CBoolVector boolVector;
1222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ReadBoolVector2(db.Files.Size(), boolVector);
1223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        CStreamSwitch streamSwitch;
1224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        streamSwitch.Set(this, &dataVector);
1225f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        for (CNum i = 0; i < numFiles; i++)
1226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
1227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          CFileItem &file = db.Files[i];
1228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          file.AttribDefined = boolVector[i];
1229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (file.AttribDefined)
1230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            file.Attrib = ReadUInt32();
1231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
1232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1234cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /*
1235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kIsAux:
1236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ReadBoolVector(db.Files.Size(), db.IsAux);
1238cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
1239cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kParent:
1241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.IsTree = true;
1243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // CBoolVector boolVector;
1244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // ReadBoolVector2(db.Files.Size(), boolVector);
1245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // CStreamSwitch streamSwitch;
1246cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        // streamSwitch.Set(this, &dataVector);
1247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        CBoolVector boolVector;
1248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ReadBoolVector2(db.Files.Size(), boolVector);
1249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.ThereAreAltStreams = false;
1251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        for (i = 0; i < numFiles; i++)
1252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          CFileItem &file = db.Files[i];
1254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          // file.Parent = -1;
1255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          // if (boolVector[i])
1256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          file.Parent = (int)ReadUInt32();
1257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          file.IsAltStream = !boolVector[i];
1258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          if (file.IsAltStream)
1259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            db.ThereAreAltStreams = true;
1260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
1262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      */
1264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NID::kEmptyStream:
1265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        ReadBoolVector(numFiles, emptyStreamVector);
1267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        numEmptyStreams = 0;
1268f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++)
1269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (emptyStreamVector[i])
1270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            numEmptyStreams++;
1271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        BoolVector_Fill_False(emptyFileVector, numEmptyStreams);
1273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        BoolVector_Fill_False(antiFileVector, numEmptyStreams);
1274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NID::kEmptyFile:  ReadBoolVector(numEmptyStreams, emptyFileVector); break;
1278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NID::kAnti:  ReadBoolVector(numEmptyStreams, antiFileVector); break;
1279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kStartPos:  ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break;
1280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kCTime:  ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break;
1281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kATime:  ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break;
1282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kMTime:  ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break;
1283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case NID::kDummy:
1284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (UInt64 j = 0; j < size; j++)
1286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (ReadByte() != 0)
1287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            ThereIsHeaderError = true;
1288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        addPropIdToList = false;
1289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      /*
1292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      case NID::kNtSecure:
1293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        try
1295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          {
1297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            CStreamSwitch streamSwitch;
1298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            streamSwitch.Set(this, &dataVector);
1299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            UInt32 numDescriptors = ReadUInt32();
1300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            size_t offset = 0;
1301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            db.SecureOffsets.Clear();
1302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            for (i = 0; i < numDescriptors; i++)
1303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            {
1304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              UInt32 size = ReadUInt32();
1305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              db.SecureOffsets.Add(offset);
1306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              offset += size;
1307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            }
1308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            // ThrowIncorrect();;
1309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            db.SecureOffsets.Add(offset);
1310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            db.SecureBuf.SetCapacity(offset);
1311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            for (i = 0; i < numDescriptors; i++)
1312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            {
1313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              offset = db.SecureOffsets[i];
1314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
1315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            }
1316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            db.SecureIDs.Clear();
1317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            for (unsigned i = 0; i < db.Files.Size(); i++)
1318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            {
1319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              db.SecureIDs.Add(ReadNum());
1320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              // db.SecureIDs.Add(ReadUInt32());
1321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            }
1322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            // ReadUInt32();
1323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky            if (_inByteBack->GetRem() != 0)
1324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky              ThrowIncorrect();;
1325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          }
1326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        catch(CInArchiveException &)
1328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
1329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          ThereIsHeaderError = true;
1330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          addPropIdToList = isKnownType = false;
1331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          db.ClearSecure();
1332cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
1333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
1334cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1335cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      */
1336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      default:
1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        addPropIdToList = isKnownType = false;
1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (isKnownType)
1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (addPropIdToList)
1342f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka        db.ArcInfo.FileInfoPopIDs.Add(type2);
1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
1345cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      db.UnsupportedFeatureWarning = true;
1347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _inByteBack->SkipRem();
1348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1349f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02)
1350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (_inByteBack->GetRem() != 0)
1351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowIncorrect();
1352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  type = ReadID(); // Read (NID::kEnd) end of headers
1355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1356f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  if (numFiles - numEmptyStreams != unpackSizes.Size())
1357f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka    ThrowUnsupported();
1358f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum emptyFileIndex = 0;
1360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum sizeIndex = 0;
1361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum numAntiItems = 0;
1363f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1364f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  CNum i;
1365f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numEmptyStreams; i++)
1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (antiFileVector[i])
1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numAntiItems++;
1369f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFiles; i++)
1371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CFileItem &file = db.Files[i];
1373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool isAnti;
1374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    file.HasStream = !emptyStreamVector[i];
1375cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    file.Crc = 0;
1376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (file.HasStream)
1377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      file.IsDir = false;
1379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      isAnti = false;
1380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      file.Size = unpackSizes[sizeIndex];
1381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      file.CrcDefined = digests.ValidAndDefined(sizeIndex);
1382cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (file.CrcDefined)
1383cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        file.Crc = digests.Vals[sizeIndex];
1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sizeIndex++;
1385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      file.IsDir = !emptyFileVector[emptyFileIndex];
1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      isAnti = antiFileVector[emptyFileIndex];
1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      emptyFileIndex++;
1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      file.Size = 0;
1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      file.CrcDefined = false;
1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numAntiItems != 0)
1395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      db.IsAnti.Add(isAnti);
1396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1398cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.FillLinks();
1399cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
1400cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (type != NID::kEnd)
1401cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ThrowIncorrect();
1402cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_inByteBack->GetRem() != 0)
1403cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ThrowIncorrect();
1404cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
1405cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return S_OK;
1406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1408cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CDbEx::FillLinks()
1409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1410f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  FolderStartFileIndex.Alloc(NumFolders);
1411f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka  FileIndexToFolderIndexMap.Alloc(Files.Size());
1412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CNum folderIndex = 0;
1414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CNum indexInFolder = 0;
1415cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned i;
1416f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1417cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (i = 0; i < Files.Size(); i++)
1418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1419cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool emptyStream = !Files[i].HasStream;
1420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (indexInFolder == 0)
1421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (emptyStream)
1423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
1424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        FileIndexToFolderIndexMap[i] = kNumNoIndex;
1425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        continue;
1426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
1427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // v3.13 incorrectly worked with empty folders
1428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      // v4.07: we skip empty folders
1429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (;;)
1430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (folderIndex >= NumFolders)
1432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          ThrowIncorrect();
1433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        FolderStartFileIndex[folderIndex] = i;
1434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (NumUnpackStreamsVector[folderIndex] != 0)
1435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
1436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        folderIndex++;
1437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FileIndexToFolderIndexMap[i] = folderIndex;
1440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (emptyStream)
1441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
1442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (++indexInFolder >= NumUnpackStreamsVector[folderIndex])
1443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      folderIndex++;
1445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      indexInFolder = 0;
1446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (indexInFolder != 0)
1450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folderIndex++;
1451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
1452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (indexInFolder != 0)
1453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ThrowIncorrect();
1454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
1455f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka
1456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (;;)
1457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (folderIndex >= NumFolders)
1459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
1460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FolderStartFileIndex[folderIndex] = i;
1461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    /*
1462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (NumUnpackStreamsVector[folderIndex] != 0)
1463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ThrowIncorrect();;
1464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    */
1465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    folderIndex++;
1466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1469baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadDatabase2(
1470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
1471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CDbEx &db
1472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _7Z_DECODER_CRYPRO_VARS_DECL
1473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    )
1474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  db.Clear();
1476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.ArcInfo.StartPosition = _arhiveBeginStreamPosition;
1477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1478cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.ArcInfo.Version.Major = _header[6];
1479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.ArcInfo.Version.Minor = _header[7];
1480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (db.ArcInfo.Version.Major != kMajorVersion)
1482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // db.UnsupportedVersion = true;
1484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_FALSE;
1485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 nextHeaderOffset = Get64(_header + 12);
1488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt64 nextHeaderSize = Get64(_header + 20);
1489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 nextHeaderCRC = Get32(_header + 28);
1490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef FORMAT_7Z_RECOVERY
1492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 crcFromArc = Get32(_header + 8);
1493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
1494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 cur, fileSize;
1496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
1497cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const unsigned kCheckSize = 512;
1498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte buf[kCheckSize];
1499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
1500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt64 rem = fileSize - cur;
1501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned checkSize = kCheckSize;
1502cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (rem < kCheckSize)
1503cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      checkSize = (unsigned)(rem);
1504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (checkSize < 3)
1505cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_FALSE;
1506cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL));
1507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
1508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (buf[checkSize - 1] != 0)
1510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_FALSE;
1511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned i;
1513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (i = checkSize - 2;; i--)
1514cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
1515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo ||
1516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)
1517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
1518cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (i == 0)
1519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return S_FALSE;
1520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
1521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    nextHeaderSize = checkSize - i;
1522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    nextHeaderOffset = rem - nextHeaderSize;
1523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
1524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
1525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.StartHeaderWasRecovered = true;
1526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
1528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
1529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // Crc was tested already at signature check
1531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect();
1532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
1535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.PhySize = kHeaderSize;
1536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1537cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.IsArc = false;
1538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if ((Int64)nextHeaderOffset < 0 ||
1539cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      nextHeaderSize > ((UInt64)1 << 62))
1540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_FALSE;
1541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (nextHeaderSize == 0)
1542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (nextHeaderOffset != 0)
1544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return S_FALSE;
1545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.IsArc = true;
1546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_OK;
1547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!db.StartHeaderWasRecovered)
1550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.IsArc = true;
1551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  HeadersSize += kHeaderSize + nextHeaderSize;
1553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
1554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize)
1555cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1556cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.UnexpectedEnd = true;
1557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return S_FALSE;
1558cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
1560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size_t nextHeaderSize_t = (size_t)nextHeaderSize;
1562cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (nextHeaderSize_t != nextHeaderSize)
1563cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return E_OUTOFMEMORY;
1564cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CByteBuffer buffer2(nextHeaderSize_t);
1565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1566cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t));
1567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1568cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC)
1569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ThrowIncorrect();
1570cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!db.StartHeaderWasRecovered)
1572cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.PhySizeWasConfirmed = true;
1573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CStreamSwitch streamSwitch;
1575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  streamSwitch.Set(this, buffer2);
1576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CObjectVector<CByteBuffer> dataVector;
1578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 type = ReadID();
1580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type != NID::kHeader)
1581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type != NID::kEncodedHeader)
1583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowIncorrect();
1584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = ReadAndDecodePackedStreams(
1585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        EXTERNAL_CODECS_LOC_VARS
1586cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.ArcInfo.StartPositionAfterHeader,
1587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        db.ArcInfo.DataStartPosition2,
1588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        dataVector
1589cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        _7Z_DECODER_CRYPRO_VARS
1590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        );
1591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(result);
1592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (dataVector.Size() == 0)
1593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
1594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (dataVector.Size() > 1)
1595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowIncorrect();
1596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    streamSwitch.Remove();
1597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    streamSwitch.Set(this, dataVector.Front());
1598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ReadID() != NID::kHeader)
1599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      ThrowIncorrect();
1600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  db.IsArc = true;
1603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
1604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  db.HeadersSize = HeadersSize;
1605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return ReadHeader(
1607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    EXTERNAL_CODECS_LOC_VARS
1608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    db
1609cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _7Z_DECODER_CRYPRO_VARS
1610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    );
1611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1613baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadDatabase(
1614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DECL_EXTERNAL_CODECS_LOC_VARS
1615cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CDbEx &db
1616cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    _7Z_DECODER_CRYPRO_VARS_DECL
1617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    )
1618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  try
1620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1621cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT res = ReadDatabase2(
1622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      EXTERNAL_CODECS_LOC_VARS db
1623cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      _7Z_DECODER_CRYPRO_VARS
1624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      );
1625cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (ThereIsHeaderError)
1626cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      db.ThereIsHeaderError = true;
1627cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (res == E_NOTIMPL)
1628cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ThrowUnsupported();
1629cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return res;
1630cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1631cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  catch(CUnsupportedFeatureException &)
1632cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.UnsupportedFeatureError = true;
1634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_FALSE;
1635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
1636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  catch(CInArchiveException &)
1637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
1638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    db.ThereIsHeaderError = true;
1639cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return S_FALSE;
1640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
1644