1*f6dc9357SAndroid Build Coastguard Worker // AgentProxy.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
7*f6dc9357SAndroid Build Coastguard Worker #include <wchar.h>
8*f6dc9357SAndroid Build Coastguard Worker #else
9*f6dc9357SAndroid Build Coastguard Worker #include <ctype.h>
10*f6dc9357SAndroid Build Coastguard Worker #endif
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/Sort.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/UTFConvert.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
20*f6dc9357SAndroid Build Coastguard Worker
21*f6dc9357SAndroid Build Coastguard Worker #include "../../Archive/Common/ItemNameUtils.h"
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker #include "AgentProxy.h"
24*f6dc9357SAndroid Build Coastguard Worker
25*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
26*f6dc9357SAndroid Build Coastguard Worker
FindSubDir(unsigned dirIndex,const wchar_t * name,unsigned & insertPos) const27*f6dc9357SAndroid Build Coastguard Worker int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name, unsigned &insertPos) const
28*f6dc9357SAndroid Build Coastguard Worker {
29*f6dc9357SAndroid Build Coastguard Worker const CRecordVector<unsigned> &subDirs = Dirs[dirIndex].SubDirs;
30*f6dc9357SAndroid Build Coastguard Worker unsigned left = 0, right = subDirs.Size();
31*f6dc9357SAndroid Build Coastguard Worker for (;;)
32*f6dc9357SAndroid Build Coastguard Worker {
33*f6dc9357SAndroid Build Coastguard Worker if (left == right)
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker insertPos = left;
36*f6dc9357SAndroid Build Coastguard Worker return -1;
37*f6dc9357SAndroid Build Coastguard Worker }
38*f6dc9357SAndroid Build Coastguard Worker const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
39*f6dc9357SAndroid Build Coastguard Worker const unsigned dirIndex2 = subDirs[mid];
40*f6dc9357SAndroid Build Coastguard Worker const int comp = CompareFileNames(name, Dirs[dirIndex2].Name);
41*f6dc9357SAndroid Build Coastguard Worker if (comp == 0)
42*f6dc9357SAndroid Build Coastguard Worker return (int)dirIndex2;
43*f6dc9357SAndroid Build Coastguard Worker if (comp < 0)
44*f6dc9357SAndroid Build Coastguard Worker right = mid;
45*f6dc9357SAndroid Build Coastguard Worker else
46*f6dc9357SAndroid Build Coastguard Worker left = mid + 1;
47*f6dc9357SAndroid Build Coastguard Worker }
48*f6dc9357SAndroid Build Coastguard Worker }
49*f6dc9357SAndroid Build Coastguard Worker
FindSubDir(unsigned dirIndex,const wchar_t * name) const50*f6dc9357SAndroid Build Coastguard Worker int CProxyArc::FindSubDir(unsigned dirIndex, const wchar_t *name) const
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker unsigned insertPos;
53*f6dc9357SAndroid Build Coastguard Worker return FindSubDir(dirIndex, name, insertPos);
54*f6dc9357SAndroid Build Coastguard Worker }
55*f6dc9357SAndroid Build Coastguard Worker
AllocStringAndCopy(const wchar_t * s,size_t len)56*f6dc9357SAndroid Build Coastguard Worker static const wchar_t *AllocStringAndCopy(const wchar_t *s, size_t len)
57*f6dc9357SAndroid Build Coastguard Worker {
58*f6dc9357SAndroid Build Coastguard Worker wchar_t *p = new wchar_t[len + 1];
59*f6dc9357SAndroid Build Coastguard Worker MyStringCopy(p, s);
60*f6dc9357SAndroid Build Coastguard Worker return p;
61*f6dc9357SAndroid Build Coastguard Worker }
62*f6dc9357SAndroid Build Coastguard Worker
AllocStringAndCopy(const UString & s)63*f6dc9357SAndroid Build Coastguard Worker static const wchar_t *AllocStringAndCopy(const UString &s)
64*f6dc9357SAndroid Build Coastguard Worker {
65*f6dc9357SAndroid Build Coastguard Worker return AllocStringAndCopy(s, s.Len());
66*f6dc9357SAndroid Build Coastguard Worker }
67*f6dc9357SAndroid Build Coastguard Worker
AddDir(unsigned dirIndex,int arcIndex,const UString & name)68*f6dc9357SAndroid Build Coastguard Worker unsigned CProxyArc::AddDir(unsigned dirIndex, int arcIndex, const UString &name)
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker unsigned insertPos;
71*f6dc9357SAndroid Build Coastguard Worker int subDirIndex = FindSubDir(dirIndex, name, insertPos);
72*f6dc9357SAndroid Build Coastguard Worker if (subDirIndex != -1)
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker if (arcIndex != -1)
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker CProxyDir &item = Dirs[(unsigned)subDirIndex];
77*f6dc9357SAndroid Build Coastguard Worker if (item.ArcIndex == -1)
78*f6dc9357SAndroid Build Coastguard Worker item.ArcIndex = arcIndex;
79*f6dc9357SAndroid Build Coastguard Worker }
80*f6dc9357SAndroid Build Coastguard Worker return (unsigned)subDirIndex;
81*f6dc9357SAndroid Build Coastguard Worker }
82*f6dc9357SAndroid Build Coastguard Worker subDirIndex = (int)Dirs.Size();
83*f6dc9357SAndroid Build Coastguard Worker Dirs[dirIndex].SubDirs.Insert(insertPos, (unsigned)subDirIndex);
84*f6dc9357SAndroid Build Coastguard Worker CProxyDir &item = Dirs.AddNew();
85*f6dc9357SAndroid Build Coastguard Worker
86*f6dc9357SAndroid Build Coastguard Worker item.NameLen = name.Len();
87*f6dc9357SAndroid Build Coastguard Worker item.Name = AllocStringAndCopy(name);
88*f6dc9357SAndroid Build Coastguard Worker
89*f6dc9357SAndroid Build Coastguard Worker item.ArcIndex = arcIndex;
90*f6dc9357SAndroid Build Coastguard Worker item.ParentDir = (int)dirIndex;
91*f6dc9357SAndroid Build Coastguard Worker return (unsigned)subDirIndex;
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker
Clear()94*f6dc9357SAndroid Build Coastguard Worker void CProxyDir::Clear()
95*f6dc9357SAndroid Build Coastguard Worker {
96*f6dc9357SAndroid Build Coastguard Worker SubDirs.Clear();
97*f6dc9357SAndroid Build Coastguard Worker SubFiles.Clear();
98*f6dc9357SAndroid Build Coastguard Worker }
99*f6dc9357SAndroid Build Coastguard Worker
GetDirPathParts(unsigned dirIndex,UStringVector & pathParts) const100*f6dc9357SAndroid Build Coastguard Worker void CProxyArc::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts) const
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker pathParts.Clear();
103*f6dc9357SAndroid Build Coastguard Worker // while (dirIndex != -1)
104*f6dc9357SAndroid Build Coastguard Worker for (;;)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker const CProxyDir &dir = Dirs[dirIndex];
107*f6dc9357SAndroid Build Coastguard Worker dirIndex = (unsigned)dir.ParentDir;
108*f6dc9357SAndroid Build Coastguard Worker if (dir.ParentDir == -1)
109*f6dc9357SAndroid Build Coastguard Worker break;
110*f6dc9357SAndroid Build Coastguard Worker pathParts.Insert(0, dir.Name);
111*f6dc9357SAndroid Build Coastguard Worker // 22.00: we normalize name
112*f6dc9357SAndroid Build Coastguard Worker NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(pathParts[0]);
113*f6dc9357SAndroid Build Coastguard Worker }
114*f6dc9357SAndroid Build Coastguard Worker }
115*f6dc9357SAndroid Build Coastguard Worker
GetDirPath_as_Prefix(unsigned dirIndex) const116*f6dc9357SAndroid Build Coastguard Worker UString CProxyArc::GetDirPath_as_Prefix(unsigned dirIndex) const
117*f6dc9357SAndroid Build Coastguard Worker {
118*f6dc9357SAndroid Build Coastguard Worker UString s;
119*f6dc9357SAndroid Build Coastguard Worker // while (dirIndex != -1)
120*f6dc9357SAndroid Build Coastguard Worker for (;;)
121*f6dc9357SAndroid Build Coastguard Worker {
122*f6dc9357SAndroid Build Coastguard Worker const CProxyDir &dir = Dirs[dirIndex];
123*f6dc9357SAndroid Build Coastguard Worker dirIndex = (unsigned)dir.ParentDir;
124*f6dc9357SAndroid Build Coastguard Worker if (dir.ParentDir == -1)
125*f6dc9357SAndroid Build Coastguard Worker break;
126*f6dc9357SAndroid Build Coastguard Worker s.InsertAtFront(WCHAR_PATH_SEPARATOR);
127*f6dc9357SAndroid Build Coastguard Worker s.Insert(0, dir.Name);
128*f6dc9357SAndroid Build Coastguard Worker // 22.00: we normalize name
129*f6dc9357SAndroid Build Coastguard Worker NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s.GetBuf(), MyStringLen(dir.Name));
130*f6dc9357SAndroid Build Coastguard Worker }
131*f6dc9357SAndroid Build Coastguard Worker return s;
132*f6dc9357SAndroid Build Coastguard Worker }
133*f6dc9357SAndroid Build Coastguard Worker
AddRealIndices(unsigned dirIndex,CUIntVector & realIndices) const134*f6dc9357SAndroid Build Coastguard Worker void CProxyArc::AddRealIndices(unsigned dirIndex, CUIntVector &realIndices) const
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker const CProxyDir &dir = Dirs[dirIndex];
137*f6dc9357SAndroid Build Coastguard Worker if (dir.IsLeaf())
138*f6dc9357SAndroid Build Coastguard Worker realIndices.Add((unsigned)dir.ArcIndex);
139*f6dc9357SAndroid Build Coastguard Worker unsigned i;
140*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < dir.SubDirs.Size(); i++)
141*f6dc9357SAndroid Build Coastguard Worker AddRealIndices(dir.SubDirs[i], realIndices);
142*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < dir.SubFiles.Size(); i++)
143*f6dc9357SAndroid Build Coastguard Worker realIndices.Add(dir.SubFiles[i]);
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker
GetRealIndex(unsigned dirIndex,unsigned index) const146*f6dc9357SAndroid Build Coastguard Worker int CProxyArc::GetRealIndex(unsigned dirIndex, unsigned index) const
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker const CProxyDir &dir = Dirs[dirIndex];
149*f6dc9357SAndroid Build Coastguard Worker const unsigned numDirItems = dir.SubDirs.Size();
150*f6dc9357SAndroid Build Coastguard Worker if (index < numDirItems)
151*f6dc9357SAndroid Build Coastguard Worker {
152*f6dc9357SAndroid Build Coastguard Worker const CProxyDir &f = Dirs[dir.SubDirs[index]];
153*f6dc9357SAndroid Build Coastguard Worker if (f.IsLeaf())
154*f6dc9357SAndroid Build Coastguard Worker return f.ArcIndex;
155*f6dc9357SAndroid Build Coastguard Worker return -1;
156*f6dc9357SAndroid Build Coastguard Worker }
157*f6dc9357SAndroid Build Coastguard Worker return (int)dir.SubFiles[index - numDirItems];
158*f6dc9357SAndroid Build Coastguard Worker }
159*f6dc9357SAndroid Build Coastguard Worker
GetRealIndices(unsigned dirIndex,const UInt32 * indices,UInt32 numItems,CUIntVector & realIndices) const160*f6dc9357SAndroid Build Coastguard Worker void CProxyArc::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const
161*f6dc9357SAndroid Build Coastguard Worker {
162*f6dc9357SAndroid Build Coastguard Worker const CProxyDir &dir = Dirs[dirIndex];
163*f6dc9357SAndroid Build Coastguard Worker realIndices.Clear();
164*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numItems; i++)
165*f6dc9357SAndroid Build Coastguard Worker {
166*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = indices[i];
167*f6dc9357SAndroid Build Coastguard Worker const unsigned numDirItems = dir.SubDirs.Size();
168*f6dc9357SAndroid Build Coastguard Worker if (index < numDirItems)
169*f6dc9357SAndroid Build Coastguard Worker AddRealIndices(dir.SubDirs[index], realIndices);
170*f6dc9357SAndroid Build Coastguard Worker else
171*f6dc9357SAndroid Build Coastguard Worker realIndices.Add(dir.SubFiles[index - numDirItems]);
172*f6dc9357SAndroid Build Coastguard Worker }
173*f6dc9357SAndroid Build Coastguard Worker HeapSort(realIndices.NonConstData(), realIndices.Size());
174*f6dc9357SAndroid Build Coastguard Worker }
175*f6dc9357SAndroid Build Coastguard Worker
176*f6dc9357SAndroid Build Coastguard Worker ///////////////////////////////////////////////
177*f6dc9357SAndroid Build Coastguard Worker // CProxyArc
178*f6dc9357SAndroid Build Coastguard Worker
GetSize(IInArchive * archive,UInt32 index,PROPID propID,UInt64 & size)179*f6dc9357SAndroid Build Coastguard Worker static bool GetSize(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &size)
180*f6dc9357SAndroid Build Coastguard Worker {
181*f6dc9357SAndroid Build Coastguard Worker size = 0;
182*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
183*f6dc9357SAndroid Build Coastguard Worker if (archive->GetProperty(index, propID, &prop) != S_OK)
184*f6dc9357SAndroid Build Coastguard Worker throw 20120228;
185*f6dc9357SAndroid Build Coastguard Worker return ConvertPropVariantToUInt64(prop, size);
186*f6dc9357SAndroid Build Coastguard Worker }
187*f6dc9357SAndroid Build Coastguard Worker
CalculateSizes(unsigned dirIndex,IInArchive * archive)188*f6dc9357SAndroid Build Coastguard Worker void CProxyArc::CalculateSizes(unsigned dirIndex, IInArchive *archive)
189*f6dc9357SAndroid Build Coastguard Worker {
190*f6dc9357SAndroid Build Coastguard Worker CProxyDir &dir = Dirs[dirIndex];
191*f6dc9357SAndroid Build Coastguard Worker dir.Size = dir.PackSize = 0;
192*f6dc9357SAndroid Build Coastguard Worker dir.NumSubDirs = dir.SubDirs.Size();
193*f6dc9357SAndroid Build Coastguard Worker dir.NumSubFiles = dir.SubFiles.Size();
194*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = true;
195*f6dc9357SAndroid Build Coastguard Worker dir.Crc = 0;
196*f6dc9357SAndroid Build Coastguard Worker
197*f6dc9357SAndroid Build Coastguard Worker unsigned i;
198*f6dc9357SAndroid Build Coastguard Worker
199*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < dir.SubFiles.Size(); i++)
200*f6dc9357SAndroid Build Coastguard Worker {
201*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = (UInt32)dir.SubFiles[i];
202*f6dc9357SAndroid Build Coastguard Worker UInt64 size, packSize;
203*f6dc9357SAndroid Build Coastguard Worker const bool sizeDefined = GetSize(archive, index, kpidSize, size);
204*f6dc9357SAndroid Build Coastguard Worker dir.Size += size;
205*f6dc9357SAndroid Build Coastguard Worker GetSize(archive, index, kpidPackSize, packSize);
206*f6dc9357SAndroid Build Coastguard Worker dir.PackSize += packSize;
207*f6dc9357SAndroid Build Coastguard Worker {
208*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
209*f6dc9357SAndroid Build Coastguard Worker if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
210*f6dc9357SAndroid Build Coastguard Worker {
211*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_UI4)
212*f6dc9357SAndroid Build Coastguard Worker dir.Crc += prop.ulVal;
213*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
214*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = false;
215*f6dc9357SAndroid Build Coastguard Worker }
216*f6dc9357SAndroid Build Coastguard Worker else
217*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = false;
218*f6dc9357SAndroid Build Coastguard Worker }
219*f6dc9357SAndroid Build Coastguard Worker }
220*f6dc9357SAndroid Build Coastguard Worker
221*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < dir.SubDirs.Size(); i++)
222*f6dc9357SAndroid Build Coastguard Worker {
223*f6dc9357SAndroid Build Coastguard Worker unsigned subDirIndex = dir.SubDirs[i];
224*f6dc9357SAndroid Build Coastguard Worker CalculateSizes(subDirIndex, archive);
225*f6dc9357SAndroid Build Coastguard Worker CProxyDir &f = Dirs[subDirIndex];
226*f6dc9357SAndroid Build Coastguard Worker dir.Size += f.Size;
227*f6dc9357SAndroid Build Coastguard Worker dir.PackSize += f.PackSize;
228*f6dc9357SAndroid Build Coastguard Worker dir.NumSubFiles += f.NumSubFiles;
229*f6dc9357SAndroid Build Coastguard Worker dir.NumSubDirs += f.NumSubDirs;
230*f6dc9357SAndroid Build Coastguard Worker dir.Crc += f.Crc;
231*f6dc9357SAndroid Build Coastguard Worker if (!f.CrcIsDefined)
232*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = false;
233*f6dc9357SAndroid Build Coastguard Worker }
234*f6dc9357SAndroid Build Coastguard Worker }
235*f6dc9357SAndroid Build Coastguard Worker
Load(const CArc & arc,IProgress * progress)236*f6dc9357SAndroid Build Coastguard Worker HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
237*f6dc9357SAndroid Build Coastguard Worker {
238*f6dc9357SAndroid Build Coastguard Worker // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {
239*f6dc9357SAndroid Build Coastguard Worker
240*f6dc9357SAndroid Build Coastguard Worker Files.Free();
241*f6dc9357SAndroid Build Coastguard Worker Dirs.Clear();
242*f6dc9357SAndroid Build Coastguard Worker
243*f6dc9357SAndroid Build Coastguard Worker Dirs.AddNew();
244*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = arc.Archive;
245*f6dc9357SAndroid Build Coastguard Worker
246*f6dc9357SAndroid Build Coastguard Worker UInt32 numItems;
247*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetNumberOfItems(&numItems))
248*f6dc9357SAndroid Build Coastguard Worker
249*f6dc9357SAndroid Build Coastguard Worker if (progress)
250*f6dc9357SAndroid Build Coastguard Worker RINOK(progress->SetTotal(numItems))
251*f6dc9357SAndroid Build Coastguard Worker
252*f6dc9357SAndroid Build Coastguard Worker Files.Alloc(numItems);
253*f6dc9357SAndroid Build Coastguard Worker
254*f6dc9357SAndroid Build Coastguard Worker UString path;
255*f6dc9357SAndroid Build Coastguard Worker UString name;
256*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
257*f6dc9357SAndroid Build Coastguard Worker
258*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numItems; i++)
259*f6dc9357SAndroid Build Coastguard Worker {
260*f6dc9357SAndroid Build Coastguard Worker if (progress && (i & 0xFFFF) == 0)
261*f6dc9357SAndroid Build Coastguard Worker {
262*f6dc9357SAndroid Build Coastguard Worker const UInt64 currentItemIndex = i;
263*f6dc9357SAndroid Build Coastguard Worker RINOK(progress->SetCompleted(¤tItemIndex))
264*f6dc9357SAndroid Build Coastguard Worker }
265*f6dc9357SAndroid Build Coastguard Worker
266*f6dc9357SAndroid Build Coastguard Worker const wchar_t *s = NULL;
267*f6dc9357SAndroid Build Coastguard Worker unsigned len = 0;
268*f6dc9357SAndroid Build Coastguard Worker bool isPtrName = false;
269*f6dc9357SAndroid Build Coastguard Worker
270*f6dc9357SAndroid Build Coastguard Worker #if WCHAR_PATH_SEPARATOR != L'/'
271*f6dc9357SAndroid Build Coastguard Worker wchar_t separatorChar = WCHAR_PATH_SEPARATOR;
272*f6dc9357SAndroid Build Coastguard Worker #endif
273*f6dc9357SAndroid Build Coastguard Worker
274*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_LE) && defined(_WIN32)
275*f6dc9357SAndroid Build Coastguard Worker // it works only if (sizeof(wchar_t) == 2)
276*f6dc9357SAndroid Build Coastguard Worker if (arc.GetRawProps)
277*f6dc9357SAndroid Build Coastguard Worker {
278*f6dc9357SAndroid Build Coastguard Worker const void *p;
279*f6dc9357SAndroid Build Coastguard Worker UInt32 size;
280*f6dc9357SAndroid Build Coastguard Worker UInt32 propType;
281*f6dc9357SAndroid Build Coastguard Worker if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK
282*f6dc9357SAndroid Build Coastguard Worker && propType == NPropDataType::kUtf16z
283*f6dc9357SAndroid Build Coastguard Worker && size > 2)
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker // is (size <= 2), it's empty name, and we call default arc.GetItemPath();
286*f6dc9357SAndroid Build Coastguard Worker len = size / 2 - 1;
287*f6dc9357SAndroid Build Coastguard Worker s = (const wchar_t *)p;
288*f6dc9357SAndroid Build Coastguard Worker isPtrName = true;
289*f6dc9357SAndroid Build Coastguard Worker #if WCHAR_PATH_SEPARATOR != L'/'
290*f6dc9357SAndroid Build Coastguard Worker separatorChar = L'/'; // 0
291*f6dc9357SAndroid Build Coastguard Worker #endif
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker }
294*f6dc9357SAndroid Build Coastguard Worker if (!s)
295*f6dc9357SAndroid Build Coastguard Worker #endif
296*f6dc9357SAndroid Build Coastguard Worker {
297*f6dc9357SAndroid Build Coastguard Worker prop.Clear();
298*f6dc9357SAndroid Build Coastguard Worker RINOK(arc.Archive->GetProperty(i, kpidPath, &prop))
299*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BSTR)
300*f6dc9357SAndroid Build Coastguard Worker {
301*f6dc9357SAndroid Build Coastguard Worker s = prop.bstrVal;
302*f6dc9357SAndroid Build Coastguard Worker len = ::SysStringLen(prop.bstrVal);
303*f6dc9357SAndroid Build Coastguard Worker }
304*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY)
305*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
306*f6dc9357SAndroid Build Coastguard Worker if (len == 0)
307*f6dc9357SAndroid Build Coastguard Worker {
308*f6dc9357SAndroid Build Coastguard Worker RINOK(arc.GetItem_DefaultPath(i, path))
309*f6dc9357SAndroid Build Coastguard Worker len = path.Len();
310*f6dc9357SAndroid Build Coastguard Worker s = path;
311*f6dc9357SAndroid Build Coastguard Worker }
312*f6dc9357SAndroid Build Coastguard Worker
313*f6dc9357SAndroid Build Coastguard Worker /*
314*f6dc9357SAndroid Build Coastguard Worker RINOK(arc.GetItemPath(i, path));
315*f6dc9357SAndroid Build Coastguard Worker len = path.Len();
316*f6dc9357SAndroid Build Coastguard Worker s = path;
317*f6dc9357SAndroid Build Coastguard Worker */
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker
320*f6dc9357SAndroid Build Coastguard Worker unsigned curItem = 0;
321*f6dc9357SAndroid Build Coastguard Worker
322*f6dc9357SAndroid Build Coastguard Worker /*
323*f6dc9357SAndroid Build Coastguard Worker if (arc.Ask_Deleted)
324*f6dc9357SAndroid Build Coastguard Worker {
325*f6dc9357SAndroid Build Coastguard Worker bool isDeleted = false;
326*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
327*f6dc9357SAndroid Build Coastguard Worker if (isDeleted)
328*f6dc9357SAndroid Build Coastguard Worker curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
329*f6dc9357SAndroid Build Coastguard Worker }
330*f6dc9357SAndroid Build Coastguard Worker */
331*f6dc9357SAndroid Build Coastguard Worker
332*f6dc9357SAndroid Build Coastguard Worker unsigned namePos = 0;
333*f6dc9357SAndroid Build Coastguard Worker
334*f6dc9357SAndroid Build Coastguard Worker unsigned numLevels = 0;
335*f6dc9357SAndroid Build Coastguard Worker
336*f6dc9357SAndroid Build Coastguard Worker for (unsigned j = 0; j < len; j++)
337*f6dc9357SAndroid Build Coastguard Worker {
338*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = s[j];
339*f6dc9357SAndroid Build Coastguard Worker if (c == L'/'
340*f6dc9357SAndroid Build Coastguard Worker #if WCHAR_PATH_SEPARATOR != L'/'
341*f6dc9357SAndroid Build Coastguard Worker || (c == separatorChar)
342*f6dc9357SAndroid Build Coastguard Worker #endif
343*f6dc9357SAndroid Build Coastguard Worker )
344*f6dc9357SAndroid Build Coastguard Worker {
345*f6dc9357SAndroid Build Coastguard Worker const unsigned kLevelLimit = 1 << 10;
346*f6dc9357SAndroid Build Coastguard Worker if (numLevels <= kLevelLimit)
347*f6dc9357SAndroid Build Coastguard Worker {
348*f6dc9357SAndroid Build Coastguard Worker if (numLevels == kLevelLimit)
349*f6dc9357SAndroid Build Coastguard Worker name = "[LONG_PATH]";
350*f6dc9357SAndroid Build Coastguard Worker else
351*f6dc9357SAndroid Build Coastguard Worker name.SetFrom(s + namePos, j - namePos);
352*f6dc9357SAndroid Build Coastguard Worker // 22.00: we can normalize dir here
353*f6dc9357SAndroid Build Coastguard Worker // NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
354*f6dc9357SAndroid Build Coastguard Worker curItem = AddDir(curItem, -1, name);
355*f6dc9357SAndroid Build Coastguard Worker }
356*f6dc9357SAndroid Build Coastguard Worker namePos = j + 1;
357*f6dc9357SAndroid Build Coastguard Worker numLevels++;
358*f6dc9357SAndroid Build Coastguard Worker }
359*f6dc9357SAndroid Build Coastguard Worker }
360*f6dc9357SAndroid Build Coastguard Worker
361*f6dc9357SAndroid Build Coastguard Worker /*
362*f6dc9357SAndroid Build Coastguard Worker that code must be implemeted to hide alt streams in list.
363*f6dc9357SAndroid Build Coastguard Worker if (arc.Ask_AltStreams)
364*f6dc9357SAndroid Build Coastguard Worker {
365*f6dc9357SAndroid Build Coastguard Worker bool isAltStream;
366*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
367*f6dc9357SAndroid Build Coastguard Worker if (isAltStream)
368*f6dc9357SAndroid Build Coastguard Worker {
369*f6dc9357SAndroid Build Coastguard Worker
370*f6dc9357SAndroid Build Coastguard Worker }
371*f6dc9357SAndroid Build Coastguard Worker }
372*f6dc9357SAndroid Build Coastguard Worker */
373*f6dc9357SAndroid Build Coastguard Worker
374*f6dc9357SAndroid Build Coastguard Worker bool isDir;
375*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_Dir(archive, i, isDir))
376*f6dc9357SAndroid Build Coastguard Worker
377*f6dc9357SAndroid Build Coastguard Worker CProxyFile &f = Files[i];
378*f6dc9357SAndroid Build Coastguard Worker
379*f6dc9357SAndroid Build Coastguard Worker f.NameLen = len - namePos;
380*f6dc9357SAndroid Build Coastguard Worker s += namePos;
381*f6dc9357SAndroid Build Coastguard Worker
382*f6dc9357SAndroid Build Coastguard Worker if (isPtrName)
383*f6dc9357SAndroid Build Coastguard Worker f.Name = s;
384*f6dc9357SAndroid Build Coastguard Worker else
385*f6dc9357SAndroid Build Coastguard Worker {
386*f6dc9357SAndroid Build Coastguard Worker f.Name = AllocStringAndCopy(s, f.NameLen);
387*f6dc9357SAndroid Build Coastguard Worker f.NeedDeleteName = true;
388*f6dc9357SAndroid Build Coastguard Worker }
389*f6dc9357SAndroid Build Coastguard Worker
390*f6dc9357SAndroid Build Coastguard Worker if (isDir)
391*f6dc9357SAndroid Build Coastguard Worker {
392*f6dc9357SAndroid Build Coastguard Worker name = s;
393*f6dc9357SAndroid Build Coastguard Worker // 22.00: we can normalize dir here
394*f6dc9357SAndroid Build Coastguard Worker // NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(name);
395*f6dc9357SAndroid Build Coastguard Worker AddDir(curItem, (int)i, name);
396*f6dc9357SAndroid Build Coastguard Worker }
397*f6dc9357SAndroid Build Coastguard Worker else
398*f6dc9357SAndroid Build Coastguard Worker Dirs[curItem].SubFiles.Add(i);
399*f6dc9357SAndroid Build Coastguard Worker }
400*f6dc9357SAndroid Build Coastguard Worker
401*f6dc9357SAndroid Build Coastguard Worker CalculateSizes(0, archive);
402*f6dc9357SAndroid Build Coastguard Worker
403*f6dc9357SAndroid Build Coastguard Worker // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);
404*f6dc9357SAndroid Build Coastguard Worker
405*f6dc9357SAndroid Build Coastguard Worker return S_OK;
406*f6dc9357SAndroid Build Coastguard Worker }
407*f6dc9357SAndroid Build Coastguard Worker
408*f6dc9357SAndroid Build Coastguard Worker
409*f6dc9357SAndroid Build Coastguard Worker
410*f6dc9357SAndroid Build Coastguard Worker // ---------- for Tree-mode archive ----------
411*f6dc9357SAndroid Build Coastguard Worker
GetDirPathParts(unsigned dirIndex,UStringVector & pathParts,bool & isAltStreamDir) const412*f6dc9357SAndroid Build Coastguard Worker void CProxyArc2::GetDirPathParts(unsigned dirIndex, UStringVector &pathParts, bool &isAltStreamDir) const
413*f6dc9357SAndroid Build Coastguard Worker {
414*f6dc9357SAndroid Build Coastguard Worker pathParts.Clear();
415*f6dc9357SAndroid Build Coastguard Worker
416*f6dc9357SAndroid Build Coastguard Worker isAltStreamDir = false;
417*f6dc9357SAndroid Build Coastguard Worker
418*f6dc9357SAndroid Build Coastguard Worker if (dirIndex == k_Proxy2_RootDirIndex)
419*f6dc9357SAndroid Build Coastguard Worker return;
420*f6dc9357SAndroid Build Coastguard Worker if (dirIndex == k_Proxy2_AltRootDirIndex)
421*f6dc9357SAndroid Build Coastguard Worker {
422*f6dc9357SAndroid Build Coastguard Worker isAltStreamDir = true;
423*f6dc9357SAndroid Build Coastguard Worker return;
424*f6dc9357SAndroid Build Coastguard Worker }
425*f6dc9357SAndroid Build Coastguard Worker
426*f6dc9357SAndroid Build Coastguard Worker while (dirIndex >= k_Proxy2_NumRootDirs)
427*f6dc9357SAndroid Build Coastguard Worker {
428*f6dc9357SAndroid Build Coastguard Worker const CProxyDir2 &dir = Dirs[dirIndex];
429*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
430*f6dc9357SAndroid Build Coastguard Worker if (pathParts.IsEmpty() && (int)dirIndex == file.AltDirIndex)
431*f6dc9357SAndroid Build Coastguard Worker isAltStreamDir = true;
432*f6dc9357SAndroid Build Coastguard Worker pathParts.Insert(0, file.Name);
433*f6dc9357SAndroid Build Coastguard Worker const int par = file.Parent;
434*f6dc9357SAndroid Build Coastguard Worker if (par == -1)
435*f6dc9357SAndroid Build Coastguard Worker break;
436*f6dc9357SAndroid Build Coastguard Worker dirIndex = (unsigned)Files[(unsigned)par].DirIndex;
437*f6dc9357SAndroid Build Coastguard Worker // if ((int)dirIndex == -1) break;
438*f6dc9357SAndroid Build Coastguard Worker }
439*f6dc9357SAndroid Build Coastguard Worker }
440*f6dc9357SAndroid Build Coastguard Worker
IsAltDir(unsigned dirIndex) const441*f6dc9357SAndroid Build Coastguard Worker bool CProxyArc2::IsAltDir(unsigned dirIndex) const
442*f6dc9357SAndroid Build Coastguard Worker {
443*f6dc9357SAndroid Build Coastguard Worker if (dirIndex == k_Proxy2_RootDirIndex)
444*f6dc9357SAndroid Build Coastguard Worker return false;
445*f6dc9357SAndroid Build Coastguard Worker if (dirIndex == k_Proxy2_AltRootDirIndex)
446*f6dc9357SAndroid Build Coastguard Worker return true;
447*f6dc9357SAndroid Build Coastguard Worker const CProxyDir2 &dir = Dirs[dirIndex];
448*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
449*f6dc9357SAndroid Build Coastguard Worker return ((int)dirIndex == file.AltDirIndex);
450*f6dc9357SAndroid Build Coastguard Worker }
451*f6dc9357SAndroid Build Coastguard Worker
GetDirPath_as_Prefix(unsigned dirIndex,bool & isAltStreamDir) const452*f6dc9357SAndroid Build Coastguard Worker UString CProxyArc2::GetDirPath_as_Prefix(unsigned dirIndex, bool &isAltStreamDir) const
453*f6dc9357SAndroid Build Coastguard Worker {
454*f6dc9357SAndroid Build Coastguard Worker isAltStreamDir = false;
455*f6dc9357SAndroid Build Coastguard Worker const CProxyDir2 &dir = Dirs[dirIndex];
456*f6dc9357SAndroid Build Coastguard Worker if (dirIndex == k_Proxy2_AltRootDirIndex)
457*f6dc9357SAndroid Build Coastguard Worker isAltStreamDir = true;
458*f6dc9357SAndroid Build Coastguard Worker else if (dirIndex >= k_Proxy2_NumRootDirs)
459*f6dc9357SAndroid Build Coastguard Worker {
460*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &file = Files[(unsigned)dir.ArcIndex];
461*f6dc9357SAndroid Build Coastguard Worker isAltStreamDir = ((int)dirIndex == file.AltDirIndex);
462*f6dc9357SAndroid Build Coastguard Worker }
463*f6dc9357SAndroid Build Coastguard Worker return dir.PathPrefix;
464*f6dc9357SAndroid Build Coastguard Worker }
465*f6dc9357SAndroid Build Coastguard Worker
AddRealIndices_of_ArcItem(unsigned arcIndex,bool includeAltStreams,CUIntVector & realIndices) const466*f6dc9357SAndroid Build Coastguard Worker void CProxyArc2::AddRealIndices_of_ArcItem(unsigned arcIndex, bool includeAltStreams, CUIntVector &realIndices) const
467*f6dc9357SAndroid Build Coastguard Worker {
468*f6dc9357SAndroid Build Coastguard Worker realIndices.Add(arcIndex);
469*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &file = Files[arcIndex];
470*f6dc9357SAndroid Build Coastguard Worker if (file.DirIndex != -1)
471*f6dc9357SAndroid Build Coastguard Worker AddRealIndices_of_Dir((unsigned)file.DirIndex, includeAltStreams, realIndices);
472*f6dc9357SAndroid Build Coastguard Worker if (includeAltStreams && file.AltDirIndex != -1)
473*f6dc9357SAndroid Build Coastguard Worker AddRealIndices_of_Dir((unsigned)file.AltDirIndex, includeAltStreams, realIndices);
474*f6dc9357SAndroid Build Coastguard Worker }
475*f6dc9357SAndroid Build Coastguard Worker
AddRealIndices_of_Dir(unsigned dirIndex,bool includeAltStreams,CUIntVector & realIndices) const476*f6dc9357SAndroid Build Coastguard Worker void CProxyArc2::AddRealIndices_of_Dir(unsigned dirIndex, bool includeAltStreams, CUIntVector &realIndices) const
477*f6dc9357SAndroid Build Coastguard Worker {
478*f6dc9357SAndroid Build Coastguard Worker const CRecordVector<unsigned> &subFiles = Dirs[dirIndex].Items;
479*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, subFiles)
480*f6dc9357SAndroid Build Coastguard Worker {
481*f6dc9357SAndroid Build Coastguard Worker AddRealIndices_of_ArcItem(subFiles[i], includeAltStreams, realIndices);
482*f6dc9357SAndroid Build Coastguard Worker }
483*f6dc9357SAndroid Build Coastguard Worker }
484*f6dc9357SAndroid Build Coastguard Worker
GetRealIndex(unsigned dirIndex,unsigned index) const485*f6dc9357SAndroid Build Coastguard Worker unsigned CProxyArc2::GetRealIndex(unsigned dirIndex, unsigned index) const
486*f6dc9357SAndroid Build Coastguard Worker {
487*f6dc9357SAndroid Build Coastguard Worker return Dirs[dirIndex].Items[index];
488*f6dc9357SAndroid Build Coastguard Worker }
489*f6dc9357SAndroid Build Coastguard Worker
GetRealIndices(unsigned dirIndex,const UInt32 * indices,UInt32 numItems,bool includeAltStreams,CUIntVector & realIndices) const490*f6dc9357SAndroid Build Coastguard Worker void CProxyArc2::GetRealIndices(unsigned dirIndex, const UInt32 *indices, UInt32 numItems, bool includeAltStreams, CUIntVector &realIndices) const
491*f6dc9357SAndroid Build Coastguard Worker {
492*f6dc9357SAndroid Build Coastguard Worker const CProxyDir2 &dir = Dirs[dirIndex];
493*f6dc9357SAndroid Build Coastguard Worker realIndices.Clear();
494*f6dc9357SAndroid Build Coastguard Worker for (UInt32 i = 0; i < numItems; i++)
495*f6dc9357SAndroid Build Coastguard Worker {
496*f6dc9357SAndroid Build Coastguard Worker AddRealIndices_of_ArcItem(dir.Items[indices[i]], includeAltStreams, realIndices);
497*f6dc9357SAndroid Build Coastguard Worker }
498*f6dc9357SAndroid Build Coastguard Worker HeapSort(realIndices.NonConstData(), realIndices.Size());
499*f6dc9357SAndroid Build Coastguard Worker }
500*f6dc9357SAndroid Build Coastguard Worker
CalculateSizes(unsigned dirIndex,IInArchive * archive)501*f6dc9357SAndroid Build Coastguard Worker void CProxyArc2::CalculateSizes(unsigned dirIndex, IInArchive *archive)
502*f6dc9357SAndroid Build Coastguard Worker {
503*f6dc9357SAndroid Build Coastguard Worker CProxyDir2 &dir = Dirs[dirIndex];
504*f6dc9357SAndroid Build Coastguard Worker dir.Size = dir.PackSize = 0;
505*f6dc9357SAndroid Build Coastguard Worker dir.NumSubDirs = 0; // dir.SubDirs.Size();
506*f6dc9357SAndroid Build Coastguard Worker dir.NumSubFiles = 0; // dir.Files.Size();
507*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = true;
508*f6dc9357SAndroid Build Coastguard Worker dir.Crc = 0;
509*f6dc9357SAndroid Build Coastguard Worker
510*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, dir.Items)
511*f6dc9357SAndroid Build Coastguard Worker {
512*f6dc9357SAndroid Build Coastguard Worker UInt32 index = dir.Items[i];
513*f6dc9357SAndroid Build Coastguard Worker UInt64 size, packSize;
514*f6dc9357SAndroid Build Coastguard Worker const bool sizeDefined = GetSize(archive, index, kpidSize, size);
515*f6dc9357SAndroid Build Coastguard Worker dir.Size += size;
516*f6dc9357SAndroid Build Coastguard Worker GetSize(archive, index, kpidPackSize, packSize);
517*f6dc9357SAndroid Build Coastguard Worker dir.PackSize += packSize;
518*f6dc9357SAndroid Build Coastguard Worker {
519*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
520*f6dc9357SAndroid Build Coastguard Worker if (archive->GetProperty(index, kpidCRC, &prop) == S_OK)
521*f6dc9357SAndroid Build Coastguard Worker {
522*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_UI4)
523*f6dc9357SAndroid Build Coastguard Worker dir.Crc += prop.ulVal;
524*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt != VT_EMPTY || size != 0 || !sizeDefined)
525*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = false;
526*f6dc9357SAndroid Build Coastguard Worker }
527*f6dc9357SAndroid Build Coastguard Worker else
528*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = false;
529*f6dc9357SAndroid Build Coastguard Worker }
530*f6dc9357SAndroid Build Coastguard Worker
531*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &subFile = Files[index];
532*f6dc9357SAndroid Build Coastguard Worker if (subFile.DirIndex == -1)
533*f6dc9357SAndroid Build Coastguard Worker {
534*f6dc9357SAndroid Build Coastguard Worker dir.NumSubFiles++;
535*f6dc9357SAndroid Build Coastguard Worker }
536*f6dc9357SAndroid Build Coastguard Worker else
537*f6dc9357SAndroid Build Coastguard Worker {
538*f6dc9357SAndroid Build Coastguard Worker // 22.00: we normalize name
539*f6dc9357SAndroid Build Coastguard Worker UString s = subFile.Name;
540*f6dc9357SAndroid Build Coastguard Worker NArchive::NItemName::NormalizeSlashes_in_FileName_for_OsPath(s);
541*f6dc9357SAndroid Build Coastguard Worker dir.NumSubDirs++;
542*f6dc9357SAndroid Build Coastguard Worker CProxyDir2 &f = Dirs[subFile.DirIndex];
543*f6dc9357SAndroid Build Coastguard Worker f.PathPrefix = dir.PathPrefix + s + WCHAR_PATH_SEPARATOR;
544*f6dc9357SAndroid Build Coastguard Worker CalculateSizes((unsigned)subFile.DirIndex, archive);
545*f6dc9357SAndroid Build Coastguard Worker dir.Size += f.Size;
546*f6dc9357SAndroid Build Coastguard Worker dir.PackSize += f.PackSize;
547*f6dc9357SAndroid Build Coastguard Worker dir.NumSubFiles += f.NumSubFiles;
548*f6dc9357SAndroid Build Coastguard Worker dir.NumSubDirs += f.NumSubDirs;
549*f6dc9357SAndroid Build Coastguard Worker dir.Crc += f.Crc;
550*f6dc9357SAndroid Build Coastguard Worker if (!f.CrcIsDefined)
551*f6dc9357SAndroid Build Coastguard Worker dir.CrcIsDefined = false;
552*f6dc9357SAndroid Build Coastguard Worker }
553*f6dc9357SAndroid Build Coastguard Worker
554*f6dc9357SAndroid Build Coastguard Worker if (subFile.AltDirIndex == -1)
555*f6dc9357SAndroid Build Coastguard Worker {
556*f6dc9357SAndroid Build Coastguard Worker // dir.NumSubFiles++;
557*f6dc9357SAndroid Build Coastguard Worker }
558*f6dc9357SAndroid Build Coastguard Worker else
559*f6dc9357SAndroid Build Coastguard Worker {
560*f6dc9357SAndroid Build Coastguard Worker // dir.NumSubDirs++;
561*f6dc9357SAndroid Build Coastguard Worker CProxyDir2 &f = Dirs[subFile.AltDirIndex];
562*f6dc9357SAndroid Build Coastguard Worker f.PathPrefix = dir.PathPrefix + subFile.Name + L':';
563*f6dc9357SAndroid Build Coastguard Worker CalculateSizes((unsigned)subFile.AltDirIndex, archive);
564*f6dc9357SAndroid Build Coastguard Worker }
565*f6dc9357SAndroid Build Coastguard Worker }
566*f6dc9357SAndroid Build Coastguard Worker }
567*f6dc9357SAndroid Build Coastguard Worker
568*f6dc9357SAndroid Build Coastguard Worker
IsThere_SubDir(unsigned dirIndex,const UString & name) const569*f6dc9357SAndroid Build Coastguard Worker bool CProxyArc2::IsThere_SubDir(unsigned dirIndex, const UString &name) const
570*f6dc9357SAndroid Build Coastguard Worker {
571*f6dc9357SAndroid Build Coastguard Worker const CRecordVector<unsigned> &subFiles = Dirs[dirIndex].Items;
572*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, subFiles)
573*f6dc9357SAndroid Build Coastguard Worker {
574*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &file = Files[subFiles[i]];
575*f6dc9357SAndroid Build Coastguard Worker if (file.IsDir())
576*f6dc9357SAndroid Build Coastguard Worker if (CompareFileNames(name, file.Name) == 0)
577*f6dc9357SAndroid Build Coastguard Worker return true;
578*f6dc9357SAndroid Build Coastguard Worker }
579*f6dc9357SAndroid Build Coastguard Worker return false;
580*f6dc9357SAndroid Build Coastguard Worker }
581*f6dc9357SAndroid Build Coastguard Worker
Load(const CArc & arc,IProgress * progress)582*f6dc9357SAndroid Build Coastguard Worker HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress)
583*f6dc9357SAndroid Build Coastguard Worker {
584*f6dc9357SAndroid Build Coastguard Worker if (!arc.GetRawProps)
585*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
586*f6dc9357SAndroid Build Coastguard Worker
587*f6dc9357SAndroid Build Coastguard Worker // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {
588*f6dc9357SAndroid Build Coastguard Worker
589*f6dc9357SAndroid Build Coastguard Worker Dirs.Clear();
590*f6dc9357SAndroid Build Coastguard Worker Files.Free();
591*f6dc9357SAndroid Build Coastguard Worker
592*f6dc9357SAndroid Build Coastguard Worker IInArchive *archive = arc.Archive;
593*f6dc9357SAndroid Build Coastguard Worker
594*f6dc9357SAndroid Build Coastguard Worker UInt32 numItems;
595*f6dc9357SAndroid Build Coastguard Worker RINOK(archive->GetNumberOfItems(&numItems))
596*f6dc9357SAndroid Build Coastguard Worker if (progress)
597*f6dc9357SAndroid Build Coastguard Worker RINOK(progress->SetTotal(numItems))
598*f6dc9357SAndroid Build Coastguard Worker UString fileName;
599*f6dc9357SAndroid Build Coastguard Worker
600*f6dc9357SAndroid Build Coastguard Worker
601*f6dc9357SAndroid Build Coastguard Worker {
602*f6dc9357SAndroid Build Coastguard Worker // Dirs[0] - root dir
603*f6dc9357SAndroid Build Coastguard Worker /* CProxyDir2 &dir = */ Dirs.AddNew();
604*f6dc9357SAndroid Build Coastguard Worker }
605*f6dc9357SAndroid Build Coastguard Worker
606*f6dc9357SAndroid Build Coastguard Worker {
607*f6dc9357SAndroid Build Coastguard Worker // Dirs[1] - for alt streams of root dir
608*f6dc9357SAndroid Build Coastguard Worker CProxyDir2 &dir = Dirs.AddNew();
609*f6dc9357SAndroid Build Coastguard Worker dir.PathPrefix = ':';
610*f6dc9357SAndroid Build Coastguard Worker }
611*f6dc9357SAndroid Build Coastguard Worker
612*f6dc9357SAndroid Build Coastguard Worker Files.Alloc(numItems);
613*f6dc9357SAndroid Build Coastguard Worker
614*f6dc9357SAndroid Build Coastguard Worker UString tempUString;
615*f6dc9357SAndroid Build Coastguard Worker AString tempAString;
616*f6dc9357SAndroid Build Coastguard Worker
617*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
618*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
619*f6dc9357SAndroid Build Coastguard Worker {
620*f6dc9357SAndroid Build Coastguard Worker if (progress && (i & 0xFFFFF) == 0)
621*f6dc9357SAndroid Build Coastguard Worker {
622*f6dc9357SAndroid Build Coastguard Worker UInt64 currentItemIndex = i;
623*f6dc9357SAndroid Build Coastguard Worker RINOK(progress->SetCompleted(¤tItemIndex))
624*f6dc9357SAndroid Build Coastguard Worker }
625*f6dc9357SAndroid Build Coastguard Worker
626*f6dc9357SAndroid Build Coastguard Worker CProxyFile2 &file = Files[i];
627*f6dc9357SAndroid Build Coastguard Worker
628*f6dc9357SAndroid Build Coastguard Worker const void *p;
629*f6dc9357SAndroid Build Coastguard Worker UInt32 size;
630*f6dc9357SAndroid Build Coastguard Worker UInt32 propType;
631*f6dc9357SAndroid Build Coastguard Worker RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType))
632*f6dc9357SAndroid Build Coastguard Worker
633*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_LE
634*f6dc9357SAndroid Build Coastguard Worker if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE)
635*f6dc9357SAndroid Build Coastguard Worker {
636*f6dc9357SAndroid Build Coastguard Worker file.Name = (const wchar_t *)p;
637*f6dc9357SAndroid Build Coastguard Worker file.NameLen = 0;
638*f6dc9357SAndroid Build Coastguard Worker if (size >= sizeof(wchar_t))
639*f6dc9357SAndroid Build Coastguard Worker file.NameLen = size / sizeof(wchar_t) - 1;
640*f6dc9357SAndroid Build Coastguard Worker }
641*f6dc9357SAndroid Build Coastguard Worker else
642*f6dc9357SAndroid Build Coastguard Worker #endif
643*f6dc9357SAndroid Build Coastguard Worker if (p && propType == NPropDataType::kUtf8z)
644*f6dc9357SAndroid Build Coastguard Worker {
645*f6dc9357SAndroid Build Coastguard Worker tempAString = (const char *)p;
646*f6dc9357SAndroid Build Coastguard Worker ConvertUTF8ToUnicode(tempAString, tempUString);
647*f6dc9357SAndroid Build Coastguard Worker file.NameLen = tempUString.Len();
648*f6dc9357SAndroid Build Coastguard Worker file.Name = AllocStringAndCopy(tempUString);
649*f6dc9357SAndroid Build Coastguard Worker file.NeedDeleteName = true;
650*f6dc9357SAndroid Build Coastguard Worker }
651*f6dc9357SAndroid Build Coastguard Worker else
652*f6dc9357SAndroid Build Coastguard Worker {
653*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
654*f6dc9357SAndroid Build Coastguard Worker RINOK(arc.Archive->GetProperty(i, kpidName, &prop))
655*f6dc9357SAndroid Build Coastguard Worker const wchar_t *s;
656*f6dc9357SAndroid Build Coastguard Worker if (prop.vt == VT_BSTR)
657*f6dc9357SAndroid Build Coastguard Worker s = prop.bstrVal;
658*f6dc9357SAndroid Build Coastguard Worker else if (prop.vt == VT_EMPTY)
659*f6dc9357SAndroid Build Coastguard Worker s = L"[Content]";
660*f6dc9357SAndroid Build Coastguard Worker else
661*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
662*f6dc9357SAndroid Build Coastguard Worker file.NameLen = MyStringLen(s);
663*f6dc9357SAndroid Build Coastguard Worker file.Name = AllocStringAndCopy(s, file.NameLen);
664*f6dc9357SAndroid Build Coastguard Worker file.NeedDeleteName = true;
665*f6dc9357SAndroid Build Coastguard Worker }
666*f6dc9357SAndroid Build Coastguard Worker
667*f6dc9357SAndroid Build Coastguard Worker UInt32 parent = (UInt32)(Int32)-1;
668*f6dc9357SAndroid Build Coastguard Worker UInt32 parentType = 0;
669*f6dc9357SAndroid Build Coastguard Worker RINOK(arc.GetRawProps->GetParent(i, &parent, &parentType))
670*f6dc9357SAndroid Build Coastguard Worker file.Parent = (Int32)parent;
671*f6dc9357SAndroid Build Coastguard Worker
672*f6dc9357SAndroid Build Coastguard Worker if (arc.Ask_Deleted)
673*f6dc9357SAndroid Build Coastguard Worker {
674*f6dc9357SAndroid Build Coastguard Worker bool isDeleted = false;
675*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_Deleted(archive, i, isDeleted))
676*f6dc9357SAndroid Build Coastguard Worker if (isDeleted)
677*f6dc9357SAndroid Build Coastguard Worker {
678*f6dc9357SAndroid Build Coastguard Worker // continue;
679*f6dc9357SAndroid Build Coastguard Worker // curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
680*f6dc9357SAndroid Build Coastguard Worker }
681*f6dc9357SAndroid Build Coastguard Worker }
682*f6dc9357SAndroid Build Coastguard Worker
683*f6dc9357SAndroid Build Coastguard Worker bool isDir;
684*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_Dir(archive, i, isDir))
685*f6dc9357SAndroid Build Coastguard Worker
686*f6dc9357SAndroid Build Coastguard Worker if (isDir)
687*f6dc9357SAndroid Build Coastguard Worker {
688*f6dc9357SAndroid Build Coastguard Worker file.DirIndex = (int)Dirs.Size();
689*f6dc9357SAndroid Build Coastguard Worker CProxyDir2 &dir = Dirs.AddNew();
690*f6dc9357SAndroid Build Coastguard Worker dir.ArcIndex = (int)i;
691*f6dc9357SAndroid Build Coastguard Worker }
692*f6dc9357SAndroid Build Coastguard Worker if (arc.Ask_AltStream)
693*f6dc9357SAndroid Build Coastguard Worker RINOK(Archive_IsItem_AltStream(archive, i, file.IsAltStream))
694*f6dc9357SAndroid Build Coastguard Worker }
695*f6dc9357SAndroid Build Coastguard Worker
696*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
697*f6dc9357SAndroid Build Coastguard Worker {
698*f6dc9357SAndroid Build Coastguard Worker CProxyFile2 &file = Files[i];
699*f6dc9357SAndroid Build Coastguard Worker int dirIndex;
700*f6dc9357SAndroid Build Coastguard Worker
701*f6dc9357SAndroid Build Coastguard Worker if (file.IsAltStream)
702*f6dc9357SAndroid Build Coastguard Worker {
703*f6dc9357SAndroid Build Coastguard Worker if (file.Parent == -1)
704*f6dc9357SAndroid Build Coastguard Worker dirIndex = k_Proxy2_AltRootDirIndex;
705*f6dc9357SAndroid Build Coastguard Worker else
706*f6dc9357SAndroid Build Coastguard Worker {
707*f6dc9357SAndroid Build Coastguard Worker int &folderIndex2 = Files[(unsigned)file.Parent].AltDirIndex;
708*f6dc9357SAndroid Build Coastguard Worker if (folderIndex2 == -1)
709*f6dc9357SAndroid Build Coastguard Worker {
710*f6dc9357SAndroid Build Coastguard Worker folderIndex2 = (int)Dirs.Size();
711*f6dc9357SAndroid Build Coastguard Worker CProxyDir2 &dir = Dirs.AddNew();
712*f6dc9357SAndroid Build Coastguard Worker dir.ArcIndex = file.Parent;
713*f6dc9357SAndroid Build Coastguard Worker }
714*f6dc9357SAndroid Build Coastguard Worker dirIndex = folderIndex2;
715*f6dc9357SAndroid Build Coastguard Worker }
716*f6dc9357SAndroid Build Coastguard Worker }
717*f6dc9357SAndroid Build Coastguard Worker else
718*f6dc9357SAndroid Build Coastguard Worker {
719*f6dc9357SAndroid Build Coastguard Worker if (file.Parent == -1)
720*f6dc9357SAndroid Build Coastguard Worker dirIndex = k_Proxy2_RootDirIndex;
721*f6dc9357SAndroid Build Coastguard Worker else
722*f6dc9357SAndroid Build Coastguard Worker {
723*f6dc9357SAndroid Build Coastguard Worker dirIndex = Files[(unsigned)file.Parent].DirIndex;
724*f6dc9357SAndroid Build Coastguard Worker if (dirIndex == -1)
725*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
726*f6dc9357SAndroid Build Coastguard Worker }
727*f6dc9357SAndroid Build Coastguard Worker }
728*f6dc9357SAndroid Build Coastguard Worker
729*f6dc9357SAndroid Build Coastguard Worker Dirs[dirIndex].Items.Add(i);
730*f6dc9357SAndroid Build Coastguard Worker }
731*f6dc9357SAndroid Build Coastguard Worker
732*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < k_Proxy2_NumRootDirs; i++)
733*f6dc9357SAndroid Build Coastguard Worker CalculateSizes(i, archive);
734*f6dc9357SAndroid Build Coastguard Worker
735*f6dc9357SAndroid Build Coastguard Worker // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);
736*f6dc9357SAndroid Build Coastguard Worker
737*f6dc9357SAndroid Build Coastguard Worker return S_OK;
738*f6dc9357SAndroid Build Coastguard Worker }
739*f6dc9357SAndroid Build Coastguard Worker
FindItem(unsigned dirIndex,const wchar_t * name,bool foldersOnly) const740*f6dc9357SAndroid Build Coastguard Worker int CProxyArc2::FindItem(unsigned dirIndex, const wchar_t *name, bool foldersOnly) const
741*f6dc9357SAndroid Build Coastguard Worker {
742*f6dc9357SAndroid Build Coastguard Worker const CProxyDir2 &dir = Dirs[dirIndex];
743*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, dir.Items)
744*f6dc9357SAndroid Build Coastguard Worker {
745*f6dc9357SAndroid Build Coastguard Worker const CProxyFile2 &file = Files[dir.Items[i]];
746*f6dc9357SAndroid Build Coastguard Worker if (foldersOnly && file.DirIndex == -1)
747*f6dc9357SAndroid Build Coastguard Worker continue;
748*f6dc9357SAndroid Build Coastguard Worker if (CompareFileNames(file.Name, name) == 0)
749*f6dc9357SAndroid Build Coastguard Worker return (int)i;
750*f6dc9357SAndroid Build Coastguard Worker }
751*f6dc9357SAndroid Build Coastguard Worker return -1;
752*f6dc9357SAndroid Build Coastguard Worker }
753