Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / Archive / Chm / ChmIn.h
1 // Archive/ChmIn.h\r
2 \r
3 #ifndef __ARCHIVE_CHM_IN_H\r
4 #define __ARCHIVE_CHM_IN_H\r
5 \r
6 #include "Common/Buffer.h"\r
7 #include "Common/MyString.h"\r
8 \r
9 #include "../../IStream.h"\r
10 #include "../../Common/InBuffer.h"\r
11 \r
12 #include "ChmHeader.h"\r
13 \r
14 namespace NArchive {\r
15 namespace NChm {\r
16 \r
17 struct CItem\r
18 {\r
19   UInt64 Section;\r
20   UInt64 Offset;\r
21   UInt64 Size;\r
22   AString Name;\r
23 \r
24   bool IsFormatRelatedItem() const\r
25   {\r
26     if (Name.Length() < 2)\r
27       return false;\r
28     return Name[0] == ':' && Name[1] == ':';\r
29   }\r
30   \r
31   bool IsUserItem() const\r
32   {\r
33     if (Name.Length() < 2)\r
34       return false;\r
35     return Name[0] == '/';\r
36   }\r
37   \r
38   bool IsDir() const\r
39   {\r
40     if (Name.Length() == 0)\r
41       return false;\r
42     return (Name[Name.Length() - 1] == '/');\r
43   }\r
44 };\r
45 \r
46 struct CDatabase\r
47 {\r
48   UInt64 ContentOffset;\r
49   CObjectVector<CItem> Items;\r
50   AString NewFormatString;\r
51   bool Help2Format;\r
52   bool NewFormat;\r
53 \r
54   int FindItem(const AString &name) const\r
55   {\r
56     for (int i = 0; i < Items.Size(); i++)\r
57       if (Items[i].Name == name)\r
58         return i;\r
59     return -1;\r
60   }\r
61 \r
62   void Clear()\r
63   {\r
64     NewFormat = false;\r
65     NewFormatString.Empty();\r
66     Help2Format = false;\r
67     Items.Clear();\r
68   }\r
69 };\r
70 \r
71 struct CResetTable\r
72 {\r
73   UInt64 UncompressedSize;\r
74   UInt64 CompressedSize;\r
75   UInt64 BlockSize;\r
76   CRecordVector<UInt64> ResetOffsets;\r
77   bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const\r
78   {\r
79     if (blockIndex >= ResetOffsets.Size())\r
80       return false;\r
81     UInt64 startPos = ResetOffsets[(int)blockIndex];\r
82     if (blockIndex + numBlocks >= ResetOffsets.Size())\r
83       size = CompressedSize - startPos;\r
84     else\r
85       size = ResetOffsets[(int)(blockIndex + numBlocks)] - startPos;\r
86     return true;\r
87   }\r
88   bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const\r
89   {\r
90     return GetCompressedSizeOfBlocks(blockIndex, 1, size);\r
91   }\r
92   UInt64 GetNumBlocks(UInt64 size) const\r
93   {\r
94     return (size + BlockSize - 1) / BlockSize;\r
95   }\r
96 };\r
97 \r
98 struct CLzxInfo\r
99 {\r
100   UInt32 Version;\r
101   UInt32 ResetInterval;\r
102   UInt32 WindowSize;\r
103   UInt32 CacheSize;\r
104   CResetTable ResetTable;\r
105 \r
106   UInt32 GetNumDictBits() const\r
107   {\r
108     if (Version == 2 || Version == 3)\r
109     {\r
110       for (int i = 0; i <= 31; i++)\r
111         if (((UInt32)1 << i) >= WindowSize)\r
112           return 15 + i;\r
113     }\r
114     return 0;\r
115   }\r
116 \r
117   UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; };\r
118   UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); };\r
119   UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); };\r
120   UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; };\r
121   bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const\r
122   {\r
123     UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);\r
124     if (blockIndex >= ResetTable.ResetOffsets.Size())\r
125       return false;\r
126     offset = ResetTable.ResetOffsets[(int)blockIndex];\r
127     return true;\r
128   }\r
129   bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const\r
130   {\r
131     UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);\r
132     return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size);\r
133   }\r
134 };\r
135 \r
136 struct CMethodInfo\r
137 {\r
138   GUID Guid;\r
139   CByteBuffer ControlData;\r
140   CLzxInfo LzxInfo;\r
141   bool IsLzx() const;\r
142   bool IsDes() const;\r
143   AString GetGuidString() const;\r
144   UString GetName() const;\r
145 };\r
146 \r
147 struct CSectionInfo\r
148 {\r
149   UInt64 Offset;\r
150   UInt64 CompressedSize;\r
151   UInt64 UncompressedSize;\r
152 \r
153   AString Name;\r
154   CObjectVector<CMethodInfo> Methods;\r
155 \r
156   bool IsLzx() const;\r
157   UString GetMethodName() const;\r
158 };\r
159 \r
160 class CFilesDatabase: public CDatabase\r
161 {\r
162 public:\r
163   bool LowLevel;\r
164   CRecordVector<int> Indices;\r
165   CObjectVector<CSectionInfo> Sections;\r
166 \r
167   UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; }\r
168   UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; }\r
169 \r
170   UInt64 GetFolder(int fileIndex) const\r
171   {\r
172     const CItem &item = Items[Indices[fileIndex]];\r
173     const CSectionInfo &section = Sections[(int)item.Section];\r
174     if (section.IsLzx())\r
175       return section.Methods[0].LzxInfo.GetFolder(item.Offset);\r
176     return 0;\r
177   }\r
178 \r
179   UInt64 GetLastFolder(int fileIndex) const\r
180   {\r
181     const CItem &item = Items[Indices[fileIndex]];\r
182     const CSectionInfo &section = Sections[(int)item.Section];\r
183     if (section.IsLzx())\r
184       return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);\r
185     return 0;\r
186   }\r
187 \r
188   void HighLevelClear()\r
189   {\r
190     LowLevel = true;\r
191     Indices.Clear();\r
192     Sections.Clear();\r
193   }\r
194 \r
195   void Clear()\r
196   {\r
197     CDatabase::Clear();\r
198     HighLevelClear();\r
199   }\r
200   void SetIndices();\r
201   void Sort();\r
202   bool Check();\r
203 };\r
204 \r
205 class CProgressVirt\r
206 {\r
207 public:\r
208   STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;\r
209   STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;\r
210 };\r
211 \r
212 class CInArchive\r
213 {\r
214   UInt64 _startPosition;\r
215   ::CInBuffer _inBuffer;\r
216   UInt64 _chunkSize;\r
217 \r
218   Byte ReadByte();\r
219   void ReadBytes(Byte *data, UInt32 size);\r
220   void Skip(size_t size);\r
221   UInt16 ReadUInt16();\r
222   UInt32 ReadUInt32();\r
223   UInt64 ReadUInt64();\r
224   UInt64 ReadEncInt();\r
225   void ReadString(int size, AString &s);\r
226   void ReadUString(int size, UString &s);\r
227   void ReadGUID(GUID &g);\r
228 \r
229   HRESULT ReadChunk(IInStream *inStream, UInt64 pos, UInt64 size);\r
230 \r
231   HRESULT ReadDirEntry(CDatabase &database);\r
232   HRESULT DecompressStream(IInStream *inStream, const CDatabase &database, const AString &name);\r
233 \r
234 public:\r
235   HRESULT OpenChm(IInStream *inStream, CDatabase &database);\r
236   HRESULT OpenHelp2(IInStream *inStream, CDatabase &database);\r
237   HRESULT OpenHighLevel(IInStream *inStream, CFilesDatabase &database);\r
238   HRESULT Open2(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);\r
239   HRESULT Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit, CFilesDatabase &database);\r
240 };\r
241   \r
242 }}\r
243   \r
244 #endif\r