1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* 7zIn.c -- 7z Input functions
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync2010-10-29 : Igor Pavlov : Public domain */
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <string.h>
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7z.h"
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zCrc.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "CpuArch.h"
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncByte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NUM_FOLDER_CODERS_MAX 32
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NUM_CODER_STREAMS_MAX 32
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzCoderInfo_Init(CSzCoderInfo *p)
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Buf_Init(&p->Props);
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
22baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Buf_Free(&p->Props, alloc);
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzCoderInfo_Init(p);
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzFolder_Init(CSzFolder *p)
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->Coders = 0;
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->BindPairs = 0;
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->PackStreams = 0;
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->UnpackSizes = 0;
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumCoders = 0;
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumBindPairs = 0;
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumPackStreams = 0;
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->UnpackCRCDefined = 0;
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->UnpackCRC = 0;
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumUnpackStreams = 0;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
42baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (p->Coders)
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < p->NumCoders; i++)
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SzCoderInfo_Free(&p->Coders[i], alloc);
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->Coders);
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->BindPairs);
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->PackStreams);
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->UnpackSizes);
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzFolder_Init(p);
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
55baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 result = 0;
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->NumCoders; i++)
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    result += p->Coders[i].NumOutStreams;
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return result;
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
64baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->NumBindPairs; i++)
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (p->BindPairs[i].InIndex == inStreamIndex)
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return i;
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return -1;
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
74baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->NumBindPairs; i++)
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (p->BindPairs[i].OutIndex == outStreamIndex)
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return i;
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return -1;
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
83baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 SzFolder_GetUnpackSize(CSzFolder *p)
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i = (int)SzFolder_GetNumOutStreams(p);
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (i == 0)
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 0;
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i--; i >= 0; i--)
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (SzFolder_FindBindPairForOutStream(p, i) < 0)
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return p->UnpackSizes[i];
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  /* throw 1; */
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 0;
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
95baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzFile_Init(CSzFileItem *p)
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->HasStream = 1;
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->IsDir = 0;
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->IsAnti = 0;
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->CrcDefined = 0;
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->MTimeDefined = 0;
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
104baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzAr_Init(CSzAr *p)
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->PackSizes = 0;
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->PackCRCsDefined = 0;
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->PackCRCs = 0;
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->Folders = 0;
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->Files = 0;
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumPackStreams = 0;
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumFolders = 0;
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->NumFiles = 0;
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
116baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzAr_Free(CSzAr *p, ISzAlloc *alloc)
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (p->Folders)
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < p->NumFolders; i++)
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SzFolder_Free(&p->Folders[i], alloc);
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->PackSizes);
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->PackCRCsDefined);
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->PackCRCs);
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->Folders);
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->Files);
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzAr_Init(p);
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
132baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzArEx_Init(CSzArEx *p)
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzAr_Init(&p->db);
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->FolderStartPackStreamIndex = 0;
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->PackStreamStartPositions = 0;
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->FolderStartFileIndex = 0;
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->FileIndexToFolderIndexMap = 0;
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->FileNameOffsets = 0;
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Buf_Init(&p->FileNames);
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
143baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->PackStreamStartPositions);
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->FolderStartFileIndex);
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(alloc, p->FileNameOffsets);
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Buf_Free(&p->FileNames, alloc);
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzAr_Free(&p->db, alloc);
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzArEx_Init(p);
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
158baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
163baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 GetFilePackSize(int fileIndex) const
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int folderIndex = FileIndexToFolderIndexMap[fileIndex];
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (folderIndex >= 0)
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CSzFolder &folderInfo = Folders[folderIndex];
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (FolderStartFileIndex[folderIndex] == fileIndex)
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return GetFolderFullPackSize(folderIndex);
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 0;
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
179baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 startPos = 0;
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 startPosSize = 0;
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 folderIndex = 0;
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 indexInFolder = 0;
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->db.NumFolders; i++)
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->FolderStartPackStreamIndex[i] = startPos;
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    startPos += p->db.Folders[i].NumPackStreams;
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->db.NumPackStreams; i++)
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->PackStreamStartPositions[i] = startPosSize;
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    startPosSize += p->db.PackSizes[i];
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->db.NumFiles; i++)
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFileItem *file = p->db.Files + i;
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    int emptyStream = !file->HasStream;
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (emptyStream && indexInFolder == 0)
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (indexInFolder == 0)
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      /*
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      v3.13 incorrectly worked with empty folders
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      v4.07: Loop for skipping empty folders
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      */
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (;;)
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (folderIndex >= p->db.NumFolders)
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return SZ_ERROR_ARCHIVE;
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        p->FolderStartFileIndex[folderIndex] = i;
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        folderIndex++;
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->FileIndexToFolderIndexMap[i] = folderIndex;
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (emptyStream)
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    indexInFolder++;
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      folderIndex++;
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      indexInFolder = 0;
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
243baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return p->dataPos +
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
249baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSzFolder *folder = p->db.Folders + folderIndex;
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 size = 0;
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < folder->NumPackStreams; i++)
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t < size) /* check it */
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_FAIL;
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size = t;
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *resSize = size;
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
268baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes SzReadTime(const CObjectVector<CBuf> &dataVector,
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CObjectVector<CSzFileItem> &files, UInt64 type)
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBoolVector boolVector;
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(ReadBoolVector2(files.Size(), boolVector))
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CStreamSwitch streamSwitch;
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(streamSwitch.Set(this, &dataVector));
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < files.Size(); i++)
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFileItem &file = files[i];
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CArchiveFileTime fileTime;
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool defined = boolVector[i];
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (defined)
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 low, high;
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadUInt32(low));
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadUInt32(high));
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileTime.dwLowDateTime = low;
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileTime.dwHighDateTime = high;
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    switch(type)
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
301baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic int TestSignatureCandidate(Byte *testBytes)
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t i;
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < k7zSignatureSize; i++)
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (testBytes[i] != k7zSignature[i])
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 0;
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 1;
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
310baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef struct _CSzState
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *Data;
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t Size;
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}CSzData;
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
316baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadByte(CSzData *sd, Byte *b)
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (sd->Size == 0)
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_ARCHIVE;
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  sd->Size--;
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *b = *sd->Data++;
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
325baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t i;
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < size; i++)
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadByte(sd, data + i));
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
335baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadUInt32(CSzData *sd, UInt32 *value)
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *value = 0;
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < 4; i++)
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte b;
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadByte(sd, &b));
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *value |= ((UInt32)(b) << (8 * i));
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
348baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadNumber(CSzData *sd, UInt64 *value)
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte firstByte;
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte mask = 0x80;
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadByte(sd, &firstByte));
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *value = 0;
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < 8; i++)
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte b;
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if ((firstByte & mask) == 0)
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 highPart = firstByte & (mask - 1);
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *value += (highPart << (8 * i));
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_OK;
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadByte(sd, &b));
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *value |= ((UInt64)b << (8 * i));
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mask >>= 1;
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
371baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadNumber32(CSzData *sd, UInt32 *value)
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 value64;
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber(sd, &value64));
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (value64 >= 0x80000000)
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_UNSUPPORTED;
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_UNSUPPORTED;
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *value = (UInt32)value64;
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
383baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadID(CSzData *sd, UInt64 *value)
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SzReadNumber(sd, value);
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
388baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (size > sd->Size)
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_ARCHIVE;
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  sd->Size -= (size_t)size;
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  sd->Data += (size_t)size;
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
397baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzSkeepData(CSzData *sd)
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 size;
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber(sd, &size));
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SzSkeepDataSize(sd, size);
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
404baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadArchiveProperties(CSzData *sd)
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type;
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdEnd)
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SzSkeepData(sd);
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
417baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type;
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == attribute)
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_OK;
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdEnd)
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_ARCHIVE;
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzSkeepData(sd));
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
431baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte b = 0;
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte mask = 0;
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t i;
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(Byte, *v, numItems, alloc);
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numItems; i++)
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (mask == 0)
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadByte(sd, &b));
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      mask = 0x80;
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mask >>= 1;
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
450baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte allAreDefined;
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t i;
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadByte(sd, &allAreDefined));
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (allAreDefined == 0)
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SzReadBoolVector(sd, numItems, v, alloc);
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(Byte, *v, numItems, alloc);
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numItems; i++)
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    (*v)[i] = 1;
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
463baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadHashDigests(
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t numItems,
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **digestsDefined,
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 **digests,
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *alloc)
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t i;
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt32, *digests, numItems, alloc);
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numItems; i++)
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if ((*digestsDefined)[i])
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadUInt32(sd, (*digests) + i));
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
481baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadPackInfo(
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 *dataOffset,
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 *numPackStreams,
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 **packSizes,
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **packCRCsDefined,
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 **packCRCs,
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *alloc)
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber(sd, dataOffset));
492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber32(sd, numPackStreams));
493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzWaitAttribute(sd, k7zIdSize));
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < *numPackStreams; i++)
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadNumber(sd, (*packSizes) + i));
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type;
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdEnd)
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdCRC)
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzSkeepData(sd));
515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (*packCRCsDefined == 0)
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < *numPackStreams; i++)
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      (*packCRCsDefined)[i] = 0;
523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      (*packCRCs)[i] = 0;
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
529baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadSwitch(CSzData *sd)
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte external;
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadByte(sd, &external));
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
536baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numCoders, numBindPairs, numPackStreams, i;
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numInStreams = 0, numOutStreams = 0;
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber32(sd, &numCoders));
542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numCoders > NUM_FOLDER_CODERS_MAX)
543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_UNSUPPORTED;
544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folder->NumCoders = numCoders;
545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numCoders; i++)
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SzCoderInfo_Init(folder->Coders + i);
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numCoders; i++)
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte mainByte;
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzCoderInfo *coder = folder->Coders + i;
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      unsigned idSize, j;
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte longID[15];
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadByte(sd, &mainByte));
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      idSize = (unsigned)(mainByte & 0xF);
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadBytes(sd, longID, idSize));
561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (idSize > sizeof(coder->MethodID))
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_UNSUPPORTED;
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      coder->MethodID = 0;
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (j = 0; j < idSize; j++)
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if ((mainByte & 0x10) != 0)
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber32(sd, &coder->NumInStreams));
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return SZ_ERROR_UNSUPPORTED;
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        coder->NumInStreams = 1;
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        coder->NumOutStreams = 1;
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if ((mainByte & 0x20) != 0)
581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt64 propertiesSize = 0;
583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber(sd, &propertiesSize));
584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return SZ_ERROR_MEM;
586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    while ((mainByte & 0x80) != 0)
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadByte(sd, &mainByte));
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if ((mainByte & 0x10) != 0)
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt32 n;
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber32(sd, &n));
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber32(sd, &n));
598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if ((mainByte & 0x20) != 0)
600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt64 propertiesSize = 0;
602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber(sd, &propertiesSize));
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzSkeepDataSize(sd, propertiesSize));
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    numInStreams += coder->NumInStreams;
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    numOutStreams += coder->NumOutStreams;
608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numOutStreams == 0)
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_UNSUPPORTED;
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folder->NumBindPairs = numBindPairs = numOutStreams - 1;
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numBindPairs; i++)
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzBindPair *bp = folder->BindPairs + i;
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadNumber32(sd, &bp->InIndex));
620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadNumber32(sd, &bp->OutIndex));
621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numInStreams < numBindPairs)
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_UNSUPPORTED;
625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numPackStreams == 1)
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numInStreams ; i++)
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (SzFolder_FindBindPairForInStream(folder, i) < 0)
633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (i == numInStreams)
635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_UNSUPPORTED;
636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    folder->PackStreams[0] = i;
637baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numPackStreams; i++)
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadNumber32(sd, folder->PackStreams + i));
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
645baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
646baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadUnpackInfo(
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 *numFolders,
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFolder **folders,  /* for alloc */
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *alloc,
651baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzWaitAttribute(sd, k7zIdFolder));
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber32(sd, numFolders));
656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadSwitch(sd));
658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < *numFolders; i++)
662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SzFolder_Init((*folders) + i);
663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < *numFolders; i++)
665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
667baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < *numFolders; i++)
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 j;
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFolder *folder = (*folders) + i;
676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
680baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (j = 0; j < numOutStreams; j++)
681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type;
689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdEnd)
691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_OK;
692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdCRC)
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SRes res;
695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte *crcsDefined = 0;
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 *crcs = 0;
697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res == SZ_OK)
699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (i = 0; i < *numFolders; i++)
701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          CSzFolder *folder = (*folders) + i;
703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          folder->UnpackCRCDefined = crcsDefined[i];
704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          folder->UnpackCRC = crcs[i];
705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IAlloc_Free(allocTemp, crcs);
708baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IAlloc_Free(allocTemp, crcsDefined);
709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(res);
710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzSkeepData(sd));
713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
716baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadSubStreamsInfo(
717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 numFolders,
719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFolder *folders,
720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 *numUnpackStreams,
721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 **unpackSizes,
722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **digestsDefined,
723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 **digests,
724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 type = 0;
727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 si = 0;
729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numDigests = 0;
730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFolders; i++)
732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    folders[i].NumUnpackStreams = 1;
733baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *numUnpackStreams = numFolders;
734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdNumUnpackStream)
739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *numUnpackStreams = 0;
741baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (i = 0; i < numFolders; i++)
742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        UInt32 numStreams;
744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadNumber32(sd, &numStreams));
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        folders[i].NumUnpackStreams = numStreams;
746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *numUnpackStreams += numStreams;
747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdCRC || type == k7zIdSize)
751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdEnd)
753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzSkeepData(sd));
755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (*numUnpackStreams == 0)
758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
759baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *unpackSizes = 0;
760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *digestsDefined = 0;
761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *digests = 0;
762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOM(*unpackSizes);
767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOM(*digestsDefined);
769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOM(*digests);
771baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFolders; i++)
774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    v3.13 incorrectly worked with empty folders
777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    v4.07: we check that folder is empty
778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 sum = 0;
780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 j;
781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 numSubstreams = folders[i].NumUnpackStreams;
782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numSubstreams == 0)
783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdSize)
785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (j = 1; j < numSubstreams; j++)
786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 size;
788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzReadNumber(sd, &size));
789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      (*unpackSizes)[si++] = size;
790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sum += size;
791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == k7zIdSize)
795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < *numUnpackStreams; i++)
800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    (*digestsDefined)[i] = 0;
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    (*digests)[i] = 0;
803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFolders; i++)
807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 numSubstreams = folders[i].NumUnpackStreams;
809baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numDigests += numSubstreams;
811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  si = 0;
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdCRC)
818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      int digestIndex = 0;
820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte *digestsDefined2 = 0;
821baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 *digests2 = 0;
822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res == SZ_OK)
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (i = 0; i < numFolders; i++)
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          CSzFolder *folder = folders + i;
828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          UInt32 numSubstreams = folder->NumUnpackStreams;
829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (numSubstreams == 1 && folder->UnpackCRCDefined)
830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
831baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            (*digestsDefined)[si] = 1;
832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            (*digests)[si] = folder->UnpackCRC;
833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            si++;
834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          else
836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            UInt32 j;
838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            for (j = 0; j < numSubstreams; j++, digestIndex++)
839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            {
840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              (*digestsDefined)[si] = digestsDefined2[digestIndex];
841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              (*digests)[si] = digests2[digestIndex];
842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              si++;
843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            }
844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IAlloc_Free(allocTemp, digestsDefined2);
848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IAlloc_Free(allocTemp, digests2);
849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(res);
850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else if (type == k7zIdEnd)
852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_OK;
853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzSkeepData(sd));
856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
862baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadStreamsInfo(
863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 *dataOffset,
865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzAr *p,
866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 *numUnpackStreams,
867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 **unpackSizes, /* allocTemp */
868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **digestsDefined,   /* allocTemp */
869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 **digests,        /* allocTemp */
870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *alloc,
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type;
876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if ((UInt64)(int)type != type)
878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_UNSUPPORTED;
879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    switch((int)type)
880baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
881baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdEnd:
882baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_OK;
883baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdPackInfo:
884baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
885baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
886baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
887baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
888baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdUnpackInfo:
890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
891baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
892baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
894baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdSubStreamsInfo:
895baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
896baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
897baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
898baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
899baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
900baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      default:
901baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_UNSUPPORTED;
902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
903baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
904baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
905baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
906baa3858d3f5d128a5c8466b700098109edcad5f2repo syncsize_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (dest != 0)
910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
911baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t i;
912baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);
913baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < len; i++)
914baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      dest[i] = GetUi16(src + i * 2);
915baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
916baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return len;
917baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
918baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
919baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)
920baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
921baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
922baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t pos = 0;
923baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFiles; i++)
924baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
925baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    sizes[i] = pos;
926baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (;;)
927baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
928baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (pos >= size)
929baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_ARCHIVE;
930baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
931baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
932baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      pos++;
933baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
934baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pos++;
935baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
936baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  sizes[i] = pos;
937baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
938baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
939baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
940baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadHeader2(
941baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzArEx *p,   /* allocMain */
942baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
943baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 **unpackSizes,  /* allocTemp */
944baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **digestsDefined,    /* allocTemp */
945baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 **digests,         /* allocTemp */
946baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **emptyStreamVector, /* allocTemp */
947baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **emptyFileVector,   /* allocTemp */
948baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **lwtVector,         /* allocTemp */
949baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocMain,
950baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
951baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
952baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 type;
953baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numUnpackStreams = 0;
954baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numFiles = 0;
955baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSzFileItem *files = 0;
956baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numEmptyStreams = 0;
957baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 i;
958baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
959baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadID(sd, &type));
960baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
961baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == k7zIdArchiveProperties)
962baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
963baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadArchiveProperties(sd));
964baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
965baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
966baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
967baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
968baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == k7zIdMainStreamsInfo)
969baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
970baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadStreamsInfo(sd,
971baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        &p->dataPos,
972baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        &p->db,
973baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        &numUnpackStreams,
974baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        unpackSizes,
975baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digestsDefined,
976baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        digests, allocMain, allocTemp));
977baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->dataPos += p->startPosAfterHeader;
978baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
979baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
980baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
981baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type == k7zIdEnd)
982baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_OK;
983baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (type != k7zIdFilesInfo)
984baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_ARCHIVE;
985baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
986baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadNumber32(sd, &numFiles));
987baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->db.NumFiles = numFiles;
988baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
989baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
990baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
991baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->db.Files = files;
992baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < numFiles; i++)
993baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SzFile_Init(files + i);
994baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
995baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
996baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
997baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 type;
998baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 size;
999baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadID(sd, &type));
1000baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (type == k7zIdEnd)
1001baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
1002baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(SzReadNumber(sd, &size));
1003baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (size > sd->Size)
1004baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_ARCHIVE;
1005baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if ((UInt64)(int)type != type)
1006baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1007baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(SzSkeepDataSize(sd, size));
1008baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1009baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
1010baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    switch((int)type)
1011baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1012baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdName:
1013baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1014baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        size_t namesSize;
1015baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadSwitch(sd));
1016baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        namesSize = (size_t)size - 1;
1017baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if ((namesSize & 1) != 0)
1018baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return SZ_ERROR_ARCHIVE;
1019baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!Buf_Create(&p->FileNames, namesSize, allocMain))
1020baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return SZ_ERROR_MEM;
1021baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
1022baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        memcpy(p->FileNames.data, sd->Data, namesSize);
1023baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
1024baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzSkeepDataSize(sd, namesSize));
1025baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1026baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1027baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdEmptyStream:
1028baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1029baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
1030baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        numEmptyStreams = 0;
1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (i = 0; i < numFiles; i++)
1032baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if ((*emptyStreamVector)[i])
1033baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            numEmptyStreams++;
1034baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1035baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1036baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdEmptyFile:
1037baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1038baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
1039baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1040baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1041baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdWinAttributes:
1042baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1043baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
1044baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadSwitch(sd));
1045baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (i = 0; i < numFiles; i++)
1046baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
1047baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          CSzFileItem *f = &files[i];
1048baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          Byte defined = (*lwtVector)[i];
1049baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          f->AttribDefined = defined;
1050baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          f->Attrib = 0;
1051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (defined)
1052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
1053baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            RINOK(SzReadUInt32(sd, &f->Attrib));
1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
1055baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
1056baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        IAlloc_Free(allocTemp, *lwtVector);
1057baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *lwtVector = NULL;
1058baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1059baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1060baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      case k7zIdMTime:
1061baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1062baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
1063baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzReadSwitch(sd));
1064baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        for (i = 0; i < numFiles; i++)
1065baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
1066baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          CSzFileItem *f = &files[i];
1067baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          Byte defined = (*lwtVector)[i];
1068baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          f->MTimeDefined = defined;
1069baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          f->MTime.Low = f->MTime.High = 0;
1070baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (defined)
1071baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
1072baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            RINOK(SzReadUInt32(sd, &f->MTime.Low));
1073baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            RINOK(SzReadUInt32(sd, &f->MTime.High));
1074baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
1075baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
1076baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        IAlloc_Free(allocTemp, *lwtVector);
1077baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *lwtVector = NULL;
1078baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
1079baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1080baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      default:
1081baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1082baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        RINOK(SzSkeepDataSize(sd, size));
1083baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1084baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1085baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1086baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1087baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1088baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 emptyFileIndex = 0;
1089baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 sizeIndex = 0;
1090baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < numFiles; i++)
1091baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1092baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CSzFileItem *file = files + i;
1093baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      file->IsAnti = 0;
1094baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (*emptyStreamVector == 0)
1095baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->HasStream = 1;
1096baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
1097baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
1098baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (file->HasStream)
1099baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->IsDir = 0;
1101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->Size = (*unpackSizes)[sizeIndex];
1102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->Crc = (*digests)[sizeIndex];
1103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
1104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        sizeIndex++;
1105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
1107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (*emptyFileVector == 0)
1109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          file->IsDir = 1;
1110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
1111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
1112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        emptyFileIndex++;
1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->Size = 0;
1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->Crc = 0;
1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        file->CrcDefined = 0;
1116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SzArEx_Fill(p, allocMain);
1120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1122baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadHeader(
1123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzArEx *p,
1124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
1125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocMain,
1126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
1127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 *unpackSizes = 0;
1129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *digestsDefined = 0;
1130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 *digests = 0;
1131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *emptyStreamVector = 0;
1132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *emptyFileVector = 0;
1133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *lwtVector = 0;
1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res = SzReadHeader2(p, sd,
1135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      &unpackSizes, &digestsDefined, &digests,
1136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      &emptyStreamVector, &emptyFileVector, &lwtVector,
1137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      allocMain, allocTemp);
1138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, unpackSizes);
1139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, digestsDefined);
1140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, digests);
1141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, emptyStreamVector);
1142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, emptyFileVector);
1143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, lwtVector);
1144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
1145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1147baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadAndDecodePackedStreams2(
1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ILookInStream *inStream,
1149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CBuf *outBuffer,
1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 baseOffset,
1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzAr *p,
1153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 **unpackSizes,
1154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **digestsDefined,
1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 **digests,
1156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
1157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 numUnpackStreams = 0;
1160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 dataStartPos;
1161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSzFolder *folder;
1162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 unpackSize;
1163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res;
1164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
1166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      &numUnpackStreams,  unpackSizes, digestsDefined, digests,
1167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      allocTemp, allocTemp));
1168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  dataStartPos += baseOffset;
1170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (p->NumFolders != 1)
1171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_ARCHIVE;
1172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  folder = p->Folders;
1174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  unpackSize = SzFolder_GetUnpackSize(folder);
1175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(LookInStream_SeekTo(inStream, dataStartPos));
1177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
1179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_MEM;
1180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res = SzFolder_Decode(folder, p->PackSizes,
1182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          inStream, dataStartPos,
1183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          outBuffer->data, (size_t)unpackSize, allocTemp);
1184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(res);
1185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (folder->UnpackCRCDefined)
1186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
1187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_CRC;
1188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
1189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1191baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzReadAndDecodePackedStreams(
1192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ILookInStream *inStream,
1193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzData *sd,
1194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CBuf *outBuffer,
1195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 baseOffset,
1196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
1197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSzAr p;
1199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 *unpackSizes = 0;
1200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *digestsDefined = 0;
1201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 *digests = 0;
1202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res;
1203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzAr_Init(&p);
1204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
1205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    &p, &unpackSizes, &digestsDefined, &digests,
1206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    allocTemp);
1207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SzAr_Free(&p, allocTemp);
1208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, unpackSizes);
1209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, digestsDefined);
1210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(allocTemp, digests);
1211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
1212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1214baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes SzArEx_Open2(
1215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzArEx *p,
1216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ILookInStream *inStream,
1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocMain,
1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
1219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte header[k7zStartHeaderSize];
1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Int64 startArcPos;
1222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 nextHeaderOffset, nextHeaderSize;
1223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t nextHeaderSizeT;
1224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 nextHeaderCRC;
1225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CBuf buffer;
1226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res;
1227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  startArcPos = 0;
1229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
1230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
1232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!TestSignatureCandidate(header))
1234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_NO_ARCHIVE;
1235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (header[6] != k7zMajorVersion)
1236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_UNSUPPORTED;
1237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  nextHeaderOffset = GetUi64(header + 12);
1239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  nextHeaderSize = GetUi64(header + 20);
1240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  nextHeaderCRC = GetUi32(header + 28);
1241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
1243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
1245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_CRC;
1246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  nextHeaderSizeT = (size_t)nextHeaderSize;
1248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (nextHeaderSizeT != nextHeaderSize)
1249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_MEM;
1250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (nextHeaderSizeT == 0)
1251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_OK;
1252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
1253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
1254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_NO_ARCHIVE;
1255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Int64 pos = 0;
1258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
1259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if ((UInt64)pos < startArcPos + nextHeaderOffset ||
1260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
1261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
1262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_INPUT_EOF;
1263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
1266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
1268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_MEM;
1269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
1271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
1272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = SZ_ERROR_ARCHIVE;
1274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
1275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CSzData sd;
1277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 type;
1278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sd.Data = buffer.data;
1279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sd.Size = buffer.size;
1280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      res = SzReadID(&sd, &type);
1281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res == SZ_OK)
1282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (type == k7zIdEncodedHeader)
1284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
1285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          CBuf outBuffer;
1286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          Buf_Init(&outBuffer);
1287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
1288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (res != SZ_OK)
1289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            Buf_Free(&outBuffer, allocTemp);
1290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          else
1291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
1292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            Buf_Free(&buffer, allocTemp);
1293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            buffer.data = outBuffer.data;
1294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            buffer.size = outBuffer.size;
1295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            sd.Data = buffer.data;
1296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            sd.Size = buffer.size;
1297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            res = SzReadID(&sd, &type);
1298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
1299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
1300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res == SZ_OK)
1302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (type == k7zIdHeader)
1304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SzReadHeader(p, &sd, allocMain, allocTemp);
1305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        else
1306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SZ_ERROR_UNSUPPORTED;
1307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Buf_Free(&buffer, allocTemp);
1311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
1312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1314baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
1315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
1317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res != SZ_OK)
1318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    SzArEx_Free(p, allocMain);
1319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
1320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1322baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes SzArEx_Extract(
1323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CSzArEx *p,
1324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ILookInStream *inStream,
1325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 fileIndex,
1326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 *blockIndex,
1327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte **outBuffer,
1328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t *outBufferSize,
1329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t *offset,
1330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t *outSizeProcessed,
1331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocMain,
1332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *allocTemp)
1333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
1334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
1335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res = SZ_OK;
1336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *offset = 0;
1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *outSizeProcessed = 0;
1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (folderIndex == (UInt32)-1)
1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IAlloc_Free(allocMain, *outBuffer);
1341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *blockIndex = folderIndex;
1342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outBuffer = 0;
1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outBufferSize = 0;
1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_OK;
1345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (*outBuffer == 0 || *blockIndex != folderIndex)
1348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFolder *folder = p->db.Folders + folderIndex;
1350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
1351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t unpackSize = (size_t)unpackSizeSpec;
1352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (unpackSize != unpackSizeSpec)
1355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_MEM;
1356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *blockIndex = folderIndex;
1357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IAlloc_Free(allocMain, *outBuffer);
1358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outBuffer = 0;
1359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    RINOK(LookInStream_SeekTo(inStream, startOffset));
1361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
1362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res == SZ_OK)
1363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
1364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *outBufferSize = unpackSize;
1365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (unpackSize != 0)
1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (*outBuffer == 0)
1369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SZ_ERROR_MEM;
1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res == SZ_OK)
1372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
1373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        res = SzFolder_Decode(folder,
1374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
1375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          inStream, startOffset,
1376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          *outBuffer, unpackSize, allocTemp);
1377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (res == SZ_OK)
1378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
1379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          if (folder->UnpackCRCDefined)
1380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          {
1381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync            if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
1382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync              res = SZ_ERROR_CRC;
1383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          }
1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
1385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
1386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 i;
1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSzFileItem *fileItem = p->db.Files + fileIndex;
1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *offset = 0;
1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
1394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      *offset += (UInt32)p->db.Files[i].Size;
1395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *outSizeProcessed = (size_t)fileItem->Size;
1396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (*offset + *outSizeProcessed > *outBufferSize)
1397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_FAIL;
1398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
1399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      res = SZ_ERROR_CRC;
1400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
1401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
1402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
1403