Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / Archive / 7z / 7zProperties.cpp
1 // 7zProperties.cpp
2
3 #include "StdAfx.h"
4
5 #include "7zProperties.h"
6 #include "7zHeader.h"
7 #include "7zHandler.h"
8
9 // #define _MULTI_PACK
10
11 namespace NArchive {
12 namespace N7z {
13
14 struct CPropMap
15 {
16   UInt64 FilePropID;
17   STATPROPSTG StatPROPSTG;
18 };
19
20 CPropMap kPropMap[] = 
21 {
22   { NID::kName, NULL, kpidPath, VT_BSTR},
23   { NID::kSize, NULL, kpidSize, VT_UI8},
24   { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
25   
26   #ifdef _MULTI_PACK
27   { 100, L"Pack0", kpidPackedSize0, VT_UI8},
28   { 101, L"Pack1", kpidPackedSize1, VT_UI8},
29   { 102, L"Pack2", kpidPackedSize2, VT_UI8},
30   { 103, L"Pack3", kpidPackedSize3, VT_UI8},
31   { 104, L"Pack4", kpidPackedSize4, VT_UI8},
32   #endif
33
34   { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
35   { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
36   { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
37   { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
38   { NID::kStartPos, NULL, kpidPosition, VT_UI4},
39
40   { NID::kCRC, NULL, kpidCRC, VT_UI4},
41   
42   { NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
43   // { 97, NULL, kpidSolid, VT_BOOL},
44   #ifndef _SFX
45   { 98, NULL, kpidMethod, VT_BSTR},
46   { 99, NULL, kpidBlock, VT_UI4}
47   #endif
48 };
49
50 static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
51
52 static int FindPropInMap(UInt64 filePropID)
53 {
54   for (int i = 0; i < kPropMapSize; i++)
55     if (kPropMap[i].FilePropID == filePropID)
56       return i;
57   return -1;
58 }
59
60 static void CopyOneItem(CRecordVector<UInt64> &src, 
61     CRecordVector<UInt64> &dest, UInt32 item)
62 {
63   for (int i = 0; i < src.Size(); i++)
64     if (src[i] == item)
65     {
66       dest.Add(item);
67       src.Delete(i);
68       return;
69     }
70 }
71
72 static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
73 {
74   for (int i = 0; i < src.Size(); i++)
75     if (src[i] == item)
76     {
77       src.Delete(i);
78       return;
79     }
80 }
81
82 static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
83 {
84   for (int i = 0; i < dest.Size(); i++)
85     if (dest[i] == item)
86     {
87       dest.Delete(i);
88       break;
89     }
90   dest.Insert(0, item);
91 }
92
93 void CHandler::FillPopIDs()
94
95   _fileInfoPopIDs.Clear();
96
97   #ifdef _7Z_VOL
98   if(_volumes.Size() < 1)
99     return;
100   const CVolume &volume = _volumes.Front();
101   const CArchiveDatabaseEx &_database = volume.Database;
102   #endif
103
104   CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
105
106   RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
107   RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
108
109   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
110   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
111   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
112   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
113   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
114   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
115   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
116   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
117   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
118   CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
119   _fileInfoPopIDs += fileInfoPopIDs; 
120  
121   #ifndef _SFX
122   _fileInfoPopIDs.Add(98);
123   _fileInfoPopIDs.Add(99);
124   #endif
125   #ifdef _MULTI_PACK
126   _fileInfoPopIDs.Add(100);
127   _fileInfoPopIDs.Add(101);
128   _fileInfoPopIDs.Add(102);
129   _fileInfoPopIDs.Add(103);
130   _fileInfoPopIDs.Add(104);
131   #endif
132
133   #ifndef _SFX
134   InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
135   InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
136   InsertToHead(_fileInfoPopIDs, NID::kSize);
137   InsertToHead(_fileInfoPopIDs, NID::kName);
138   #endif
139 }
140
141 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
142 {
143   *numProperties = _fileInfoPopIDs.Size();
144   return S_OK;
145 }
146
147 STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,     
148       BSTR *name, PROPID *propID, VARTYPE *varType)
149 {
150   if((int)index >= _fileInfoPopIDs.Size())
151     return E_INVALIDARG;
152   int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
153   if (indexInMap == -1)
154     return E_INVALIDARG;
155   const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
156   *propID = srcItem.propid;
157   *varType = srcItem.vt;
158   *name = 0;
159   return S_OK;
160 }
161
162 }}