Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / Archive / Udf / UdfIn.h
1 // Archive/UdfIn.h -- UDF / ECMA-167\r
2 \r
3 #ifndef __ARCHIVE_UDF_IN_H\r
4 #define __ARCHIVE_UDF_IN_H\r
5 \r
6 #include "Common/MyCom.h"\r
7 #include "Common/IntToString.h"\r
8 #include "Common/Buffer.h"\r
9 #include "Common/MyString.h"\r
10 #include "Common/MyMap.h"\r
11 \r
12 #include "../../IStream.h"\r
13 \r
14 namespace NArchive {\r
15 namespace NUdf {\r
16 \r
17 // ---------- ECMA Part 1 ----------\r
18 \r
19 // ECMA 1/7.2.12\r
20 \r
21 /*\r
22 struct CDString32\r
23 {\r
24   Byte Data[32];\r
25   void Parse(const Byte *buf);\r
26   // UString GetString() const;\r
27 };\r
28 */\r
29 \r
30 struct CDString128\r
31 {\r
32   Byte Data[128];\r
33   void Parse(const Byte *buf);\r
34   UString GetString() const;\r
35 };\r
36 \r
37 struct CDString\r
38 {\r
39   CByteBuffer Data;\r
40   void Parse(const Byte *p, unsigned size);\r
41   UString GetString() const;\r
42 };\r
43 \r
44 \r
45 // ECMA 1/7.3\r
46 \r
47 struct CTime\r
48 {\r
49   Byte Data[12];\r
50 \r
51   unsigned GetType() const { return Data[1] >> 4; }\r
52   bool IsLocal() const { return GetType() == 1; }\r
53   int GetMinutesOffset() const\r
54   {\r
55     int t = (Data[0] | ((UInt16)Data[1] << 8)) & 0xFFF;\r
56     if ((t >> 11) != 0)\r
57       t -= (1 << 12);\r
58     return (t > (60 * 24) || t < -(60 * 24)) ? 0 : t;\r
59   }\r
60   unsigned GetYear() const { return (Data[2] | ((UInt16)Data[3] << 8)); }\r
61   void Parse(const Byte *buf);\r
62 };\r
63 \r
64 \r
65 // ECMA 1/7.4\r
66 \r
67 /*\r
68 struct CRegId\r
69 {\r
70   Byte Flags;\r
71   char Id[23];\r
72   char Suffix[8];\r
73 \r
74   void Parse(const Byte *buf);\r
75 };\r
76 */\r
77 \r
78 // ---------- ECMA Part 3: Volume Structure ----------\r
79 \r
80 // ECMA 3/10.5\r
81 \r
82 struct CPartition\r
83 {\r
84   // UInt16 Flags;\r
85   UInt16 Number;\r
86   // CRegId ContentsId;\r
87   // Byte ContentsUse[128];\r
88   // UInt32 AccessType;\r
89 \r
90   UInt32 Pos;\r
91   UInt32 Len;\r
92 \r
93   // CRegId ImplId;\r
94   // Byte ImplUse[128];\r
95 \r
96   int VolIndex;\r
97   CMap32 Map;\r
98 \r
99   CPartition(): VolIndex(-1) {}\r
100 \r
101   // bool IsNsr() const { return (strncmp(ContentsId.Id, "+NSR0", 5) == 0); }\r
102   // bool IsAllocated() const { return ((Flags & 1) != 0); }\r
103 };\r
104 \r
105 struct CLogBlockAddr\r
106 {\r
107   UInt32 Pos;\r
108   UInt16 PartitionRef;\r
109   \r
110   void Parse(const Byte *buf);\r
111 };\r
112 \r
113 enum EShortAllocDescType\r
114 {\r
115   SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated = 0,\r
116   SHORT_ALLOC_DESC_TYPE_NotRecordedButAllocated = 1,\r
117   SHORT_ALLOC_DESC_TYPE_NotRecordedAndNotAllocated = 2,\r
118   SHORT_ALLOC_DESC_TYPE_NextExtent = 3\r
119 };\r
120 \r
121 struct CShortAllocDesc\r
122 {\r
123   UInt32 Len;\r
124   UInt32 Pos;\r
125 \r
126   // 4/14.14.1\r
127   // UInt32 GetLen() const { return Len & 0x3FFFFFFF; }\r
128   // UInt32 GetType() const { return Len >> 30; }\r
129   // bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; }\r
130   void Parse(const Byte *buf);\r
131 };\r
132 \r
133 /*\r
134 struct CADImpUse\r
135 {\r
136   UInt16 Flags;\r
137   UInt32 UdfUniqueId;\r
138   void Parse(const Byte *buf);\r
139 };\r
140 */\r
141 \r
142 struct CLongAllocDesc\r
143 {\r
144   UInt32 Len;\r
145   CLogBlockAddr Location;\r
146   \r
147   // Byte ImplUse[6];\r
148   // CADImpUse adImpUse; // UDF\r
149   \r
150   UInt32 GetLen() const { return Len & 0x3FFFFFFF; }\r
151   UInt32 GetType() const { return Len >> 30; }\r
152   bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; }\r
153   void Parse(const Byte *buf);\r
154 };\r
155 \r
156 struct CPartitionMap\r
157 {\r
158   Byte Type;\r
159   // Byte Len;\r
160 \r
161   // Type - 1\r
162   // UInt16 VolSeqNumber;\r
163   UInt16 PartitionNumber;\r
164 \r
165   // Byte Data[256];\r
166 \r
167   int PartitionIndex;\r
168 };\r
169 \r
170 // ECMA 4/14.6\r
171 \r
172 enum EIcbFileType\r
173 {\r
174   ICB_FILE_TYPE_DIR = 4,\r
175   ICB_FILE_TYPE_FILE = 5\r
176 };\r
177 \r
178 enum EIcbDescriptorType\r
179 {\r
180   ICB_DESC_TYPE_SHORT = 0,\r
181   ICB_DESC_TYPE_LONG = 1,\r
182   ICB_DESC_TYPE_EXTENDED = 2,\r
183   ICB_DESC_TYPE_INLINE = 3\r
184 };\r
185 \r
186 struct CIcbTag\r
187 {\r
188   // UInt32 PriorDirectNum;\r
189   // UInt16 StrategyType;\r
190   // UInt16 StrategyParam;\r
191   // UInt16 MaxNumOfEntries;\r
192   Byte FileType;\r
193   // CLogBlockAddr ParentIcb;\r
194   UInt16 Flags;\r
195 \r
196   bool IsDir() const { return FileType == ICB_FILE_TYPE_DIR; }\r
197   int GetDescriptorType() const { return Flags & 3; }\r
198   void Parse(const Byte *p);\r
199 };\r
200 \r
201 // const Byte FILEID_CHARACS_Existance = (1 << 0);\r
202 const Byte FILEID_CHARACS_Parent = (1 << 3);\r
203 \r
204 struct CFile\r
205 {\r
206   // UInt16 FileVersion;\r
207   // Byte FileCharacteristics;\r
208   // CByteBuffer ImplUse;\r
209   CDString Id;\r
210 \r
211   CFile(): /* FileVersion(0), FileCharacteristics(0), */ ItemIndex(-1) {}\r
212   int ItemIndex;\r
213   UString GetName() const { return Id.GetString(); }\r
214 };\r
215 \r
216 struct CMyExtent\r
217 {\r
218   UInt32 Pos;\r
219   UInt32 Len;\r
220   int PartitionRef;\r
221   \r
222   UInt32 GetLen() const { return Len & 0x3FFFFFFF; }\r
223   UInt32 GetType() const { return Len >> 30; }\r
224   bool IsRecAndAlloc() const { return GetType() == SHORT_ALLOC_DESC_TYPE_RecordedAndAllocated; }\r
225 };\r
226 \r
227 struct CItem\r
228 {\r
229   CIcbTag IcbTag;\r
230 \r
231   // UInt32 Uid;\r
232   // UInt32 Gid;\r
233   // UInt32 Permissions;\r
234   // UInt16 FileLinkCount;\r
235   // Byte RecordFormat;\r
236   // Byte RecordDisplayAttr;\r
237   // UInt32 RecordLen;\r
238   UInt64 Size;\r
239   UInt64 NumLogBlockRecorded;\r
240   CTime ATime;\r
241   CTime MTime;\r
242   // CTime AttrtTime;\r
243   // UInt32 CheckPoint;\r
244   // CLongAllocDesc ExtendedAttrIcb;\r
245   // CRegId ImplId;\r
246   // UInt64 UniqueId;\r
247 \r
248   bool IsInline;\r
249   CByteBuffer InlineData;\r
250   CRecordVector<CMyExtent> Extents;\r
251   CRecordVector<int> SubFiles;\r
252 \r
253   void Parse(const Byte *buf);\r
254 \r
255   bool IsRecAndAlloc() const\r
256   {\r
257     for (int i = 0; i < Extents.Size(); i++)\r
258       if (!Extents[i].IsRecAndAlloc())\r
259         return false;\r
260     return true;\r
261   }\r
262 \r
263   UInt64 GetChunksSumSize() const\r
264   {\r
265     if (IsInline)\r
266       return InlineData.GetCapacity();\r
267     UInt64 size = 0;\r
268     for (int i = 0; i < Extents.Size(); i++)\r
269       size += Extents[i].GetLen();\r
270     return size;\r
271   }\r
272 \r
273   bool CheckChunkSizes() const  {  return GetChunksSumSize() == Size; }\r
274 \r
275   bool IsDir() const { return IcbTag.IsDir(); }\r
276 };\r
277  \r
278 struct CRef\r
279 {\r
280   int Parent;\r
281   int FileIndex;\r
282 };\r
283 \r
284 \r
285 // ECMA 4 / 14.1\r
286 struct CFileSet\r
287 {\r
288   CTime RecodringTime;\r
289   // UInt16 InterchangeLevel;\r
290   // UInt16 MaxInterchangeLevel;\r
291   // UInt32 FileSetNumber;\r
292   // UInt32 FileSetDescNumber;\r
293   // CDString32 Id;\r
294   // CDString32 CopyrightId;\r
295   // CDString32 AbstractId;\r
296 \r
297   CLongAllocDesc RootDirICB;\r
298   // CRegId DomainId;\r
299   // CLongAllocDesc SystemStreamDirICB;\r
300 \r
301   CRecordVector<CRef> Refs;\r
302 };\r
303 \r
304 \r
305 // ECMA 3/10.6\r
306 \r
307 struct CLogVol\r
308 {\r
309   CDString128 Id;\r
310   UInt32 BlockSize;\r
311   // CRegId DomainId;\r
312   \r
313   // Byte ContentsUse[16];\r
314   CLongAllocDesc FileSetLocation; // UDF\r
315 \r
316   // CRegId ImplId;\r
317   // Byte ImplUse[128];\r
318 \r
319   CObjectVector<CPartitionMap> PartitionMaps;\r
320   CObjectVector<CFileSet> FileSets;\r
321 \r
322   UString GetName() const { return Id.GetString(); }\r
323 };\r
324 \r
325 struct CProgressVirt\r
326 {\r
327   virtual HRESULT SetTotal(UInt64 numBytes) PURE;\r
328   virtual HRESULT SetCompleted(UInt64 numFiles, UInt64 numBytes) PURE;\r
329   virtual HRESULT SetCompleted() PURE;\r
330 };\r
331 \r
332 class CInArchive\r
333 {\r
334   CMyComPtr<IInStream> _stream;\r
335   CProgressVirt *_progress;\r
336 \r
337   HRESULT Read(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len, Byte *buf);\r
338   HRESULT Read(int volIndex, const CLongAllocDesc &lad, Byte *buf);\r
339   HRESULT ReadFromFile(int volIndex, const CItem &item, CByteBuffer &buf);\r
340 \r
341   HRESULT ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed);\r
342   HRESULT ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed);\r
343 \r
344   HRESULT Open2();\r
345   HRESULT FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed);\r
346 \r
347   UInt64 _processedProgressBytes;\r
348 \r
349   UInt64 _fileNameLengthTotal;\r
350   int _numRefs;\r
351   UInt32 _numExtents;\r
352   UInt64 _inlineExtentsSize;\r
353   bool CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const;\r
354 public:\r
355   HRESULT Open(IInStream *inStream, CProgressVirt *progress);\r
356   void Clear();\r
357 \r
358   CObjectVector<CPartition> Partitions;\r
359   CObjectVector<CLogVol> LogVols;\r
360 \r
361   CObjectVector<CItem> Items;\r
362   CObjectVector<CFile> Files;\r
363 \r
364   int SecLogSize;\r
365 \r
366   UString GetComment() const;\r
367   UString GetItemPath(int volIndex, int fsIndex, int refIndex,\r
368       bool showVolName, bool showFsName) const;\r
369 \r
370   bool CheckItemExtents(int volIndex, const CItem &item) const;\r
371 };\r
372 \r
373 }}\r
374   \r
375 #endif\r