diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-15 21:04:28 +0100 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-24 18:05:53 +0100 |
commit | c876d3bbefe0dc00c27ca0c12d29da5874946962 (patch) | |
tree | 69f468a185a369b01998314bc3ecc19b70f4fcaa /utils/rbutilqt/quazip | |
parent | 6c6f0757d7a902feb293be165d1490c42bc8e7ad (diff) | |
download | rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.tar.gz rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.zip |
rbutil: Merge rbutil with utils folder.
rbutil uses several components from the utils folder, and can be
considered part of utils too. Having it in a separate folder is an
arbitrary split that doesn't help anymore these days, so merge them.
This also allows other utils to easily use libtools.make without the
need to navigate to a different folder.
Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21
Diffstat (limited to 'utils/rbutilqt/quazip')
-rw-r--r-- | utils/rbutilqt/quazip/LICENSE.LGPL | 458 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/README.ROCKBOX | 9 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/ioapi.h | 207 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/minizip_crypt.h | 135 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/qioapi.cpp | 363 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazip.cpp | 846 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazip.h | 611 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazip.pri | 25 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazip_global.h | 63 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazipfile.cpp | 570 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazipfile.h | 508 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazipfileinfo.cpp | 196 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazipfileinfo.h | 226 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazipnewinfo.cpp | 290 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/quazipnewinfo.h | 208 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/unzip.c | 2163 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/unzip.h | 461 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/zip.c | 2111 | ||||
-rw-r--r-- | utils/rbutilqt/quazip/zip.h | 391 |
19 files changed, 9841 insertions, 0 deletions
diff --git a/utils/rbutilqt/quazip/LICENSE.LGPL b/utils/rbutilqt/quazip/LICENSE.LGPL new file mode 100644 index 0000000000..2cba2ac74c --- /dev/null +++ b/utils/rbutilqt/quazip/LICENSE.LGPL | |||
@@ -0,0 +1,458 @@ | |||
1 | GNU LESSER GENERAL PUBLIC LICENSE | ||
2 | Version 2.1, February 1999 | ||
3 | |||
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. | ||
5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
6 | Everyone is permitted to copy and distribute verbatim copies | ||
7 | of this license document, but changing it is not allowed. | ||
8 | |||
9 | [This is the first released version of the Lesser GPL. It also counts | ||
10 | as the successor of the GNU Library Public License, version 2, hence | ||
11 | the version number 2.1.] | ||
12 | |||
13 | Preamble | ||
14 | |||
15 | The licenses for most software are designed to take away your | ||
16 | freedom to share and change it. By contrast, the GNU General Public | ||
17 | Licenses are intended to guarantee your freedom to share and change | ||
18 | free software--to make sure the software is free for all its users. | ||
19 | |||
20 | This license, the Lesser General Public License, applies to some | ||
21 | specially designated software packages--typically libraries--of the | ||
22 | Free Software Foundation and other authors who decide to use it. You | ||
23 | can use it too, but we suggest you first think carefully about whether | ||
24 | this license or the ordinary General Public License is the better | ||
25 | strategy to use in any particular case, based on the explanations below. | ||
26 | |||
27 | When we speak of free software, we are referring to freedom of use, | ||
28 | not price. Our General Public Licenses are designed to make sure that | ||
29 | you have the freedom to distribute copies of free software (and charge | ||
30 | for this service if you wish); that you receive source code or can get | ||
31 | it if you want it; that you can change the software and use pieces of | ||
32 | it in new free programs; and that you are informed that you can do | ||
33 | these things. | ||
34 | |||
35 | To protect your rights, we need to make restrictions that forbid | ||
36 | distributors to deny you these rights or to ask you to surrender these | ||
37 | rights. These restrictions translate to certain responsibilities for | ||
38 | you if you distribute copies of the library or if you modify it. | ||
39 | |||
40 | For example, if you distribute copies of the library, whether gratis | ||
41 | or for a fee, you must give the recipients all the rights that we gave | ||
42 | you. You must make sure that they, too, receive or can get the source | ||
43 | code. If you link other code with the library, you must provide | ||
44 | complete object files to the recipients, so that they can relink them | ||
45 | with the library after making changes to the library and recompiling | ||
46 | it. And you must show them these terms so they know their rights. | ||
47 | |||
48 | We protect your rights with a two-step method: (1) we copyright the | ||
49 | library, and (2) we offer you this license, which gives you legal | ||
50 | permission to copy, distribute and/or modify the library. | ||
51 | |||
52 | To protect each distributor, we want to make it very clear that | ||
53 | there is no warranty for the free library. Also, if the library is | ||
54 | modified by someone else and passed on, the recipients should know | ||
55 | that what they have is not the original version, so that the original | ||
56 | author's reputation will not be affected by problems that might be | ||
57 | introduced by others. | ||
58 | |||
59 | Finally, software patents pose a constant threat to the existence of | ||
60 | any free program. We wish to make sure that a company cannot | ||
61 | effectively restrict the users of a free program by obtaining a | ||
62 | restrictive license from a patent holder. Therefore, we insist that | ||
63 | any patent license obtained for a version of the library must be | ||
64 | consistent with the full freedom of use specified in this license. | ||
65 | |||
66 | Most GNU software, including some libraries, is covered by the | ||
67 | ordinary GNU General Public License. This license, the GNU Lesser | ||
68 | General Public License, applies to certain designated libraries, and | ||
69 | is quite different from the ordinary General Public License. We use | ||
70 | this license for certain libraries in order to permit linking those | ||
71 | libraries into non-free programs. | ||
72 | |||
73 | When a program is linked with a library, whether statically or using | ||
74 | a shared library, the combination of the two is legally speaking a | ||
75 | combined work, a derivative of the original library. The ordinary | ||
76 | General Public License therefore permits such linking only if the | ||
77 | entire combination fits its criteria of freedom. The Lesser General | ||
78 | Public License permits more lax criteria for linking other code with | ||
79 | the library. | ||
80 | |||
81 | We call this license the "Lesser" General Public License because it | ||
82 | does Less to protect the user's freedom than the ordinary General | ||
83 | Public License. It also provides other free software developers Less | ||
84 | of an advantage over competing non-free programs. These disadvantages | ||
85 | are the reason we use the ordinary General Public License for many | ||
86 | libraries. However, the Lesser license provides advantages in certain | ||
87 | special circumstances. | ||
88 | |||
89 | For example, on rare occasions, there may be a special need to | ||
90 | encourage the widest possible use of a certain library, so that it becomes | ||
91 | a de-facto standard. To achieve this, non-free programs must be | ||
92 | allowed to use the library. A more frequent case is that a free | ||
93 | library does the same job as widely used non-free libraries. In this | ||
94 | case, there is little to gain by limiting the free library to free | ||
95 | software only, so we use the Lesser General Public License. | ||
96 | |||
97 | In other cases, permission to use a particular library in non-free | ||
98 | programs enables a greater number of people to use a large body of | ||
99 | free software. For example, permission to use the GNU C Library in | ||
100 | non-free programs enables many more people to use the whole GNU | ||
101 | operating system, as well as its variant, the GNU/Linux operating | ||
102 | system. | ||
103 | |||
104 | Although the Lesser General Public License is Less protective of the | ||
105 | users' freedom, it does ensure that the user of a program that is | ||
106 | linked with the Library has the freedom and the wherewithal to run | ||
107 | that program using a modified version of the Library. | ||
108 | |||
109 | The precise terms and conditions for copying, distribution and | ||
110 | modification follow. Pay close attention to the difference between a | ||
111 | "work based on the library" and a "work that uses the library". The | ||
112 | former contains code derived from the library, whereas the latter must | ||
113 | be combined with the library in order to run. | ||
114 | |||
115 | GNU LESSER GENERAL PUBLIC LICENSE | ||
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
117 | |||
118 | 0. This License Agreement applies to any software library or other | ||
119 | program which contains a notice placed by the copyright holder or | ||
120 | other authorized party saying it may be distributed under the terms of | ||
121 | this Lesser General Public License (also called "this License"). | ||
122 | Each licensee is addressed as "you". | ||
123 | |||
124 | A "library" means a collection of software functions and/or data | ||
125 | prepared so as to be conveniently linked with application programs | ||
126 | (which use some of those functions and data) to form executables. | ||
127 | |||
128 | The "Library", below, refers to any such software library or work | ||
129 | which has been distributed under these terms. A "work based on the | ||
130 | Library" means either the Library or any derivative work under | ||
131 | copyright law: that is to say, a work containing the Library or a | ||
132 | portion of it, either verbatim or with modifications and/or translated | ||
133 | straightforwardly into another language. (Hereinafter, translation is | ||
134 | included without limitation in the term "modification".) | ||
135 | |||
136 | "Source code" for a work means the preferred form of the work for | ||
137 | making modifications to it. For a library, complete source code means | ||
138 | all the source code for all modules it contains, plus any associated | ||
139 | interface definition files, plus the scripts used to control compilation | ||
140 | and installation of the library. | ||
141 | |||
142 | Activities other than copying, distribution and modification are not | ||
143 | covered by this License; they are outside its scope. The act of | ||
144 | running a program using the Library is not restricted, and output from | ||
145 | such a program is covered only if its contents constitute a work based | ||
146 | on the Library (independent of the use of the Library in a tool for | ||
147 | writing it). Whether that is true depends on what the Library does | ||
148 | and what the program that uses the Library does. | ||
149 | |||
150 | 1. You may copy and distribute verbatim copies of the Library's | ||
151 | complete source code as you receive it, in any medium, provided that | ||
152 | you conspicuously and appropriately publish on each copy an | ||
153 | appropriate copyright notice and disclaimer of warranty; keep intact | ||
154 | all the notices that refer to this License and to the absence of any | ||
155 | warranty; and distribute a copy of this License along with the | ||
156 | Library. | ||
157 | |||
158 | You may charge a fee for the physical act of transferring a copy, | ||
159 | and you may at your option offer warranty protection in exchange for a | ||
160 | fee. | ||
161 | |||
162 | 2. You may modify your copy or copies of the Library or any portion | ||
163 | of it, thus forming a work based on the Library, and copy and | ||
164 | distribute such modifications or work under the terms of Section 1 | ||
165 | above, provided that you also meet all of these conditions: | ||
166 | |||
167 | a) The modified work must itself be a software library. | ||
168 | |||
169 | b) You must cause the files modified to carry prominent notices | ||
170 | stating that you changed the files and the date of any change. | ||
171 | |||
172 | c) You must cause the whole of the work to be licensed at no | ||
173 | charge to all third parties under the terms of this License. | ||
174 | |||
175 | d) If a facility in the modified Library refers to a function or a | ||
176 | table of data to be supplied by an application program that uses | ||
177 | the facility, other than as an argument passed when the facility | ||
178 | is invoked, then you must make a good faith effort to ensure that, | ||
179 | in the event an application does not supply such function or | ||
180 | table, the facility still operates, and performs whatever part of | ||
181 | its purpose remains meaningful. | ||
182 | |||
183 | (For example, a function in a library to compute square roots has | ||
184 | a purpose that is entirely well-defined independent of the | ||
185 | application. Therefore, Subsection 2d requires that any | ||
186 | application-supplied function or table used by this function must | ||
187 | be optional: if the application does not supply it, the square | ||
188 | root function must still compute square roots.) | ||
189 | |||
190 | These requirements apply to the modified work as a whole. If | ||
191 | identifiable sections of that work are not derived from the Library, | ||
192 | and can be reasonably considered independent and separate works in | ||
193 | themselves, then this License, and its terms, do not apply to those | ||
194 | sections when you distribute them as separate works. But when you | ||
195 | distribute the same sections as part of a whole which is a work based | ||
196 | on the Library, the distribution of the whole must be on the terms of | ||
197 | this License, whose permissions for other licensees extend to the | ||
198 | entire whole, and thus to each and every part regardless of who wrote | ||
199 | it. | ||
200 | |||
201 | Thus, it is not the intent of this section to claim rights or contest | ||
202 | your rights to work written entirely by you; rather, the intent is to | ||
203 | exercise the right to control the distribution of derivative or | ||
204 | collective works based on the Library. | ||
205 | |||
206 | In addition, mere aggregation of another work not based on the Library | ||
207 | with the Library (or with a work based on the Library) on a volume of | ||
208 | a storage or distribution medium does not bring the other work under | ||
209 | the scope of this License. | ||
210 | |||
211 | 3. You may opt to apply the terms of the ordinary GNU General Public | ||
212 | License instead of this License to a given copy of the Library. To do | ||
213 | this, you must alter all the notices that refer to this License, so | ||
214 | that they refer to the ordinary GNU General Public License, version 2, | ||
215 | instead of to this License. (If a newer version than version 2 of the | ||
216 | ordinary GNU General Public License has appeared, then you can specify | ||
217 | that version instead if you wish.) Do not make any other change in | ||
218 | these notices. | ||
219 | |||
220 | Once this change is made in a given copy, it is irreversible for | ||
221 | that copy, so the ordinary GNU General Public License applies to all | ||
222 | subsequent copies and derivative works made from that copy. | ||
223 | |||
224 | This option is useful when you wish to copy part of the code of | ||
225 | the Library into a program that is not a library. | ||
226 | |||
227 | 4. You may copy and distribute the Library (or a portion or | ||
228 | derivative of it, under Section 2) in object code or executable form | ||
229 | under the terms of Sections 1 and 2 above provided that you accompany | ||
230 | it with the complete corresponding machine-readable source code, which | ||
231 | must be distributed under the terms of Sections 1 and 2 above on a | ||
232 | medium customarily used for software interchange. | ||
233 | |||
234 | If distribution of object code is made by offering access to copy | ||
235 | from a designated place, then offering equivalent access to copy the | ||
236 | source code from the same place satisfies the requirement to | ||
237 | distribute the source code, even though third parties are not | ||
238 | compelled to copy the source along with the object code. | ||
239 | |||
240 | 5. A program that contains no derivative of any portion of the | ||
241 | Library, but is designed to work with the Library by being compiled or | ||
242 | linked with it, is called a "work that uses the Library". Such a | ||
243 | work, in isolation, is not a derivative work of the Library, and | ||
244 | therefore falls outside the scope of this License. | ||
245 | |||
246 | However, linking a "work that uses the Library" with the Library | ||
247 | creates an executable that is a derivative of the Library (because it | ||
248 | contains portions of the Library), rather than a "work that uses the | ||
249 | library". The executable is therefore covered by this License. | ||
250 | Section 6 states terms for distribution of such executables. | ||
251 | |||
252 | When a "work that uses the Library" uses material from a header file | ||
253 | that is part of the Library, the object code for the work may be a | ||
254 | derivative work of the Library even though the source code is not. | ||
255 | Whether this is true is especially significant if the work can be | ||
256 | linked without the Library, or if the work is itself a library. The | ||
257 | threshold for this to be true is not precisely defined by law. | ||
258 | |||
259 | If such an object file uses only numerical parameters, data | ||
260 | structure layouts and accessors, and small macros and small inline | ||
261 | functions (ten lines or less in length), then the use of the object | ||
262 | file is unrestricted, regardless of whether it is legally a derivative | ||
263 | work. (Executables containing this object code plus portions of the | ||
264 | Library will still fall under Section 6.) | ||
265 | |||
266 | Otherwise, if the work is a derivative of the Library, you may | ||
267 | distribute the object code for the work under the terms of Section 6. | ||
268 | Any executables containing that work also fall under Section 6, | ||
269 | whether or not they are linked directly with the Library itself. | ||
270 | |||
271 | 6. As an exception to the Sections above, you may also combine or | ||
272 | link a "work that uses the Library" with the Library to produce a | ||
273 | work containing portions of the Library, and distribute that work | ||
274 | under terms of your choice, provided that the terms permit | ||
275 | modification of the work for the customer's own use and reverse | ||
276 | engineering for debugging such modifications. | ||
277 | |||
278 | You must give prominent notice with each copy of the work that the | ||
279 | Library is used in it and that the Library and its use are covered by | ||
280 | this License. You must supply a copy of this License. If the work | ||
281 | during execution displays copyright notices, you must include the | ||
282 | copyright notice for the Library among them, as well as a reference | ||
283 | directing the user to the copy of this License. Also, you must do one | ||
284 | of these things: | ||
285 | |||
286 | a) Accompany the work with the complete corresponding | ||
287 | machine-readable source code for the Library including whatever | ||
288 | changes were used in the work (which must be distributed under | ||
289 | Sections 1 and 2 above); and, if the work is an executable linked | ||
290 | with the Library, with the complete machine-readable "work that | ||
291 | uses the Library", as object code and/or source code, so that the | ||
292 | user can modify the Library and then relink to produce a modified | ||
293 | executable containing the modified Library. (It is understood | ||
294 | that the user who changes the contents of definitions files in the | ||
295 | Library will not necessarily be able to recompile the application | ||
296 | to use the modified definitions.) | ||
297 | |||
298 | b) Use a suitable shared library mechanism for linking with the | ||
299 | Library. A suitable mechanism is one that (1) uses at run time a | ||
300 | copy of the library already present on the user's computer system, | ||
301 | rather than copying library functions into the executable, and (2) | ||
302 | will operate properly with a modified version of the library, if | ||
303 | the user installs one, as long as the modified version is | ||
304 | interface-compatible with the version that the work was made with. | ||
305 | |||
306 | c) Accompany the work with a written offer, valid for at | ||
307 | least three years, to give the same user the materials | ||
308 | specified in Subsection 6a, above, for a charge no more | ||
309 | than the cost of performing this distribution. | ||
310 | |||
311 | d) If distribution of the work is made by offering access to copy | ||
312 | from a designated place, offer equivalent access to copy the above | ||
313 | specified materials from the same place. | ||
314 | |||
315 | e) Verify that the user has already received a copy of these | ||
316 | materials or that you have already sent this user a copy. | ||
317 | |||
318 | For an executable, the required form of the "work that uses the | ||
319 | Library" must include any data and utility programs needed for | ||
320 | reproducing the executable from it. However, as a special exception, | ||
321 | the materials to be distributed need not include anything that is | ||
322 | normally distributed (in either source or binary form) with the major | ||
323 | components (compiler, kernel, and so on) of the operating system on | ||
324 | which the executable runs, unless that component itself accompanies | ||
325 | the executable. | ||
326 | |||
327 | It may happen that this requirement contradicts the license | ||
328 | restrictions of other proprietary libraries that do not normally | ||
329 | accompany the operating system. Such a contradiction means you cannot | ||
330 | use both them and the Library together in an executable that you | ||
331 | distribute. | ||
332 | |||
333 | 7. You may place library facilities that are a work based on the | ||
334 | Library side-by-side in a single library together with other library | ||
335 | facilities not covered by this License, and distribute such a combined | ||
336 | library, provided that the separate distribution of the work based on | ||
337 | the Library and of the other library facilities is otherwise | ||
338 | permitted, and provided that you do these two things: | ||
339 | |||
340 | a) Accompany the combined library with a copy of the same work | ||
341 | based on the Library, uncombined with any other library | ||
342 | facilities. This must be distributed under the terms of the | ||
343 | Sections above. | ||
344 | |||
345 | b) Give prominent notice with the combined library of the fact | ||
346 | that part of it is a work based on the Library, and explaining | ||
347 | where to find the accompanying uncombined form of the same work. | ||
348 | |||
349 | 8. You may not copy, modify, sublicense, link with, or distribute | ||
350 | the Library except as expressly provided under this License. Any | ||
351 | attempt otherwise to copy, modify, sublicense, link with, or | ||
352 | distribute the Library is void, and will automatically terminate your | ||
353 | rights under this License. However, parties who have received copies, | ||
354 | or rights, from you under this License will not have their licenses | ||
355 | terminated so long as such parties remain in full compliance. | ||
356 | |||
357 | 9. You are not required to accept this License, since you have not | ||
358 | signed it. However, nothing else grants you permission to modify or | ||
359 | distribute the Library or its derivative works. These actions are | ||
360 | prohibited by law if you do not accept this License. Therefore, by | ||
361 | modifying or distributing the Library (or any work based on the | ||
362 | Library), you indicate your acceptance of this License to do so, and | ||
363 | all its terms and conditions for copying, distributing or modifying | ||
364 | the Library or works based on it. | ||
365 | |||
366 | 10. Each time you redistribute the Library (or any work based on the | ||
367 | Library), the recipient automatically receives a license from the | ||
368 | original licensor to copy, distribute, link with or modify the Library | ||
369 | subject to these terms and conditions. You may not impose any further | ||
370 | restrictions on the recipients' exercise of the rights granted herein. | ||
371 | You are not responsible for enforcing compliance by third parties with | ||
372 | this License. | ||
373 | |||
374 | 11. If, as a consequence of a court judgment or allegation of patent | ||
375 | infringement or for any other reason (not limited to patent issues), | ||
376 | conditions are imposed on you (whether by court order, agreement or | ||
377 | otherwise) that contradict the conditions of this License, they do not | ||
378 | excuse you from the conditions of this License. If you cannot | ||
379 | distribute so as to satisfy simultaneously your obligations under this | ||
380 | License and any other pertinent obligations, then as a consequence you | ||
381 | may not distribute the Library at all. For example, if a patent | ||
382 | license would not permit royalty-free redistribution of the Library by | ||
383 | all those who receive copies directly or indirectly through you, then | ||
384 | the only way you could satisfy both it and this License would be to | ||
385 | refrain entirely from distribution of the Library. | ||
386 | |||
387 | If any portion of this section is held invalid or unenforceable under any | ||
388 | particular circumstance, the balance of the section is intended to apply, | ||
389 | and the section as a whole is intended to apply in other circumstances. | ||
390 | |||
391 | It is not the purpose of this section to induce you to infringe any | ||
392 | patents or other property right claims or to contest validity of any | ||
393 | such claims; this section has the sole purpose of protecting the | ||
394 | integrity of the free software distribution system which is | ||
395 | implemented by public license practices. Many people have made | ||
396 | generous contributions to the wide range of software distributed | ||
397 | through that system in reliance on consistent application of that | ||
398 | system; it is up to the author/donor to decide if he or she is willing | ||
399 | to distribute software through any other system and a licensee cannot | ||
400 | impose that choice. | ||
401 | |||
402 | This section is intended to make thoroughly clear what is believed to | ||
403 | be a consequence of the rest of this License. | ||
404 | |||
405 | 12. If the distribution and/or use of the Library is restricted in | ||
406 | certain countries either by patents or by copyrighted interfaces, the | ||
407 | original copyright holder who places the Library under this License may add | ||
408 | an explicit geographical distribution limitation excluding those countries, | ||
409 | so that distribution is permitted only in or among countries not thus | ||
410 | excluded. In such case, this License incorporates the limitation as if | ||
411 | written in the body of this License. | ||
412 | |||
413 | 13. The Free Software Foundation may publish revised and/or new | ||
414 | versions of the Lesser General Public License from time to time. | ||
415 | Such new versions will be similar in spirit to the present version, | ||
416 | but may differ in detail to address new problems or concerns. | ||
417 | |||
418 | Each version is given a distinguishing version number. If the Library | ||
419 | specifies a version number of this License which applies to it and | ||
420 | "any later version", you have the option of following the terms and | ||
421 | conditions either of that version or of any later version published by | ||
422 | the Free Software Foundation. If the Library does not specify a | ||
423 | license version number, you may choose any version ever published by | ||
424 | the Free Software Foundation. | ||
425 | |||
426 | 14. If you wish to incorporate parts of the Library into other free | ||
427 | programs whose distribution conditions are incompatible with these, | ||
428 | write to the author to ask for permission. For software which is | ||
429 | copyrighted by the Free Software Foundation, write to the Free | ||
430 | Software Foundation; we sometimes make exceptions for this. Our | ||
431 | decision will be guided by the two goals of preserving the free status | ||
432 | of all derivatives of our free software and of promoting the sharing | ||
433 | and reuse of software generally. | ||
434 | |||
435 | NO WARRANTY | ||
436 | |||
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO | ||
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. | ||
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | ||
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY | ||
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE | ||
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE | ||
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME | ||
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | ||
446 | |||
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN | ||
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY | ||
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU | ||
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR | ||
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE | ||
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING | ||
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A | ||
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF | ||
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | ||
456 | DAMAGES. | ||
457 | |||
458 | END OF TERMS AND CONDITIONS | ||
diff --git a/utils/rbutilqt/quazip/README.ROCKBOX b/utils/rbutilqt/quazip/README.ROCKBOX new file mode 100644 index 0000000000..a168b2a079 --- /dev/null +++ b/utils/rbutilqt/quazip/README.ROCKBOX | |||
@@ -0,0 +1,9 @@ | |||
1 | This folder contains the quazip project for ZIP file compression/decompression. | ||
2 | These files are distributed under the LGPL v2.1 or later. Only source files | ||
3 | actually used in Rockbox Utility are included, further sources have been left | ||
4 | out. Check the quazip source distribution for those. | ||
5 | |||
6 | The source files have been last synced with the projects release 0.9.1 at | ||
7 | https://github.com/stachenov/quazip/ on June 8, 2020. | ||
8 | |||
9 | |||
diff --git a/utils/rbutilqt/quazip/ioapi.h b/utils/rbutilqt/quazip/ioapi.h new file mode 100644 index 0000000000..75d0aa6933 --- /dev/null +++ b/utils/rbutilqt/quazip/ioapi.h | |||
@@ -0,0 +1,207 @@ | |||
1 | /* ioapi.h -- IO base function header for compress/uncompress .zip | ||
2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | ||
3 | |||
4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) | ||
5 | |||
6 | Modifications for Zip64 support | ||
7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | ||
8 | |||
9 | Modified by Sergey A. Tachenov to allow QIODevice API usage. | ||
10 | |||
11 | For more info read MiniZip_info.txt | ||
12 | |||
13 | Changes | ||
14 | |||
15 | Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) | ||
16 | Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. | ||
17 | More if/def section may be needed to support other platforms | ||
18 | Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. | ||
19 | (but you should use iowin32.c for windows instead) | ||
20 | |||
21 | */ | ||
22 | |||
23 | #ifndef _ZLIBIOAPI64_H | ||
24 | #define _ZLIBIOAPI64_H | ||
25 | |||
26 | #if (!defined(_WIN32)) && (!defined(WIN32)) | ||
27 | |||
28 | // Linux needs this to support file operation on files larger then 4+GB | ||
29 | // But might need better if/def to select just the platforms that needs them. | ||
30 | |||
31 | #ifndef __USE_FILE_OFFSET64 | ||
32 | #define __USE_FILE_OFFSET64 | ||
33 | #endif | ||
34 | #ifndef __USE_LARGEFILE64 | ||
35 | #define __USE_LARGEFILE64 | ||
36 | #endif | ||
37 | #ifndef _LARGEFILE64_SOURCE | ||
38 | #define _LARGEFILE64_SOURCE | ||
39 | #endif | ||
40 | #ifndef _FILE_OFFSET_BIT | ||
41 | #define _FILE_OFFSET_BIT 64 | ||
42 | #endif | ||
43 | #endif | ||
44 | |||
45 | #include <stdio.h> | ||
46 | #include <stdlib.h> | ||
47 | #include <zlib.h> | ||
48 | |||
49 | #if defined(USE_FILE32API) | ||
50 | #define fopen64 fopen | ||
51 | #define ftello64 ftell | ||
52 | #define fseeko64 fseek | ||
53 | #else | ||
54 | #ifdef _MSC_VER | ||
55 | #define fopen64 fopen | ||
56 | #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) | ||
57 | #define ftello64 _ftelli64 | ||
58 | #define fseeko64 _fseeki64 | ||
59 | #else // old MSC | ||
60 | #define ftello64 ftell | ||
61 | #define fseeko64 fseek | ||
62 | #endif | ||
63 | #endif | ||
64 | #endif | ||
65 | |||
66 | /* | ||
67 | #ifndef ZPOS64_T | ||
68 | #ifdef _WIN32 | ||
69 | #define ZPOS64_T fpos_t | ||
70 | #else | ||
71 | #include <stdint.h> | ||
72 | #define ZPOS64_T uint64_t | ||
73 | #endif | ||
74 | #endif | ||
75 | */ | ||
76 | |||
77 | #ifdef HAVE_MINIZIP64_CONF_H | ||
78 | #include "mz64conf.h" | ||
79 | #endif | ||
80 | |||
81 | /* a type choosen by DEFINE */ | ||
82 | #ifdef HAVE_64BIT_INT_CUSTOM | ||
83 | typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; | ||
84 | #else | ||
85 | #ifdef HAS_STDINT_H | ||
86 | #include "stdint.h" | ||
87 | typedef uint64_t ZPOS64_T; | ||
88 | #else | ||
89 | |||
90 | |||
91 | #if defined(_MSC_VER) || defined(__BORLANDC__) | ||
92 | typedef unsigned __int64 ZPOS64_T; | ||
93 | #else | ||
94 | typedef unsigned long long int ZPOS64_T; | ||
95 | #endif | ||
96 | #endif | ||
97 | #endif | ||
98 | |||
99 | |||
100 | |||
101 | #ifdef __cplusplus | ||
102 | extern "C" { | ||
103 | #endif | ||
104 | |||
105 | #ifndef OF | ||
106 | #define OF _Z_OF | ||
107 | #endif | ||
108 | |||
109 | #define ZLIB_FILEFUNC_SEEK_CUR (1) | ||
110 | #define ZLIB_FILEFUNC_SEEK_END (2) | ||
111 | #define ZLIB_FILEFUNC_SEEK_SET (0) | ||
112 | |||
113 | #define ZLIB_FILEFUNC_MODE_READ (1) | ||
114 | #define ZLIB_FILEFUNC_MODE_WRITE (2) | ||
115 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) | ||
116 | |||
117 | #define ZLIB_FILEFUNC_MODE_EXISTING (4) | ||
118 | #define ZLIB_FILEFUNC_MODE_CREATE (8) | ||
119 | |||
120 | |||
121 | #ifndef ZCALLBACK | ||
122 | #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) | ||
123 | #define ZCALLBACK CALLBACK | ||
124 | #else | ||
125 | #define ZCALLBACK | ||
126 | #endif | ||
127 | #endif | ||
128 | |||
129 | |||
130 | |||
131 | |||
132 | typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode)); | ||
133 | typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); | ||
134 | typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); | ||
135 | typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); | ||
136 | typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); | ||
137 | |||
138 | typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); | ||
139 | typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); | ||
140 | |||
141 | |||
142 | /* here is the "old" 32 bits structure structure */ | ||
143 | typedef struct zlib_filefunc_def_s | ||
144 | { | ||
145 | open_file_func zopen_file; | ||
146 | read_file_func zread_file; | ||
147 | write_file_func zwrite_file; | ||
148 | tell_file_func ztell_file; | ||
149 | seek_file_func zseek_file; | ||
150 | close_file_func zclose_file; | ||
151 | testerror_file_func zerror_file; | ||
152 | voidpf opaque; | ||
153 | } zlib_filefunc_def; | ||
154 | |||
155 | typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); | ||
156 | typedef int (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); | ||
157 | typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, voidpf file, int mode)); | ||
158 | |||
159 | typedef struct zlib_filefunc64_def_s | ||
160 | { | ||
161 | open64_file_func zopen64_file; | ||
162 | read_file_func zread_file; | ||
163 | write_file_func zwrite_file; | ||
164 | tell64_file_func ztell64_file; | ||
165 | seek64_file_func zseek64_file; | ||
166 | close_file_func zclose_file; | ||
167 | testerror_file_func zerror_file; | ||
168 | voidpf opaque; | ||
169 | close_file_func zfakeclose_file; // for no-auto-close flag | ||
170 | } zlib_filefunc64_def; | ||
171 | |||
172 | void fill_qiodevice64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); | ||
173 | void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); | ||
174 | |||
175 | /* now internal definition, only for zip.c and unzip.h */ | ||
176 | typedef struct zlib_filefunc64_32_def_s | ||
177 | { | ||
178 | zlib_filefunc64_def zfile_func64; | ||
179 | open_file_func zopen32_file; | ||
180 | tell_file_func ztell32_file; | ||
181 | seek_file_func zseek32_file; | ||
182 | } zlib_filefunc64_32_def; | ||
183 | |||
184 | |||
185 | #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) | ||
186 | #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) | ||
187 | //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) | ||
188 | //#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) | ||
189 | #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) | ||
190 | #define ZFAKECLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zfakeclose_file)) ((filefunc).zfile_func64.opaque,filestream)) | ||
191 | #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) | ||
192 | |||
193 | voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode)); | ||
194 | int call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); | ||
195 | ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); | ||
196 | |||
197 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); | ||
198 | |||
199 | #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) | ||
200 | #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) | ||
201 | #define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) | ||
202 | |||
203 | #ifdef __cplusplus | ||
204 | } | ||
205 | #endif | ||
206 | |||
207 | #endif | ||
diff --git a/utils/rbutilqt/quazip/minizip_crypt.h b/utils/rbutilqt/quazip/minizip_crypt.h new file mode 100644 index 0000000000..2e833f7f3c --- /dev/null +++ b/utils/rbutilqt/quazip/minizip_crypt.h | |||
@@ -0,0 +1,135 @@ | |||
1 | /* crypt.h -- base code for crypt/uncrypt ZIPfile | ||
2 | |||
3 | |||
4 | Version 1.01e, February 12th, 2005 | ||
5 | |||
6 | Copyright (C) 1998-2005 Gilles Vollant | ||
7 | |||
8 | This code is a modified version of crypting code in Infozip distribution | ||
9 | |||
10 | The encryption/decryption parts of this source code (as opposed to the | ||
11 | non-echoing password parts) were originally written in Europe. The | ||
12 | whole source package can be freely distributed, including from the USA. | ||
13 | (Prior to January 2000, re-export from the US was a violation of US law.) | ||
14 | |||
15 | This encryption code is a direct transcription of the algorithm from | ||
16 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This | ||
17 | file (appnote.txt) is distributed with the PKZIP program (even in the | ||
18 | version without encryption capabilities). | ||
19 | |||
20 | If you don't need crypting in your application, just define symbols | ||
21 | NOCRYPT and NOUNCRYPT. | ||
22 | |||
23 | This code support the "Traditional PKWARE Encryption". | ||
24 | |||
25 | The new AES encryption added on Zip format by Winzip (see the page | ||
26 | http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong | ||
27 | Encryption is not supported. | ||
28 | */ | ||
29 | |||
30 | #include "quazip_global.h" | ||
31 | |||
32 | #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) | ||
33 | |||
34 | /*********************************************************************** | ||
35 | * Return the next byte in the pseudo-random sequence | ||
36 | */ | ||
37 | static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab QUAZIP_UNUSED) | ||
38 | { | ||
39 | //(void) pcrc_32_tab; /* avoid "unused parameter" warning */ | ||
40 | unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an | ||
41 | * unpredictable manner on 16-bit systems; not a problem | ||
42 | * with any known compiler so far, though */ | ||
43 | |||
44 | temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; | ||
45 | return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); | ||
46 | } | ||
47 | |||
48 | /*********************************************************************** | ||
49 | * Update the encryption keys with the next byte of plain text | ||
50 | */ | ||
51 | static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c) | ||
52 | { | ||
53 | (*(pkeys+0)) = CRC32((*(pkeys+0)), c); | ||
54 | (*(pkeys+1)) += (*(pkeys+0)) & 0xff; | ||
55 | (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; | ||
56 | { | ||
57 | register int keyshift = (int)((*(pkeys+1)) >> 24); | ||
58 | (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); | ||
59 | } | ||
60 | return c; | ||
61 | } | ||
62 | |||
63 | |||
64 | /*********************************************************************** | ||
65 | * Initialize the encryption keys and the random header according to | ||
66 | * the given password. | ||
67 | */ | ||
68 | static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab) | ||
69 | { | ||
70 | *(pkeys+0) = 305419896L; | ||
71 | *(pkeys+1) = 591751049L; | ||
72 | *(pkeys+2) = 878082192L; | ||
73 | while (*passwd != '\0') { | ||
74 | update_keys(pkeys,pcrc_32_tab,(int)*passwd); | ||
75 | passwd++; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | #define zdecode(pkeys,pcrc_32_tab,c) \ | ||
80 | (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) | ||
81 | |||
82 | #define zencode(pkeys,pcrc_32_tab,c,t) \ | ||
83 | (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) | ||
84 | |||
85 | #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED | ||
86 | |||
87 | #define RAND_HEAD_LEN 12 | ||
88 | /* "last resort" source for second part of crypt seed pattern */ | ||
89 | # ifndef ZCR_SEED2 | ||
90 | # define ZCR_SEED2 3141592654UL /* use PI as default pattern */ | ||
91 | # endif | ||
92 | |||
93 | static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) | ||
94 | const char *passwd; /* password string */ | ||
95 | unsigned char *buf; /* where to write header */ | ||
96 | int bufSize; | ||
97 | unsigned long* pkeys; | ||
98 | const z_crc_t FAR * pcrc_32_tab; | ||
99 | unsigned long crcForCrypting; | ||
100 | { | ||
101 | int n; /* index in random header */ | ||
102 | int t; /* temporary */ | ||
103 | int c; /* random byte */ | ||
104 | unsigned char header[RAND_HEAD_LEN-2]; /* random header */ | ||
105 | static unsigned calls = 0; /* ensure different random header each time */ | ||
106 | |||
107 | if (bufSize<RAND_HEAD_LEN) | ||
108 | return 0; | ||
109 | |||
110 | /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the | ||
111 | * output of rand() to get less predictability, since rand() is | ||
112 | * often poorly implemented. | ||
113 | */ | ||
114 | if (++calls == 1) | ||
115 | { | ||
116 | srand((unsigned)(time(NULL) ^ ZCR_SEED2)); | ||
117 | } | ||
118 | init_keys(passwd, pkeys, pcrc_32_tab); | ||
119 | for (n = 0; n < RAND_HEAD_LEN-2; n++) | ||
120 | { | ||
121 | c = (rand() >> 7) & 0xff; | ||
122 | header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); | ||
123 | } | ||
124 | /* Encrypt random header (last two bytes is high word of crc) */ | ||
125 | init_keys(passwd, pkeys, pcrc_32_tab); | ||
126 | for (n = 0; n < RAND_HEAD_LEN-2; n++) | ||
127 | { | ||
128 | buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); | ||
129 | } | ||
130 | buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); | ||
131 | buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); | ||
132 | return n; | ||
133 | } | ||
134 | |||
135 | #endif | ||
diff --git a/utils/rbutilqt/quazip/qioapi.cpp b/utils/rbutilqt/quazip/qioapi.cpp new file mode 100644 index 0000000000..3932ebeef0 --- /dev/null +++ b/utils/rbutilqt/quazip/qioapi.cpp | |||
@@ -0,0 +1,363 @@ | |||
1 | /* ioapi.c -- IO base function header for compress/uncompress .zip | ||
2 | files using zlib + zip or unzip API | ||
3 | |||
4 | Version 1.01e, February 12th, 2005 | ||
5 | |||
6 | Copyright (C) 1998-2005 Gilles Vollant | ||
7 | |||
8 | Modified by Sergey A. Tachenov to integrate with Qt. | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <string.h> | ||
14 | #include <zlib.h> | ||
15 | |||
16 | #include "ioapi.h" | ||
17 | #include "quazip_global.h" | ||
18 | #include <QtCore/QIODevice> | ||
19 | #if (QT_VERSION >= 0x050100) | ||
20 | #define QUAZIP_QSAVEFILE_BUG_WORKAROUND | ||
21 | #endif | ||
22 | #ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND | ||
23 | #include <QtCore/QSaveFile> | ||
24 | #endif | ||
25 | |||
26 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ | ||
27 | |||
28 | #ifndef SEEK_CUR | ||
29 | #define SEEK_CUR 1 | ||
30 | #endif | ||
31 | |||
32 | #ifndef SEEK_END | ||
33 | #define SEEK_END 2 | ||
34 | #endif | ||
35 | |||
36 | #ifndef SEEK_SET | ||
37 | #define SEEK_SET 0 | ||
38 | #endif | ||
39 | |||
40 | voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode) | ||
41 | { | ||
42 | if (pfilefunc->zfile_func64.zopen64_file != NULL) | ||
43 | return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,file,mode); | ||
44 | else | ||
45 | { | ||
46 | return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,file,mode); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | int call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) | ||
51 | { | ||
52 | if (pfilefunc->zfile_func64.zseek64_file != NULL) | ||
53 | return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); | ||
54 | else | ||
55 | { | ||
56 | uLong offsetTruncated = (uLong)offset; | ||
57 | if (offsetTruncated != offset) | ||
58 | return -1; | ||
59 | else | ||
60 | return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) | ||
65 | { | ||
66 | if (pfilefunc->zfile_func64.zseek64_file != NULL) | ||
67 | return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); | ||
68 | else | ||
69 | { | ||
70 | uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); | ||
71 | if ((tell_uLong) == ((uLong)-1)) | ||
72 | return (ZPOS64_T)-1; | ||
73 | else | ||
74 | return tell_uLong; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | /// @cond internal | ||
79 | struct QIODevice_descriptor { | ||
80 | // Position only used for writing to sequential devices. | ||
81 | qint64 pos; | ||
82 | inline QIODevice_descriptor(): | ||
83 | pos(0) | ||
84 | {} | ||
85 | }; | ||
86 | /// @endcond | ||
87 | |||
88 | voidpf ZCALLBACK qiodevice_open_file_func ( | ||
89 | voidpf opaque, | ||
90 | voidpf file, | ||
91 | int mode) | ||
92 | { | ||
93 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
94 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(file); | ||
95 | QIODevice::OpenMode desiredMode; | ||
96 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) | ||
97 | desiredMode = QIODevice::ReadOnly; | ||
98 | else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) | ||
99 | desiredMode = QIODevice::ReadWrite; | ||
100 | else if (mode & ZLIB_FILEFUNC_MODE_CREATE) | ||
101 | desiredMode = QIODevice::WriteOnly; | ||
102 | if (iodevice->isOpen()) { | ||
103 | if ((iodevice->openMode() & desiredMode) == desiredMode) { | ||
104 | if (desiredMode != QIODevice::WriteOnly | ||
105 | && iodevice->isSequential()) { | ||
106 | // We can use sequential devices only for writing. | ||
107 | delete d; | ||
108 | return NULL; | ||
109 | } else { | ||
110 | if ((desiredMode & QIODevice::WriteOnly) != 0) { | ||
111 | // open for writing, need to seek existing device | ||
112 | if (!iodevice->isSequential()) { | ||
113 | iodevice->seek(0); | ||
114 | } else { | ||
115 | d->pos = iodevice->pos(); | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | return iodevice; | ||
120 | } else { | ||
121 | delete d; | ||
122 | return NULL; | ||
123 | } | ||
124 | } | ||
125 | iodevice->open(desiredMode); | ||
126 | if (iodevice->isOpen()) { | ||
127 | if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) { | ||
128 | // We can use sequential devices only for writing. | ||
129 | iodevice->close(); | ||
130 | delete d; | ||
131 | return NULL; | ||
132 | } else { | ||
133 | return iodevice; | ||
134 | } | ||
135 | } else { | ||
136 | delete d; | ||
137 | return NULL; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | |||
142 | uLong ZCALLBACK qiodevice_read_file_func ( | ||
143 | voidpf opaque, | ||
144 | voidpf stream, | ||
145 | void* buf, | ||
146 | uLong size) | ||
147 | { | ||
148 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
149 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream); | ||
150 | qint64 ret64 = iodevice->read((char*)buf,size); | ||
151 | uLong ret; | ||
152 | ret = (uLong) ret64; | ||
153 | if (ret64 != -1) { | ||
154 | d->pos += ret64; | ||
155 | } | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | |||
160 | uLong ZCALLBACK qiodevice_write_file_func ( | ||
161 | voidpf opaque, | ||
162 | voidpf stream, | ||
163 | const void* buf, | ||
164 | uLong size) | ||
165 | { | ||
166 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
167 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream); | ||
168 | uLong ret; | ||
169 | qint64 ret64 = iodevice->write((char*)buf,size); | ||
170 | if (ret64 != -1) { | ||
171 | d->pos += ret64; | ||
172 | } | ||
173 | ret = (uLong) ret64; | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | uLong ZCALLBACK qiodevice_tell_file_func ( | ||
178 | voidpf opaque, | ||
179 | voidpf stream) | ||
180 | { | ||
181 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
182 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream); | ||
183 | uLong ret; | ||
184 | qint64 ret64; | ||
185 | if (iodevice->isSequential()) { | ||
186 | ret64 = d->pos; | ||
187 | } else { | ||
188 | ret64 = iodevice->pos(); | ||
189 | } | ||
190 | ret = static_cast<uLong>(ret64); | ||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | ZPOS64_T ZCALLBACK qiodevice64_tell_file_func ( | ||
195 | voidpf opaque, | ||
196 | voidpf stream) | ||
197 | { | ||
198 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
199 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream); | ||
200 | qint64 ret; | ||
201 | if (iodevice->isSequential()) { | ||
202 | ret = d->pos; | ||
203 | } else { | ||
204 | ret = iodevice->pos(); | ||
205 | } | ||
206 | return static_cast<ZPOS64_T>(ret); | ||
207 | } | ||
208 | |||
209 | int ZCALLBACK qiodevice_seek_file_func ( | ||
210 | voidpf /*opaque UNUSED*/, | ||
211 | voidpf stream, | ||
212 | uLong offset, | ||
213 | int origin) | ||
214 | { | ||
215 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream); | ||
216 | if (iodevice->isSequential()) { | ||
217 | if (origin == ZLIB_FILEFUNC_SEEK_END | ||
218 | && offset == 0) { | ||
219 | // sequential devices are always at end (needed in mdAppend) | ||
220 | return 0; | ||
221 | } else { | ||
222 | qWarning("qiodevice_seek_file_func() called for sequential device"); | ||
223 | return -1; | ||
224 | } | ||
225 | } | ||
226 | uLong qiodevice_seek_result=0; | ||
227 | int ret; | ||
228 | switch (origin) | ||
229 | { | ||
230 | case ZLIB_FILEFUNC_SEEK_CUR : | ||
231 | qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset; | ||
232 | break; | ||
233 | case ZLIB_FILEFUNC_SEEK_END : | ||
234 | qiodevice_seek_result = ((QIODevice*)stream)->size() - offset; | ||
235 | break; | ||
236 | case ZLIB_FILEFUNC_SEEK_SET : | ||
237 | qiodevice_seek_result = offset; | ||
238 | break; | ||
239 | default: | ||
240 | return -1; | ||
241 | } | ||
242 | ret = !iodevice->seek(qiodevice_seek_result); | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | int ZCALLBACK qiodevice64_seek_file_func ( | ||
247 | voidpf /*opaque UNUSED*/, | ||
248 | voidpf stream, | ||
249 | ZPOS64_T offset, | ||
250 | int origin) | ||
251 | { | ||
252 | QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream); | ||
253 | if (iodevice->isSequential()) { | ||
254 | if (origin == ZLIB_FILEFUNC_SEEK_END | ||
255 | && offset == 0) { | ||
256 | // sequential devices are always at end (needed in mdAppend) | ||
257 | return 0; | ||
258 | } else { | ||
259 | qWarning("qiodevice_seek_file_func() called for sequential device"); | ||
260 | return -1; | ||
261 | } | ||
262 | } | ||
263 | qint64 qiodevice_seek_result=0; | ||
264 | int ret; | ||
265 | switch (origin) | ||
266 | { | ||
267 | case ZLIB_FILEFUNC_SEEK_CUR : | ||
268 | qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset; | ||
269 | break; | ||
270 | case ZLIB_FILEFUNC_SEEK_END : | ||
271 | qiodevice_seek_result = ((QIODevice*)stream)->size() - offset; | ||
272 | break; | ||
273 | case ZLIB_FILEFUNC_SEEK_SET : | ||
274 | qiodevice_seek_result = offset; | ||
275 | break; | ||
276 | default: | ||
277 | return -1; | ||
278 | } | ||
279 | ret = !iodevice->seek(qiodevice_seek_result); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | int ZCALLBACK qiodevice_close_file_func ( | ||
284 | voidpf opaque, | ||
285 | voidpf stream) | ||
286 | { | ||
287 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
288 | delete d; | ||
289 | QIODevice *device = reinterpret_cast<QIODevice*>(stream); | ||
290 | #ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND | ||
291 | // QSaveFile terribly breaks the is-a idiom: | ||
292 | // it IS a QIODevice, but it is NOT compatible with it: close() is private | ||
293 | QSaveFile *file = qobject_cast<QSaveFile*>(device); | ||
294 | if (file != NULL) { | ||
295 | // We have to call the ugly commit() instead: | ||
296 | return file->commit() ? 0 : -1; | ||
297 | } | ||
298 | #endif | ||
299 | device->close(); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | int ZCALLBACK qiodevice_fakeclose_file_func ( | ||
304 | voidpf opaque, | ||
305 | voidpf /*stream*/) | ||
306 | { | ||
307 | QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque); | ||
308 | delete d; | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | int ZCALLBACK qiodevice_error_file_func ( | ||
313 | voidpf /*opaque UNUSED*/, | ||
314 | voidpf /*stream UNUSED*/) | ||
315 | { | ||
316 | // can't check for error due to the QIODevice API limitation | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | void fill_qiodevice_filefunc ( | ||
321 | zlib_filefunc_def* pzlib_filefunc_def) | ||
322 | { | ||
323 | pzlib_filefunc_def->zopen_file = qiodevice_open_file_func; | ||
324 | pzlib_filefunc_def->zread_file = qiodevice_read_file_func; | ||
325 | pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func; | ||
326 | pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func; | ||
327 | pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func; | ||
328 | pzlib_filefunc_def->zclose_file = qiodevice_close_file_func; | ||
329 | pzlib_filefunc_def->zerror_file = qiodevice_error_file_func; | ||
330 | pzlib_filefunc_def->opaque = new QIODevice_descriptor; | ||
331 | } | ||
332 | |||
333 | void fill_qiodevice64_filefunc ( | ||
334 | zlib_filefunc64_def* pzlib_filefunc_def) | ||
335 | { | ||
336 | // Open functions are the same for Qt. | ||
337 | pzlib_filefunc_def->zopen64_file = qiodevice_open_file_func; | ||
338 | pzlib_filefunc_def->zread_file = qiodevice_read_file_func; | ||
339 | pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func; | ||
340 | pzlib_filefunc_def->ztell64_file = qiodevice64_tell_file_func; | ||
341 | pzlib_filefunc_def->zseek64_file = qiodevice64_seek_file_func; | ||
342 | pzlib_filefunc_def->zclose_file = qiodevice_close_file_func; | ||
343 | pzlib_filefunc_def->zerror_file = qiodevice_error_file_func; | ||
344 | pzlib_filefunc_def->opaque = new QIODevice_descriptor; | ||
345 | pzlib_filefunc_def->zfakeclose_file = qiodevice_fakeclose_file_func; | ||
346 | } | ||
347 | |||
348 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) | ||
349 | { | ||
350 | p_filefunc64_32->zfile_func64.zopen64_file = NULL; | ||
351 | p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; | ||
352 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; | ||
353 | p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; | ||
354 | p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; | ||
355 | p_filefunc64_32->zfile_func64.ztell64_file = NULL; | ||
356 | p_filefunc64_32->zfile_func64.zseek64_file = NULL; | ||
357 | p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; | ||
358 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; | ||
359 | p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; | ||
360 | p_filefunc64_32->zfile_func64.zfakeclose_file = NULL; | ||
361 | p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; | ||
362 | p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; | ||
363 | } | ||
diff --git a/utils/rbutilqt/quazip/quazip.cpp b/utils/rbutilqt/quazip/quazip.cpp new file mode 100644 index 0000000000..61c2ea87eb --- /dev/null +++ b/utils/rbutilqt/quazip/quazip.cpp | |||
@@ -0,0 +1,846 @@ | |||
1 | /* | ||
2 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
3 | |||
4 | This file is part of QuaZIP. | ||
5 | |||
6 | QuaZIP is free software: you can redistribute it and/or modify | ||
7 | it under the terms of the GNU Lesser General Public License as published by | ||
8 | the Free Software Foundation, either version 2.1 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | QuaZIP is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU Lesser General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Lesser General Public License | ||
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
18 | |||
19 | See COPYING file for the full LGPL text. | ||
20 | |||
21 | Original ZIP package is copyrighted by Gilles Vollant, see | ||
22 | quazip/(un)zip.h files for details, basically it's zlib license. | ||
23 | **/ | ||
24 | |||
25 | #include <QtCore/QFile> | ||
26 | #include <QtCore/QFlags> | ||
27 | #include <QtCore/QHash> | ||
28 | |||
29 | #include "quazip.h" | ||
30 | |||
31 | #define QUAZIP_OS_UNIX 3u | ||
32 | |||
33 | /// All the internal stuff for the QuaZip class. | ||
34 | /** | ||
35 | \internal | ||
36 | |||
37 | This class keeps all the private stuff for the QuaZip class so it can | ||
38 | be changed without breaking binary compatibility, according to the | ||
39 | Pimpl idiom. | ||
40 | */ | ||
41 | class QuaZipPrivate { | ||
42 | friend class QuaZip; | ||
43 | private: | ||
44 | Q_DISABLE_COPY(QuaZipPrivate) | ||
45 | /// The pointer to the corresponding QuaZip instance. | ||
46 | QuaZip *q; | ||
47 | /// The codec for file names (used when UTF-8 is not enabled). | ||
48 | QTextCodec *fileNameCodec; | ||
49 | /// The codec for comments (used when UTF-8 is not enabled). | ||
50 | QTextCodec *commentCodec; | ||
51 | /// The archive file name. | ||
52 | QString zipName; | ||
53 | /// The device to access the archive. | ||
54 | QIODevice *ioDevice; | ||
55 | /// The global comment. | ||
56 | QString comment; | ||
57 | /// The open mode. | ||
58 | QuaZip::Mode mode; | ||
59 | union { | ||
60 | /// The internal handle for UNZIP modes. | ||
61 | unzFile unzFile_f; | ||
62 | /// The internal handle for ZIP modes. | ||
63 | zipFile zipFile_f; | ||
64 | }; | ||
65 | /// Whether a current file is set. | ||
66 | bool hasCurrentFile_f; | ||
67 | /// The last error. | ||
68 | int zipError; | ||
69 | /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled. | ||
70 | bool dataDescriptorWritingEnabled; | ||
71 | /// The zip64 mode. | ||
72 | bool zip64; | ||
73 | /// The auto-close flag. | ||
74 | bool autoClose; | ||
75 | /// The UTF-8 flag. | ||
76 | bool utf8; | ||
77 | /// The OS code. | ||
78 | uint osCode; | ||
79 | inline QTextCodec *getDefaultFileNameCodec() | ||
80 | { | ||
81 | if (defaultFileNameCodec == NULL) { | ||
82 | return QTextCodec::codecForLocale(); | ||
83 | } else { | ||
84 | return defaultFileNameCodec; | ||
85 | } | ||
86 | } | ||
87 | /// The constructor for the corresponding QuaZip constructor. | ||
88 | inline QuaZipPrivate(QuaZip *q): | ||
89 | q(q), | ||
90 | fileNameCodec(getDefaultFileNameCodec()), | ||
91 | commentCodec(QTextCodec::codecForLocale()), | ||
92 | ioDevice(NULL), | ||
93 | mode(QuaZip::mdNotOpen), | ||
94 | hasCurrentFile_f(false), | ||
95 | zipError(UNZ_OK), | ||
96 | dataDescriptorWritingEnabled(true), | ||
97 | zip64(false), | ||
98 | autoClose(true), | ||
99 | utf8(false), | ||
100 | osCode(defaultOsCode) | ||
101 | { | ||
102 | unzFile_f = NULL; | ||
103 | zipFile_f = NULL; | ||
104 | lastMappedDirectoryEntry.num_of_file = 0; | ||
105 | lastMappedDirectoryEntry.pos_in_zip_directory = 0; | ||
106 | } | ||
107 | /// The constructor for the corresponding QuaZip constructor. | ||
108 | inline QuaZipPrivate(QuaZip *q, const QString &zipName): | ||
109 | q(q), | ||
110 | fileNameCodec(getDefaultFileNameCodec()), | ||
111 | commentCodec(QTextCodec::codecForLocale()), | ||
112 | zipName(zipName), | ||
113 | ioDevice(NULL), | ||
114 | mode(QuaZip::mdNotOpen), | ||
115 | hasCurrentFile_f(false), | ||
116 | zipError(UNZ_OK), | ||
117 | dataDescriptorWritingEnabled(true), | ||
118 | zip64(false), | ||
119 | autoClose(true), | ||
120 | utf8(false), | ||
121 | osCode(defaultOsCode) | ||
122 | { | ||
123 | unzFile_f = NULL; | ||
124 | zipFile_f = NULL; | ||
125 | lastMappedDirectoryEntry.num_of_file = 0; | ||
126 | lastMappedDirectoryEntry.pos_in_zip_directory = 0; | ||
127 | } | ||
128 | /// The constructor for the corresponding QuaZip constructor. | ||
129 | inline QuaZipPrivate(QuaZip *q, QIODevice *ioDevice): | ||
130 | q(q), | ||
131 | fileNameCodec(getDefaultFileNameCodec()), | ||
132 | commentCodec(QTextCodec::codecForLocale()), | ||
133 | ioDevice(ioDevice), | ||
134 | mode(QuaZip::mdNotOpen), | ||
135 | hasCurrentFile_f(false), | ||
136 | zipError(UNZ_OK), | ||
137 | dataDescriptorWritingEnabled(true), | ||
138 | zip64(false), | ||
139 | autoClose(true), | ||
140 | utf8(false), | ||
141 | osCode(defaultOsCode) | ||
142 | { | ||
143 | unzFile_f = NULL; | ||
144 | zipFile_f = NULL; | ||
145 | lastMappedDirectoryEntry.num_of_file = 0; | ||
146 | lastMappedDirectoryEntry.pos_in_zip_directory = 0; | ||
147 | } | ||
148 | /// Returns either a list of file names or a list of QuaZipFileInfo. | ||
149 | template<typename TFileInfo> | ||
150 | bool getFileInfoList(QList<TFileInfo> *result) const; | ||
151 | |||
152 | /// Stores map of filenames and file locations for unzipping | ||
153 | inline void clearDirectoryMap(); | ||
154 | inline void addCurrentFileToDirectoryMap(const QString &fileName); | ||
155 | bool goToFirstUnmappedFile(); | ||
156 | QHash<QString, unz64_file_pos> directoryCaseSensitive; | ||
157 | QHash<QString, unz64_file_pos> directoryCaseInsensitive; | ||
158 | unz64_file_pos lastMappedDirectoryEntry; | ||
159 | static QTextCodec *defaultFileNameCodec; | ||
160 | static uint defaultOsCode; | ||
161 | }; | ||
162 | |||
163 | QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL; | ||
164 | uint QuaZipPrivate::defaultOsCode = QUAZIP_OS_UNIX; | ||
165 | |||
166 | void QuaZipPrivate::clearDirectoryMap() | ||
167 | { | ||
168 | directoryCaseInsensitive.clear(); | ||
169 | directoryCaseSensitive.clear(); | ||
170 | lastMappedDirectoryEntry.num_of_file = 0; | ||
171 | lastMappedDirectoryEntry.pos_in_zip_directory = 0; | ||
172 | } | ||
173 | |||
174 | void QuaZipPrivate::addCurrentFileToDirectoryMap(const QString &fileName) | ||
175 | { | ||
176 | if (!hasCurrentFile_f || fileName.isEmpty()) { | ||
177 | return; | ||
178 | } | ||
179 | // Adds current file to filename map as fileName | ||
180 | unz64_file_pos fileDirectoryPos; | ||
181 | unzGetFilePos64(unzFile_f, &fileDirectoryPos); | ||
182 | directoryCaseSensitive.insert(fileName, fileDirectoryPos); | ||
183 | // Only add lowercase to directory map if not already there | ||
184 | // ensures only map the first one seen | ||
185 | QString lower = fileName.toLower(); | ||
186 | if (!directoryCaseInsensitive.contains(lower)) | ||
187 | directoryCaseInsensitive.insert(lower, fileDirectoryPos); | ||
188 | // Mark last one | ||
189 | if (fileDirectoryPos.pos_in_zip_directory > lastMappedDirectoryEntry.pos_in_zip_directory) | ||
190 | lastMappedDirectoryEntry = fileDirectoryPos; | ||
191 | } | ||
192 | |||
193 | bool QuaZipPrivate::goToFirstUnmappedFile() | ||
194 | { | ||
195 | zipError = UNZ_OK; | ||
196 | if (mode != QuaZip::mdUnzip) { | ||
197 | qWarning("QuaZipPrivate::goToNextUnmappedFile(): ZIP is not open in mdUnzip mode"); | ||
198 | return false; | ||
199 | } | ||
200 | // If not mapped anything, go to beginning | ||
201 | if (lastMappedDirectoryEntry.pos_in_zip_directory == 0) { | ||
202 | unzGoToFirstFile(unzFile_f); | ||
203 | } else { | ||
204 | // Goto the last one mapped, plus one | ||
205 | unzGoToFilePos64(unzFile_f, &lastMappedDirectoryEntry); | ||
206 | unzGoToNextFile(unzFile_f); | ||
207 | } | ||
208 | hasCurrentFile_f=zipError==UNZ_OK; | ||
209 | if(zipError==UNZ_END_OF_LIST_OF_FILE) | ||
210 | zipError=UNZ_OK; | ||
211 | return hasCurrentFile_f; | ||
212 | } | ||
213 | |||
214 | QuaZip::QuaZip(): | ||
215 | p(new QuaZipPrivate(this)) | ||
216 | { | ||
217 | } | ||
218 | |||
219 | QuaZip::QuaZip(const QString& zipName): | ||
220 | p(new QuaZipPrivate(this, zipName)) | ||
221 | { | ||
222 | } | ||
223 | |||
224 | QuaZip::QuaZip(QIODevice *ioDevice): | ||
225 | p(new QuaZipPrivate(this, ioDevice)) | ||
226 | { | ||
227 | } | ||
228 | |||
229 | QuaZip::~QuaZip() | ||
230 | { | ||
231 | if(isOpen()) | ||
232 | close(); | ||
233 | delete p; | ||
234 | } | ||
235 | |||
236 | bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi) | ||
237 | { | ||
238 | p->zipError=UNZ_OK; | ||
239 | if(isOpen()) { | ||
240 | qWarning("QuaZip::open(): ZIP already opened"); | ||
241 | return false; | ||
242 | } | ||
243 | QIODevice *ioDevice = p->ioDevice; | ||
244 | if (ioDevice == NULL) { | ||
245 | if (p->zipName.isEmpty()) { | ||
246 | qWarning("QuaZip::open(): set either ZIP file name or IO device first"); | ||
247 | return false; | ||
248 | } else { | ||
249 | ioDevice = new QFile(p->zipName); | ||
250 | } | ||
251 | } | ||
252 | unsigned flags = 0; | ||
253 | switch(mode) { | ||
254 | case mdUnzip: | ||
255 | if (ioApi == NULL) { | ||
256 | if (p->autoClose) | ||
257 | flags |= UNZ_AUTO_CLOSE; | ||
258 | p->unzFile_f=unzOpenInternal(ioDevice, NULL, 1, flags); | ||
259 | } else { | ||
260 | // QuaZIP pre-zip64 compatibility mode | ||
261 | p->unzFile_f=unzOpen2(ioDevice, ioApi); | ||
262 | if (p->unzFile_f != NULL) { | ||
263 | if (p->autoClose) { | ||
264 | unzSetFlags(p->unzFile_f, UNZ_AUTO_CLOSE); | ||
265 | } else { | ||
266 | unzClearFlags(p->unzFile_f, UNZ_AUTO_CLOSE); | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | if(p->unzFile_f!=NULL) { | ||
271 | if (ioDevice->isSequential()) { | ||
272 | unzClose(p->unzFile_f); | ||
273 | if (!p->zipName.isEmpty()) | ||
274 | delete ioDevice; | ||
275 | qWarning("QuaZip::open(): " | ||
276 | "only mdCreate can be used with " | ||
277 | "sequential devices"); | ||
278 | return false; | ||
279 | } | ||
280 | p->mode=mode; | ||
281 | p->ioDevice = ioDevice; | ||
282 | return true; | ||
283 | } else { | ||
284 | p->zipError=UNZ_OPENERROR; | ||
285 | if (!p->zipName.isEmpty()) | ||
286 | delete ioDevice; | ||
287 | return false; | ||
288 | } | ||
289 | case mdCreate: | ||
290 | case mdAppend: | ||
291 | case mdAdd: | ||
292 | if (ioApi == NULL) { | ||
293 | if (p->autoClose) | ||
294 | flags |= ZIP_AUTO_CLOSE; | ||
295 | if (p->dataDescriptorWritingEnabled) | ||
296 | flags |= ZIP_WRITE_DATA_DESCRIPTOR; | ||
297 | if (p->utf8) | ||
298 | flags |= ZIP_ENCODING_UTF8; | ||
299 | p->zipFile_f=zipOpen3(ioDevice, | ||
300 | mode==mdCreate?APPEND_STATUS_CREATE: | ||
301 | mode==mdAppend?APPEND_STATUS_CREATEAFTER: | ||
302 | APPEND_STATUS_ADDINZIP, | ||
303 | NULL, NULL, flags); | ||
304 | } else { | ||
305 | // QuaZIP pre-zip64 compatibility mode | ||
306 | p->zipFile_f=zipOpen2(ioDevice, | ||
307 | mode==mdCreate?APPEND_STATUS_CREATE: | ||
308 | mode==mdAppend?APPEND_STATUS_CREATEAFTER: | ||
309 | APPEND_STATUS_ADDINZIP, | ||
310 | NULL, | ||
311 | ioApi); | ||
312 | if (p->zipFile_f != NULL) { | ||
313 | zipSetFlags(p->zipFile_f, flags); | ||
314 | } | ||
315 | } | ||
316 | if(p->zipFile_f!=NULL) { | ||
317 | if (ioDevice->isSequential()) { | ||
318 | if (mode != mdCreate) { | ||
319 | zipClose(p->zipFile_f, NULL); | ||
320 | qWarning("QuaZip::open(): " | ||
321 | "only mdCreate can be used with " | ||
322 | "sequential devices"); | ||
323 | if (!p->zipName.isEmpty()) | ||
324 | delete ioDevice; | ||
325 | return false; | ||
326 | } | ||
327 | zipSetFlags(p->zipFile_f, ZIP_SEQUENTIAL); | ||
328 | } | ||
329 | p->mode=mode; | ||
330 | p->ioDevice = ioDevice; | ||
331 | return true; | ||
332 | } else { | ||
333 | p->zipError=UNZ_OPENERROR; | ||
334 | if (!p->zipName.isEmpty()) | ||
335 | delete ioDevice; | ||
336 | return false; | ||
337 | } | ||
338 | default: | ||
339 | qWarning("QuaZip::open(): unknown mode: %d", (int)mode); | ||
340 | if (!p->zipName.isEmpty()) | ||
341 | delete ioDevice; | ||
342 | return false; | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | void QuaZip::close() | ||
348 | { | ||
349 | p->zipError=UNZ_OK; | ||
350 | switch(p->mode) { | ||
351 | case mdNotOpen: | ||
352 | qWarning("QuaZip::close(): ZIP is not open"); | ||
353 | return; | ||
354 | case mdUnzip: | ||
355 | p->zipError=unzClose(p->unzFile_f); | ||
356 | break; | ||
357 | case mdCreate: | ||
358 | case mdAppend: | ||
359 | case mdAdd: | ||
360 | p->zipError=zipClose(p->zipFile_f, p->comment.isNull() ? NULL : isUtf8Enabled() | ||
361 | ? p->comment.toUtf8().constData() | ||
362 | : p->commentCodec->fromUnicode(p->comment).constData()); | ||
363 | break; | ||
364 | default: | ||
365 | qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode); | ||
366 | return; | ||
367 | } | ||
368 | // opened by name, need to delete the internal IO device | ||
369 | if (!p->zipName.isEmpty()) { | ||
370 | delete p->ioDevice; | ||
371 | p->ioDevice = NULL; | ||
372 | } | ||
373 | p->clearDirectoryMap(); | ||
374 | if(p->zipError==UNZ_OK) | ||
375 | p->mode=mdNotOpen; | ||
376 | } | ||
377 | |||
378 | void QuaZip::setZipName(const QString& zipName) | ||
379 | { | ||
380 | if(isOpen()) { | ||
381 | qWarning("QuaZip::setZipName(): ZIP is already open!"); | ||
382 | return; | ||
383 | } | ||
384 | p->zipName=zipName; | ||
385 | p->ioDevice = NULL; | ||
386 | } | ||
387 | |||
388 | void QuaZip::setIoDevice(QIODevice *ioDevice) | ||
389 | { | ||
390 | if(isOpen()) { | ||
391 | qWarning("QuaZip::setIoDevice(): ZIP is already open!"); | ||
392 | return; | ||
393 | } | ||
394 | p->ioDevice = ioDevice; | ||
395 | p->zipName = QString(); | ||
396 | } | ||
397 | |||
398 | int QuaZip::getEntriesCount()const | ||
399 | { | ||
400 | QuaZip *fakeThis=(QuaZip*)this; // non-const | ||
401 | fakeThis->p->zipError=UNZ_OK; | ||
402 | if(p->mode!=mdUnzip) { | ||
403 | qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode"); | ||
404 | return -1; | ||
405 | } | ||
406 | unz_global_info64 globalInfo; | ||
407 | if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK) | ||
408 | return p->zipError; | ||
409 | return (int)globalInfo.number_entry; | ||
410 | } | ||
411 | |||
412 | QString QuaZip::getComment()const | ||
413 | { | ||
414 | QuaZip *fakeThis=(QuaZip*)this; // non-const | ||
415 | fakeThis->p->zipError=UNZ_OK; | ||
416 | if(p->mode!=mdUnzip) { | ||
417 | qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode"); | ||
418 | return QString(); | ||
419 | } | ||
420 | unz_global_info64 globalInfo; | ||
421 | QByteArray comment; | ||
422 | if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK) | ||
423 | return QString(); | ||
424 | comment.resize(globalInfo.size_comment); | ||
425 | if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0) | ||
426 | return QString(); | ||
427 | fakeThis->p->zipError = UNZ_OK; | ||
428 | unsigned flags = 0; | ||
429 | return (unzGetFileFlags(p->unzFile_f, &flags) == UNZ_OK) && (flags & UNZ_ENCODING_UTF8) | ||
430 | ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment); | ||
431 | } | ||
432 | |||
433 | bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs) | ||
434 | { | ||
435 | p->zipError=UNZ_OK; | ||
436 | if(p->mode!=mdUnzip) { | ||
437 | qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode"); | ||
438 | return false; | ||
439 | } | ||
440 | if(fileName.isEmpty()) { | ||
441 | p->hasCurrentFile_f=false; | ||
442 | return true; | ||
443 | } | ||
444 | // Unicode-aware reimplementation of the unzLocateFile function | ||
445 | if(p->unzFile_f==NULL) { | ||
446 | p->zipError=UNZ_PARAMERROR; | ||
447 | return false; | ||
448 | } | ||
449 | if(fileName.length()>MAX_FILE_NAME_LENGTH) { | ||
450 | p->zipError=UNZ_PARAMERROR; | ||
451 | return false; | ||
452 | } | ||
453 | // Find the file by name | ||
454 | bool sens = convertCaseSensitivity(cs) == Qt::CaseSensitive; | ||
455 | QString lower, current; | ||
456 | if(!sens) lower=fileName.toLower(); | ||
457 | p->hasCurrentFile_f=false; | ||
458 | |||
459 | // Check the appropriate Map | ||
460 | unz64_file_pos fileDirPos; | ||
461 | fileDirPos.pos_in_zip_directory = 0; | ||
462 | if (sens) { | ||
463 | if (p->directoryCaseSensitive.contains(fileName)) | ||
464 | fileDirPos = p->directoryCaseSensitive.value(fileName); | ||
465 | } else { | ||
466 | if (p->directoryCaseInsensitive.contains(lower)) | ||
467 | fileDirPos = p->directoryCaseInsensitive.value(lower); | ||
468 | } | ||
469 | |||
470 | if (fileDirPos.pos_in_zip_directory != 0) { | ||
471 | p->zipError = unzGoToFilePos64(p->unzFile_f, &fileDirPos); | ||
472 | p->hasCurrentFile_f = p->zipError == UNZ_OK; | ||
473 | } | ||
474 | |||
475 | if (p->hasCurrentFile_f) | ||
476 | return p->hasCurrentFile_f; | ||
477 | |||
478 | // Not mapped yet, start from where we have got to so far | ||
479 | for(bool more=p->goToFirstUnmappedFile(); more; more=goToNextFile()) { | ||
480 | current=getCurrentFileName(); | ||
481 | if(current.isEmpty()) return false; | ||
482 | if(sens) { | ||
483 | if(current==fileName) break; | ||
484 | } else { | ||
485 | if(current.toLower()==lower) break; | ||
486 | } | ||
487 | } | ||
488 | return p->hasCurrentFile_f; | ||
489 | } | ||
490 | |||
491 | bool QuaZip::goToFirstFile() | ||
492 | { | ||
493 | p->zipError=UNZ_OK; | ||
494 | if(p->mode!=mdUnzip) { | ||
495 | qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); | ||
496 | return false; | ||
497 | } | ||
498 | p->zipError=unzGoToFirstFile(p->unzFile_f); | ||
499 | p->hasCurrentFile_f=p->zipError==UNZ_OK; | ||
500 | return p->hasCurrentFile_f; | ||
501 | } | ||
502 | |||
503 | bool QuaZip::goToNextFile() | ||
504 | { | ||
505 | p->zipError=UNZ_OK; | ||
506 | if(p->mode!=mdUnzip) { | ||
507 | qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); | ||
508 | return false; | ||
509 | } | ||
510 | p->zipError=unzGoToNextFile(p->unzFile_f); | ||
511 | p->hasCurrentFile_f=p->zipError==UNZ_OK; | ||
512 | if(p->zipError==UNZ_END_OF_LIST_OF_FILE) | ||
513 | p->zipError=UNZ_OK; | ||
514 | return p->hasCurrentFile_f; | ||
515 | } | ||
516 | |||
517 | bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const | ||
518 | { | ||
519 | QuaZipFileInfo64 info64; | ||
520 | if (info == NULL) { // Very unlikely because of the overloads | ||
521 | return false; | ||
522 | } | ||
523 | if (getCurrentFileInfo(&info64)) { | ||
524 | info64.toQuaZipFileInfo(*info); | ||
525 | return true; | ||
526 | } else { | ||
527 | return false; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | bool QuaZip::getCurrentFileInfo(QuaZipFileInfo64 *info)const | ||
532 | { | ||
533 | QuaZip *fakeThis=(QuaZip*)this; // non-const | ||
534 | fakeThis->p->zipError=UNZ_OK; | ||
535 | if(p->mode!=mdUnzip) { | ||
536 | qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode"); | ||
537 | return false; | ||
538 | } | ||
539 | unz_file_info64 info_z; | ||
540 | QByteArray fileName; | ||
541 | QByteArray extra; | ||
542 | QByteArray comment; | ||
543 | if(info==NULL) return false; | ||
544 | if(!isOpen()||!hasCurrentFile()) return false; | ||
545 | if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK) | ||
546 | return false; | ||
547 | fileName.resize(info_z.size_filename); | ||
548 | extra.resize(info_z.size_file_extra); | ||
549 | comment.resize(info_z.size_file_comment); | ||
550 | if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL, | ||
551 | fileName.data(), fileName.size(), | ||
552 | extra.data(), extra.size(), | ||
553 | comment.data(), comment.size()))!=UNZ_OK) | ||
554 | return false; | ||
555 | info->versionCreated=info_z.version; | ||
556 | info->versionNeeded=info_z.version_needed; | ||
557 | info->flags=info_z.flag; | ||
558 | info->method=info_z.compression_method; | ||
559 | info->crc=info_z.crc; | ||
560 | info->compressedSize=info_z.compressed_size; | ||
561 | info->uncompressedSize=info_z.uncompressed_size; | ||
562 | info->diskNumberStart=info_z.disk_num_start; | ||
563 | info->internalAttr=info_z.internal_fa; | ||
564 | info->externalAttr=info_z.external_fa; | ||
565 | info->name=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName); | ||
566 | info->comment=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment); | ||
567 | info->extra=extra; | ||
568 | info->dateTime=QDateTime( | ||
569 | QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday), | ||
570 | QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec)); | ||
571 | // Add to directory map | ||
572 | p->addCurrentFileToDirectoryMap(info->name); | ||
573 | return true; | ||
574 | } | ||
575 | |||
576 | QString QuaZip::getCurrentFileName()const | ||
577 | { | ||
578 | QuaZip *fakeThis=(QuaZip*)this; // non-const | ||
579 | fakeThis->p->zipError=UNZ_OK; | ||
580 | if(p->mode!=mdUnzip) { | ||
581 | qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode"); | ||
582 | return QString(); | ||
583 | } | ||
584 | if(!isOpen()||!hasCurrentFile()) return QString(); | ||
585 | QByteArray fileName(MAX_FILE_NAME_LENGTH, 0); | ||
586 | unz_file_info64 file_info; | ||
587 | if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &file_info, fileName.data(), fileName.size(), | ||
588 | NULL, 0, NULL, 0))!=UNZ_OK) | ||
589 | return QString(); | ||
590 | fileName.resize(file_info.size_filename); | ||
591 | QString result = (file_info.flag & UNZ_ENCODING_UTF8) | ||
592 | ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName); | ||
593 | if (result.isEmpty()) | ||
594 | return result; | ||
595 | // Add to directory map | ||
596 | p->addCurrentFileToDirectoryMap(result); | ||
597 | return result; | ||
598 | } | ||
599 | |||
600 | void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec) | ||
601 | { | ||
602 | p->fileNameCodec=fileNameCodec; | ||
603 | } | ||
604 | |||
605 | void QuaZip::setFileNameCodec(const char *fileNameCodecName) | ||
606 | { | ||
607 | p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName); | ||
608 | } | ||
609 | |||
610 | void QuaZip::setOsCode(uint osCode) | ||
611 | { | ||
612 | p->osCode = osCode; | ||
613 | } | ||
614 | |||
615 | uint QuaZip::getOsCode() const | ||
616 | { | ||
617 | return p->osCode; | ||
618 | } | ||
619 | |||
620 | QTextCodec *QuaZip::getFileNameCodec()const | ||
621 | { | ||
622 | return p->fileNameCodec; | ||
623 | } | ||
624 | |||
625 | void QuaZip::setCommentCodec(QTextCodec *commentCodec) | ||
626 | { | ||
627 | p->commentCodec=commentCodec; | ||
628 | } | ||
629 | |||
630 | void QuaZip::setCommentCodec(const char *commentCodecName) | ||
631 | { | ||
632 | p->commentCodec=QTextCodec::codecForName(commentCodecName); | ||
633 | } | ||
634 | |||
635 | QTextCodec *QuaZip::getCommentCodec()const | ||
636 | { | ||
637 | return p->commentCodec; | ||
638 | } | ||
639 | |||
640 | QString QuaZip::getZipName() const | ||
641 | { | ||
642 | return p->zipName; | ||
643 | } | ||
644 | |||
645 | QIODevice *QuaZip::getIoDevice() const | ||
646 | { | ||
647 | if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice | ||
648 | return NULL; | ||
649 | return p->ioDevice; | ||
650 | } | ||
651 | |||
652 | QuaZip::Mode QuaZip::getMode()const | ||
653 | { | ||
654 | return p->mode; | ||
655 | } | ||
656 | |||
657 | bool QuaZip::isOpen()const | ||
658 | { | ||
659 | return p->mode!=mdNotOpen; | ||
660 | } | ||
661 | |||
662 | int QuaZip::getZipError() const | ||
663 | { | ||
664 | return p->zipError; | ||
665 | } | ||
666 | |||
667 | void QuaZip::setComment(const QString& comment) | ||
668 | { | ||
669 | p->comment=comment; | ||
670 | } | ||
671 | |||
672 | bool QuaZip::hasCurrentFile()const | ||
673 | { | ||
674 | return p->hasCurrentFile_f; | ||
675 | } | ||
676 | |||
677 | unzFile QuaZip::getUnzFile() | ||
678 | { | ||
679 | return p->unzFile_f; | ||
680 | } | ||
681 | |||
682 | zipFile QuaZip::getZipFile() | ||
683 | { | ||
684 | return p->zipFile_f; | ||
685 | } | ||
686 | |||
687 | void QuaZip::setDataDescriptorWritingEnabled(bool enabled) | ||
688 | { | ||
689 | p->dataDescriptorWritingEnabled = enabled; | ||
690 | } | ||
691 | |||
692 | bool QuaZip::isDataDescriptorWritingEnabled() const | ||
693 | { | ||
694 | return p->dataDescriptorWritingEnabled; | ||
695 | } | ||
696 | |||
697 | template<typename TFileInfo> | ||
698 | TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok); | ||
699 | |||
700 | template<> | ||
701 | QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok) | ||
702 | { | ||
703 | QuaZipFileInfo info; | ||
704 | *ok = zip->getCurrentFileInfo(&info); | ||
705 | return info; | ||
706 | } | ||
707 | |||
708 | template<> | ||
709 | QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok) | ||
710 | { | ||
711 | QuaZipFileInfo64 info; | ||
712 | *ok = zip->getCurrentFileInfo(&info); | ||
713 | return info; | ||
714 | } | ||
715 | |||
716 | template<> | ||
717 | QString QuaZip_getFileInfo(QuaZip *zip, bool *ok) | ||
718 | { | ||
719 | QString name = zip->getCurrentFileName(); | ||
720 | *ok = !name.isEmpty(); | ||
721 | return name; | ||
722 | } | ||
723 | |||
724 | template<typename TFileInfo> | ||
725 | bool QuaZipPrivate::getFileInfoList(QList<TFileInfo> *result) const | ||
726 | { | ||
727 | QuaZipPrivate *fakeThis=const_cast<QuaZipPrivate*>(this); | ||
728 | fakeThis->zipError=UNZ_OK; | ||
729 | if (mode!=QuaZip::mdUnzip) { | ||
730 | qWarning("QuaZip::getFileNameList/getFileInfoList(): " | ||
731 | "ZIP is not open in mdUnzip mode"); | ||
732 | return false; | ||
733 | } | ||
734 | QString currentFile; | ||
735 | if (q->hasCurrentFile()) { | ||
736 | currentFile = q->getCurrentFileName(); | ||
737 | } | ||
738 | if (q->goToFirstFile()) { | ||
739 | do { | ||
740 | bool ok; | ||
741 | result->append(QuaZip_getFileInfo<TFileInfo>(q, &ok)); | ||
742 | if (!ok) | ||
743 | return false; | ||
744 | } while (q->goToNextFile()); | ||
745 | } | ||
746 | if (zipError != UNZ_OK) | ||
747 | return false; | ||
748 | if (currentFile.isEmpty()) { | ||
749 | if (!q->goToFirstFile()) | ||
750 | return false; | ||
751 | } else { | ||
752 | if (!q->setCurrentFile(currentFile)) | ||
753 | return false; | ||
754 | } | ||
755 | return true; | ||
756 | } | ||
757 | |||
758 | QStringList QuaZip::getFileNameList() const | ||
759 | { | ||
760 | QStringList list; | ||
761 | if (p->getFileInfoList(&list)) | ||
762 | return list; | ||
763 | else | ||
764 | return QStringList(); | ||
765 | } | ||
766 | |||
767 | QList<QuaZipFileInfo> QuaZip::getFileInfoList() const | ||
768 | { | ||
769 | QList<QuaZipFileInfo> list; | ||
770 | if (p->getFileInfoList(&list)) | ||
771 | return list; | ||
772 | else | ||
773 | return QList<QuaZipFileInfo>(); | ||
774 | } | ||
775 | |||
776 | QList<QuaZipFileInfo64> QuaZip::getFileInfoList64() const | ||
777 | { | ||
778 | QList<QuaZipFileInfo64> list; | ||
779 | if (p->getFileInfoList(&list)) | ||
780 | return list; | ||
781 | else | ||
782 | return QList<QuaZipFileInfo64>(); | ||
783 | } | ||
784 | |||
785 | Qt::CaseSensitivity QuaZip::convertCaseSensitivity(QuaZip::CaseSensitivity cs) | ||
786 | { | ||
787 | if (cs == csDefault) { | ||
788 | #ifdef Q_OS_WIN | ||
789 | return Qt::CaseInsensitive; | ||
790 | #else | ||
791 | return Qt::CaseSensitive; | ||
792 | #endif | ||
793 | } else { | ||
794 | return cs == csSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; | ||
795 | } | ||
796 | } | ||
797 | |||
798 | void QuaZip::setDefaultFileNameCodec(QTextCodec *codec) | ||
799 | { | ||
800 | QuaZipPrivate::defaultFileNameCodec = codec; | ||
801 | } | ||
802 | |||
803 | void QuaZip::setDefaultFileNameCodec(const char *codecName) | ||
804 | { | ||
805 | setDefaultFileNameCodec(QTextCodec::codecForName(codecName)); | ||
806 | } | ||
807 | |||
808 | void QuaZip::setDefaultOsCode(uint osCode) | ||
809 | { | ||
810 | QuaZipPrivate::defaultOsCode = osCode; | ||
811 | } | ||
812 | |||
813 | uint QuaZip::getDefaultOsCode() | ||
814 | { | ||
815 | return QuaZipPrivate::defaultOsCode; | ||
816 | } | ||
817 | |||
818 | void QuaZip::setZip64Enabled(bool zip64) | ||
819 | { | ||
820 | p->zip64 = zip64; | ||
821 | } | ||
822 | |||
823 | bool QuaZip::isZip64Enabled() const | ||
824 | { | ||
825 | return p->zip64; | ||
826 | } | ||
827 | |||
828 | void QuaZip::setUtf8Enabled(bool utf8) | ||
829 | { | ||
830 | p->utf8 = utf8; | ||
831 | } | ||
832 | |||
833 | bool QuaZip::isUtf8Enabled() const | ||
834 | { | ||
835 | return p->utf8; | ||
836 | } | ||
837 | |||
838 | bool QuaZip::isAutoClose() const | ||
839 | { | ||
840 | return p->autoClose; | ||
841 | } | ||
842 | |||
843 | void QuaZip::setAutoClose(bool autoClose) const | ||
844 | { | ||
845 | p->autoClose = autoClose; | ||
846 | } | ||
diff --git a/utils/rbutilqt/quazip/quazip.h b/utils/rbutilqt/quazip/quazip.h new file mode 100644 index 0000000000..8ff0756254 --- /dev/null +++ b/utils/rbutilqt/quazip/quazip.h | |||
@@ -0,0 +1,611 @@ | |||
1 | #ifndef QUA_ZIP_H | ||
2 | #define QUA_ZIP_H | ||
3 | |||
4 | /* | ||
5 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
6 | |||
7 | This file is part of QuaZIP. | ||
8 | |||
9 | QuaZIP is free software: you can redistribute it and/or modify | ||
10 | it under the terms of the GNU Lesser General Public License as published by | ||
11 | the Free Software Foundation, either version 2.1 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | QuaZIP is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU Lesser General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU Lesser General Public License | ||
20 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | See COPYING file for the full LGPL text. | ||
23 | |||
24 | Original ZIP package is copyrighted by Gilles Vollant, see | ||
25 | quazip/(un)zip.h files for details, basically it's zlib license. | ||
26 | **/ | ||
27 | |||
28 | #include <QtCore/QString> | ||
29 | #include <QtCore/QStringList> | ||
30 | #include <QTextCodec> | ||
31 | |||
32 | #include "zip.h" | ||
33 | #include "unzip.h" | ||
34 | |||
35 | #include "quazip_global.h" | ||
36 | #include "quazipfileinfo.h" | ||
37 | |||
38 | // just in case it will be defined in the later versions of the ZIP/UNZIP | ||
39 | #ifndef UNZ_OPENERROR | ||
40 | // define additional error code | ||
41 | #define UNZ_OPENERROR -1000 | ||
42 | #endif | ||
43 | |||
44 | class QuaZipPrivate; | ||
45 | |||
46 | /// ZIP archive. | ||
47 | /** \class QuaZip quazip.h <quazip/quazip.h> | ||
48 | * This class implements basic interface to the ZIP archive. It can be | ||
49 | * used to read table contents of the ZIP archive and retreiving | ||
50 | * information about the files inside it. | ||
51 | * | ||
52 | * You can also use this class to open files inside archive by passing | ||
53 | * pointer to the instance of this class to the constructor of the | ||
54 | * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*) | ||
55 | * for the possible pitfalls. | ||
56 | * | ||
57 | * This class is indended to provide interface to the ZIP subpackage of | ||
58 | * the ZIP/UNZIP package as well as to the UNZIP subpackage. But | ||
59 | * currently it supports only UNZIP. | ||
60 | * | ||
61 | * The use of this class is simple - just create instance using | ||
62 | * constructor, then set ZIP archive file name using setFile() function | ||
63 | * (if you did not passed the name to the constructor), then open() and | ||
64 | * then use different functions to work with it! Well, if you are | ||
65 | * paranoid, you may also wish to call close before destructing the | ||
66 | * instance, to check for errors on close. | ||
67 | * | ||
68 | * You may also use getUnzFile() and getZipFile() functions to get the | ||
69 | * ZIP archive handle and use it with ZIP/UNZIP package API directly. | ||
70 | * | ||
71 | * This class supports localized file names inside ZIP archive, but you | ||
72 | * have to set up proper codec with setCodec() function. By default, | ||
73 | * locale codec will be used, which is probably ok for UNIX systems, but | ||
74 | * will almost certainly fail with ZIP archives created in Windows. This | ||
75 | * is because Windows ZIP programs have strange habit of using DOS | ||
76 | * encoding for file names in ZIP archives. For example, ZIP archive | ||
77 | * with cyrillic names created in Windows will have file names in \c | ||
78 | * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one | ||
79 | * function is not much trouble, but for true platform independency it | ||
80 | * would be nice to have some mechanism for file name encoding auto | ||
81 | * detection using locale information. Does anyone know a good way to do | ||
82 | * it? | ||
83 | **/ | ||
84 | class QUAZIP_EXPORT QuaZip { | ||
85 | friend class QuaZipPrivate; | ||
86 | public: | ||
87 | /// Useful constants. | ||
88 | enum Constants { | ||
89 | MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from | ||
90 | \c UNZ_MAXFILENAMEINZIP constant in | ||
91 | unzip.c. */ | ||
92 | }; | ||
93 | /// Open mode of the ZIP file. | ||
94 | enum Mode { | ||
95 | mdNotOpen, ///< ZIP file is not open. This is the initial mode. | ||
96 | mdUnzip, ///< ZIP file is open for reading files inside it. | ||
97 | mdCreate, ///< ZIP file was created with open() call. | ||
98 | mdAppend, /**< ZIP file was opened in append mode. This refers to | ||
99 | * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package | ||
100 | * and means that zip is appended to some existing file | ||
101 | * what is useful when that file contains | ||
102 | * self-extractor code. This is obviously \em not what | ||
103 | * you whant to use to add files to the existing ZIP | ||
104 | * archive. | ||
105 | **/ | ||
106 | mdAdd ///< ZIP file was opened for adding files in the archive. | ||
107 | }; | ||
108 | /// Case sensitivity for the file names. | ||
109 | /** This is what you specify when accessing files in the archive. | ||
110 | * Works perfectly fine with any characters thanks to Qt's great | ||
111 | * unicode support. This is different from ZIP/UNZIP API, where | ||
112 | * only US-ASCII characters was supported. | ||
113 | **/ | ||
114 | enum CaseSensitivity { | ||
115 | csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows. | ||
116 | csSensitive=1, ///< Case sensitive. | ||
117 | csInsensitive=2 ///< Case insensitive. | ||
118 | }; | ||
119 | /// Returns the actual case sensitivity for the specified QuaZIP one. | ||
120 | /** | ||
121 | \param cs The value to convert. | ||
122 | \returns If CaseSensitivity::csDefault, then returns the default | ||
123 | file name case sensitivity for the platform. Otherwise, just | ||
124 | returns the appropriate value from the Qt::CaseSensitivity enum. | ||
125 | */ | ||
126 | static Qt::CaseSensitivity convertCaseSensitivity( | ||
127 | CaseSensitivity cs); | ||
128 | private: | ||
129 | QuaZipPrivate *p; | ||
130 | // not (and will not be) implemented | ||
131 | QuaZip(const QuaZip& that); | ||
132 | // not (and will not be) implemented | ||
133 | QuaZip& operator=(const QuaZip& that); | ||
134 | public: | ||
135 | /// Constructs QuaZip object. | ||
136 | /** Call setName() before opening constructed object. */ | ||
137 | QuaZip(); | ||
138 | /// Constructs QuaZip object associated with ZIP file \a zipName. | ||
139 | QuaZip(const QString& zipName); | ||
140 | /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice. | ||
141 | /** The IO device must be seekable, otherwise an error will occur when opening. */ | ||
142 | QuaZip(QIODevice *ioDevice); | ||
143 | /// Destroys QuaZip object. | ||
144 | /** Calls close() if necessary. */ | ||
145 | ~QuaZip(); | ||
146 | /// Opens ZIP file. | ||
147 | /** | ||
148 | * Argument \a mode specifies open mode of the ZIP archive. See Mode | ||
149 | * for details. Note that there is zipOpen2() function in the | ||
150 | * ZIP/UNZIP API which accepts \a globalcomment argument, but it | ||
151 | * does not use it anywhere, so this open() function does not have this | ||
152 | * argument. See setComment() if you need to set global comment. | ||
153 | * | ||
154 | * If the ZIP file is accessed via explicitly set QIODevice, then | ||
155 | * this device is opened in the necessary mode. If the device was | ||
156 | * already opened by some other means, then QuaZIP checks if the | ||
157 | * open mode is compatible to the mode needed for the requested operation. | ||
158 | * If necessary, seeking is performed to position the device properly. | ||
159 | * | ||
160 | * \return \c true if successful, \c false otherwise. | ||
161 | * | ||
162 | * \note ZIP/UNZIP API open calls do not return error code - they | ||
163 | * just return \c NULL indicating an error. But to make things | ||
164 | * easier, quazip.h header defines additional error code \c | ||
165 | * UNZ_ERROROPEN and getZipError() will return it if the open call | ||
166 | * of the ZIP/UNZIP API returns \c NULL. | ||
167 | * | ||
168 | * Argument \a ioApi specifies IO function set for ZIP/UNZIP | ||
169 | * package to use. See unzip.h, zip.h and ioapi.h for details. Note | ||
170 | * that IO API for QuaZip is different from the original package. | ||
171 | * The file path argument was changed to be of type \c voidpf, and | ||
172 | * QuaZip passes a QIODevice pointer there. This QIODevice is either | ||
173 | * set explicitly via setIoDevice() or the QuaZip(QIODevice*) | ||
174 | * constructor, or it is created internally when opening the archive | ||
175 | * by its file name. The default API (qioapi.cpp) just delegates | ||
176 | * everything to the QIODevice API. Not only this allows to use a | ||
177 | * QIODevice instead of file name, but also has a nice side effect | ||
178 | * of raising the file size limit from 2G to 4G (in non-zip64 archives). | ||
179 | * | ||
180 | * \note If the zip64 support is needed, the ioApi argument \em must be NULL | ||
181 | * because due to the backwards compatibility issues it can be used to | ||
182 | * provide a 32-bit API only. | ||
183 | * | ||
184 | * \note If the \ref QuaZip::setAutoClose() "no-auto-close" feature is used, | ||
185 | * then the \a ioApi argument \em should be NULL because the old API | ||
186 | * doesn't support the 'fake close' operation, causing slight memory leaks | ||
187 | * and other possible troubles (like closing the output device in case | ||
188 | * when an error occurs during opening). | ||
189 | * | ||
190 | * In short: just forget about the \a ioApi argument and you'll be | ||
191 | * fine. | ||
192 | **/ | ||
193 | bool open(Mode mode, zlib_filefunc_def *ioApi =NULL); | ||
194 | /// Closes ZIP file. | ||
195 | /** Call getZipError() to determine if the close was successful. | ||
196 | * | ||
197 | * If the file was opened by name, then the underlying QIODevice is closed | ||
198 | * and deleted. | ||
199 | * | ||
200 | * If the underlying QIODevice was set explicitly using setIoDevice() or | ||
201 | * the appropriate constructor, then it is closed if the auto-close flag | ||
202 | * is set (which it is by default). Call setAutoClose() to clear the | ||
203 | * auto-close flag if this behavior is undesirable. | ||
204 | * | ||
205 | * Since Qt 5.1, the QSaveFile was introduced. It breaks the QIODevice API | ||
206 | * by making close() private and crashing the application if it is called | ||
207 | * from the base class where it is public. It is an excellent example | ||
208 | * of poor design that illustrates why you should never ever break | ||
209 | * an is-a relationship between the base class and a subclass. QuaZIP | ||
210 | * works around this bug by checking if the QIODevice is an instance | ||
211 | * of QSaveFile, using qobject_cast<>, and if it is, calls | ||
212 | * QSaveFile::commit() instead of close(). It is a really ugly hack, | ||
213 | * but at least it makes your programs work instead of crashing. Note that | ||
214 | * if the auto-close flag is cleared, then this is a non-issue, and | ||
215 | * commit() isn't called. | ||
216 | */ | ||
217 | void close(); | ||
218 | /// Sets the codec used to encode/decode file names inside archive. | ||
219 | /** This is necessary to access files in the ZIP archive created | ||
220 | * under Windows with non-latin characters in file names. For | ||
221 | * example, file names with cyrillic letters will be in \c IBM866 | ||
222 | * encoding. | ||
223 | **/ | ||
224 | void setFileNameCodec(QTextCodec *fileNameCodec); | ||
225 | /// Sets the codec used to encode/decode file names inside archive. | ||
226 | /** \overload | ||
227 | * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName)); | ||
228 | **/ | ||
229 | void setFileNameCodec(const char *fileNameCodecName); | ||
230 | /// Sets the OS code (highest 8 bits of the “version made by” field) for new files. | ||
231 | /** There is currently no way to specify this for each file individually, | ||
232 | except by calling this function before opening each file. If this function is not called, | ||
233 | then the default OS code will be used. The default code is set by calling | ||
234 | setDefaultOsCode(). The default value at the moment of QuaZip creation will be used. */ | ||
235 | void setOsCode(uint osCode); | ||
236 | /// Returns the OS code for new files. | ||
237 | uint getOsCode() const; | ||
238 | /// Returns the codec used to encode/decode comments inside archive. | ||
239 | QTextCodec* getFileNameCodec() const; | ||
240 | /// Sets the codec used to encode/decode comments inside archive. | ||
241 | /** This codec defaults to locale codec, which is probably ok. | ||
242 | **/ | ||
243 | void setCommentCodec(QTextCodec *commentCodec); | ||
244 | /// Sets the codec used to encode/decode comments inside archive. | ||
245 | /** \overload | ||
246 | * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName)); | ||
247 | **/ | ||
248 | void setCommentCodec(const char *commentCodecName); | ||
249 | /// Returns the codec used to encode/decode comments inside archive. | ||
250 | QTextCodec* getCommentCodec() const; | ||
251 | /// Returns the name of the ZIP file. | ||
252 | /** Returns null string if no ZIP file name has been set, for | ||
253 | * example when the QuaZip instance is set up to use a QIODevice | ||
254 | * instead. | ||
255 | * \sa setZipName(), setIoDevice(), getIoDevice() | ||
256 | **/ | ||
257 | QString getZipName() const; | ||
258 | /// Sets the name of the ZIP file. | ||
259 | /** Does nothing if the ZIP file is open. | ||
260 | * | ||
261 | * Does not reset error code returned by getZipError(). | ||
262 | * \sa setIoDevice(), getIoDevice(), getZipName() | ||
263 | **/ | ||
264 | void setZipName(const QString& zipName); | ||
265 | /// Returns the device representing this ZIP file. | ||
266 | /** Returns null string if no device has been set explicitly, for | ||
267 | * example when opening a ZIP file by name. | ||
268 | * \sa setIoDevice(), getZipName(), setZipName() | ||
269 | **/ | ||
270 | QIODevice *getIoDevice() const; | ||
271 | /// Sets the device representing the ZIP file. | ||
272 | /** Does nothing if the ZIP file is open. | ||
273 | * | ||
274 | * Does not reset error code returned by getZipError(). | ||
275 | * \sa getIoDevice(), getZipName(), setZipName() | ||
276 | **/ | ||
277 | void setIoDevice(QIODevice *ioDevice); | ||
278 | /// Returns the mode in which ZIP file was opened. | ||
279 | Mode getMode() const; | ||
280 | /// Returns \c true if ZIP file is open, \c false otherwise. | ||
281 | bool isOpen() const; | ||
282 | /// Returns the error code of the last operation. | ||
283 | /** Returns \c UNZ_OK if the last operation was successful. | ||
284 | * | ||
285 | * Error code resets to \c UNZ_OK every time you call any function | ||
286 | * that accesses something inside ZIP archive, even if it is \c | ||
287 | * const (like getEntriesCount()). open() and close() calls reset | ||
288 | * error code too. See documentation for the specific functions for | ||
289 | * details on error detection. | ||
290 | **/ | ||
291 | int getZipError() const; | ||
292 | /// Returns number of the entries in the ZIP central directory. | ||
293 | /** Returns negative error code in the case of error. The same error | ||
294 | * code will be returned by subsequent getZipError() call. | ||
295 | **/ | ||
296 | int getEntriesCount() const; | ||
297 | /// Returns global comment in the ZIP file. | ||
298 | QString getComment() const; | ||
299 | /// Sets the global comment in the ZIP file. | ||
300 | /** The comment will be written to the archive on close operation. | ||
301 | * QuaZip makes a distinction between a null QByteArray() comment | ||
302 | * and an empty "" comment in the QuaZip::mdAdd mode. | ||
303 | * A null comment is the default and it means "don't change | ||
304 | * the comment". An empty comment removes the original comment. | ||
305 | * | ||
306 | * \sa open() | ||
307 | **/ | ||
308 | void setComment(const QString& comment); | ||
309 | /// Sets the current file to the first file in the archive. | ||
310 | /** Returns \c true on success, \c false otherwise. Call | ||
311 | * getZipError() to get the error code. | ||
312 | **/ | ||
313 | bool goToFirstFile(); | ||
314 | /// Sets the current file to the next file in the archive. | ||
315 | /** Returns \c true on success, \c false otherwise. Call | ||
316 | * getZipError() to determine if there was an error. | ||
317 | * | ||
318 | * Should be used only in QuaZip::mdUnzip mode. | ||
319 | * | ||
320 | * \note If the end of file was reached, getZipError() will return | ||
321 | * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make | ||
322 | * things like this easier: | ||
323 | * \code | ||
324 | * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { | ||
325 | * // do something | ||
326 | * } | ||
327 | * if(zip.getZipError()==UNZ_OK) { | ||
328 | * // ok, there was no error | ||
329 | * } | ||
330 | * \endcode | ||
331 | **/ | ||
332 | bool goToNextFile(); | ||
333 | /// Sets current file by its name. | ||
334 | /** Returns \c true if successful, \c false otherwise. Argument \a | ||
335 | * cs specifies case sensitivity of the file name. Call | ||
336 | * getZipError() in the case of a failure to get error code. | ||
337 | * | ||
338 | * This is not a wrapper to unzLocateFile() function. That is | ||
339 | * because I had to implement locale-specific case-insensitive | ||
340 | * comparison. | ||
341 | * | ||
342 | * Here are the differences from the original implementation: | ||
343 | * | ||
344 | * - If the file was not found, error code is \c UNZ_OK, not \c | ||
345 | * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()). | ||
346 | * - If this function fails, it unsets the current file rather than | ||
347 | * resetting it back to what it was before the call. | ||
348 | * | ||
349 | * If \a fileName is null string then this function unsets the | ||
350 | * current file and return \c true. Note that you should close the | ||
351 | * file first if it is open! See | ||
352 | * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details. | ||
353 | * | ||
354 | * Should be used only in QuaZip::mdUnzip mode. | ||
355 | * | ||
356 | * \sa setFileNameCodec(), CaseSensitivity | ||
357 | **/ | ||
358 | bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault); | ||
359 | /// Returns \c true if the current file has been set. | ||
360 | bool hasCurrentFile() const; | ||
361 | /// Retrieves information about the current file. | ||
362 | /** Fills the structure pointed by \a info. Returns \c true on | ||
363 | * success, \c false otherwise. In the latter case structure pointed | ||
364 | * by \a info remains untouched. If there was an error, | ||
365 | * getZipError() returns error code. | ||
366 | * | ||
367 | * Should be used only in QuaZip::mdUnzip mode. | ||
368 | * | ||
369 | * Does nothing and returns \c false in any of the following cases. | ||
370 | * - ZIP is not open; | ||
371 | * - ZIP does not have current file. | ||
372 | * | ||
373 | * In both cases getZipError() returns \c UNZ_OK since there | ||
374 | * is no ZIP/UNZIP API call. | ||
375 | * | ||
376 | * This overload doesn't support zip64, but will work OK on zip64 archives | ||
377 | * except that if one of the sizes (compressed or uncompressed) is greater | ||
378 | * than 0xFFFFFFFFu, it will be set to exactly 0xFFFFFFFFu. | ||
379 | * | ||
380 | * \sa getCurrentFileInfo(QuaZipFileInfo64* info)const | ||
381 | * \sa QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo&)const | ||
382 | **/ | ||
383 | bool getCurrentFileInfo(QuaZipFileInfo* info)const; | ||
384 | /// Retrieves information about the current file. | ||
385 | /** \overload | ||
386 | * | ||
387 | * This function supports zip64. If the archive doesn't use zip64, it is | ||
388 | * completely equivalent to getCurrentFileInfo(QuaZipFileInfo* info) | ||
389 | * except for the argument type. | ||
390 | * | ||
391 | * \sa | ||
392 | **/ | ||
393 | bool getCurrentFileInfo(QuaZipFileInfo64* info)const; | ||
394 | /// Returns the current file name. | ||
395 | /** Equivalent to calling getCurrentFileInfo() and then getting \c | ||
396 | * name field of the QuaZipFileInfo structure, but faster and more | ||
397 | * convenient. | ||
398 | * | ||
399 | * Should be used only in QuaZip::mdUnzip mode. | ||
400 | **/ | ||
401 | QString getCurrentFileName()const; | ||
402 | /// Returns \c unzFile handle. | ||
403 | /** You can use this handle to directly call UNZIP part of the | ||
404 | * ZIP/UNZIP package functions (see unzip.h). | ||
405 | * | ||
406 | * \warning When using the handle returned by this function, please | ||
407 | * keep in mind that QuaZip class is unable to detect any changes | ||
408 | * you make in the ZIP file state (e. g. changing current file, or | ||
409 | * closing the handle). So please do not do anything with this | ||
410 | * handle that is possible to do with the functions of this class. | ||
411 | * Or at least return the handle in the original state before | ||
412 | * calling some another function of this class (including implicit | ||
413 | * destructor calls and calls from the QuaZipFile objects that refer | ||
414 | * to this QuaZip instance!). So if you have changed the current | ||
415 | * file in the ZIP archive - then change it back or you may | ||
416 | * experience some strange behavior or even crashes. | ||
417 | **/ | ||
418 | unzFile getUnzFile(); | ||
419 | /// Returns \c zipFile handle. | ||
420 | /** You can use this handle to directly call ZIP part of the | ||
421 | * ZIP/UNZIP package functions (see zip.h). Warnings about the | ||
422 | * getUnzFile() function also apply to this function. | ||
423 | **/ | ||
424 | zipFile getZipFile(); | ||
425 | /// Changes the data descriptor writing mode. | ||
426 | /** | ||
427 | According to the ZIP format specification, a file inside archive | ||
428 | may have a data descriptor immediately following the file | ||
429 | data. This is reflected by a special flag in the local file header | ||
430 | and in the central directory. By default, QuaZIP sets this flag | ||
431 | and writes the data descriptor unless both method and level were | ||
432 | set to 0, in which case it operates in 1.0-compatible mode and | ||
433 | never writes data descriptors. | ||
434 | |||
435 | By setting this flag to false, it is possible to disable data | ||
436 | descriptor writing, thus increasing compatibility with archive | ||
437 | readers that don't understand this feature of the ZIP file format. | ||
438 | |||
439 | Setting this flag affects all the QuaZipFile instances that are | ||
440 | opened after this flag is set. | ||
441 | |||
442 | The data descriptor writing mode is enabled by default. | ||
443 | |||
444 | Note that if the ZIP archive is written into a QIODevice for which | ||
445 | QIODevice::isSequential() returns \c true, then the data descriptor | ||
446 | is mandatory and will be written even if this flag is set to false. | ||
447 | |||
448 | \param enabled If \c true, enable local descriptor writing, | ||
449 | disable it otherwise. | ||
450 | |||
451 | \sa QuaZipFile::isDataDescriptorWritingEnabled() | ||
452 | */ | ||
453 | void setDataDescriptorWritingEnabled(bool enabled); | ||
454 | /// Returns the data descriptor default writing mode. | ||
455 | /** | ||
456 | \sa setDataDescriptorWritingEnabled() | ||
457 | */ | ||
458 | bool isDataDescriptorWritingEnabled() const; | ||
459 | /// Returns a list of files inside the archive. | ||
460 | /** | ||
461 | \return A list of file names or an empty list if there | ||
462 | was an error or if the archive is empty (call getZipError() to | ||
463 | figure out which). | ||
464 | \sa getFileInfoList() | ||
465 | */ | ||
466 | QStringList getFileNameList() const; | ||
467 | /// Returns information list about all files inside the archive. | ||
468 | /** | ||
469 | \return A list of QuaZipFileInfo objects or an empty list if there | ||
470 | was an error or if the archive is empty (call getZipError() to | ||
471 | figure out which). | ||
472 | |||
473 | This function doesn't support zip64, but will still work with zip64 | ||
474 | archives, converting results using QuaZipFileInfo64::toQuaZipFileInfo(). | ||
475 | If all file sizes are below 4 GB, it will work just fine. | ||
476 | |||
477 | \sa getFileNameList() | ||
478 | \sa getFileInfoList64() | ||
479 | */ | ||
480 | QList<QuaZipFileInfo> getFileInfoList() const; | ||
481 | /// Returns information list about all files inside the archive. | ||
482 | /** | ||
483 | \overload | ||
484 | |||
485 | This function supports zip64. | ||
486 | |||
487 | \sa getFileNameList() | ||
488 | \sa getFileInfoList() | ||
489 | */ | ||
490 | QList<QuaZipFileInfo64> getFileInfoList64() const; | ||
491 | /// Enables the zip64 mode. | ||
492 | /** | ||
493 | * @param zip64 If \c true, the zip64 mode is enabled, disabled otherwise. | ||
494 | * | ||
495 | * Once this is enabled, all new files (until the mode is disabled again) | ||
496 | * will be created in the zip64 mode, thus enabling the ability to write | ||
497 | * files larger than 4 GB. By default, the zip64 mode is off due to | ||
498 | * compatibility reasons. | ||
499 | * | ||
500 | * Note that this does not affect the ability to read zip64 archives in any | ||
501 | * way. | ||
502 | * | ||
503 | * \sa isZip64Enabled() | ||
504 | */ | ||
505 | void setZip64Enabled(bool zip64); | ||
506 | /// Returns whether the zip64 mode is enabled. | ||
507 | /** | ||
508 | * @return \c true if and only if the zip64 mode is enabled. | ||
509 | * | ||
510 | * \sa setZip64Enabled() | ||
511 | */ | ||
512 | bool isZip64Enabled() const; | ||
513 | /// Enables the use of UTF-8 encoding for file names and comments text. | ||
514 | /** | ||
515 | * @param utf8 If \c true, the UTF-8 mode is enabled, disabled otherwise. | ||
516 | * | ||
517 | * Once this is enabled, the names of all new files and comments text (until | ||
518 | * the mode is disabled again) will be encoded in UTF-8 encoding, and the | ||
519 | * version to extract will be set to 6.3 (63) in ZIP header. By default, | ||
520 | * the UTF-8 mode is off due to compatibility reasons. | ||
521 | * | ||
522 | * Note that when extracting ZIP archives, the UTF-8 mode is determined from | ||
523 | * ZIP file header, not from this flag. | ||
524 | * | ||
525 | * \sa isUtf8Enabled() | ||
526 | */ | ||
527 | void setUtf8Enabled(bool utf8); | ||
528 | /// Returns whether the UTF-8 encoding mode is enabled. | ||
529 | /** | ||
530 | * @return \c true if and only if the UTF-8 mode is enabled. | ||
531 | * | ||
532 | * \sa setUtf8Enabled() | ||
533 | */ | ||
534 | bool isUtf8Enabled() const; | ||
535 | /// Returns the auto-close flag. | ||
536 | /** | ||
537 | @sa setAutoClose() | ||
538 | */ | ||
539 | bool isAutoClose() const; | ||
540 | /// Sets or unsets the auto-close flag. | ||
541 | /** | ||
542 | By default, QuaZIP opens the underlying QIODevice when open() is called, | ||
543 | and closes it when close() is called. In some cases, when the device | ||
544 | is set explicitly using setIoDevice(), it may be desirable to | ||
545 | leave the device open. If the auto-close flag is unset using this method, | ||
546 | then the device isn't closed automatically if it was set explicitly. | ||
547 | |||
548 | If it is needed to clear this flag, it is recommended to do so before | ||
549 | opening the archive because otherwise QuaZIP may close the device | ||
550 | during the open() call if an error is encountered after the device | ||
551 | is opened. | ||
552 | |||
553 | If the device was not set explicitly, but rather the setZipName() or | ||
554 | the appropriate constructor was used to set the ZIP file name instead, | ||
555 | then the auto-close flag has no effect, and the internal device | ||
556 | is closed nevertheless because there is no other way to close it. | ||
557 | |||
558 | @sa isAutoClose() | ||
559 | @sa setIoDevice() | ||
560 | */ | ||
561 | void setAutoClose(bool autoClose) const; | ||
562 | /// Sets the default file name codec to use. | ||
563 | /** | ||
564 | * The default codec is used by the constructors, so calling this function | ||
565 | * won't affect the QuaZip instances already created at that moment. | ||
566 | * | ||
567 | * The codec specified here can be overriden by calling setFileNameCodec(). | ||
568 | * If neither function is called, QTextCodec::codecForLocale() will be used | ||
569 | * to decode or encode file names. Use this function with caution if | ||
570 | * the application uses other libraries that depend on QuaZIP. Those | ||
571 | * libraries can either call this function by themselves, thus overriding | ||
572 | * your setting or can rely on the default encoding, thus failing | ||
573 | * mysteriously if you change it. For these reasons, it isn't recommended | ||
574 | * to use this function if you are developing a library, not an application. | ||
575 | * Instead, ask your library users to call it in case they need specific | ||
576 | * encoding. | ||
577 | * | ||
578 | * In most cases, using setFileNameCodec() instead is the right choice. | ||
579 | * However, if you depend on third-party code that uses QuaZIP, then the | ||
580 | * reasons stated above can actually become a reason to use this function | ||
581 | * in case the third-party code in question fails because it doesn't | ||
582 | * understand the encoding you need and doesn't provide a way to specify it. | ||
583 | * This applies to the JlCompress class as well, as it was contributed and | ||
584 | * doesn't support explicit encoding parameters. | ||
585 | * | ||
586 | * In short: use setFileNameCodec() when you can, resort to | ||
587 | * setDefaultFileNameCodec() when you don't have access to the QuaZip | ||
588 | * instance. | ||
589 | * | ||
590 | * @param codec The codec to use by default. If NULL, resets to default. | ||
591 | */ | ||
592 | static void setDefaultFileNameCodec(QTextCodec *codec); | ||
593 | /** | ||
594 | * @overload | ||
595 | * Equivalent to calling | ||
596 | * setDefaultFileNameCodec(QTextCodec::codecForName(codecName)). | ||
597 | */ | ||
598 | static void setDefaultFileNameCodec(const char *codecName); | ||
599 | /// Sets default OS code. | ||
600 | /** | ||
601 | * @sa setOsCode() | ||
602 | */ | ||
603 | static void setDefaultOsCode(uint osCode); | ||
604 | /// Returns default OS code. | ||
605 | /** | ||
606 | * @sa getOsCode() | ||
607 | */ | ||
608 | static uint getDefaultOsCode(); | ||
609 | }; | ||
610 | |||
611 | #endif | ||
diff --git a/utils/rbutilqt/quazip/quazip.pri b/utils/rbutilqt/quazip/quazip.pri new file mode 100644 index 0000000000..3a82bd0275 --- /dev/null +++ b/utils/rbutilqt/quazip/quazip.pri | |||
@@ -0,0 +1,25 @@ | |||
1 | |||
2 | SOURCES += \ | ||
3 | $$PWD/quazip.cpp \ | ||
4 | $$PWD/quazipfile.cpp \ | ||
5 | $$PWD/quazipnewinfo.cpp \ | ||
6 | $$PWD/quazipfileinfo.cpp \ | ||
7 | $$PWD/qioapi.cpp \ | ||
8 | $$PWD/unzip.c \ | ||
9 | $$PWD/zip.c \ | ||
10 | |||
11 | HEADERS += \ | ||
12 | $$PWD/minizip_crypt.h \ | ||
13 | $$PWD/ioapi.h \ | ||
14 | $$PWD/quazipfile.h \ | ||
15 | $$PWD/quazipfileinfo.h \ | ||
16 | $$PWD/quazipnewinfo.h \ | ||
17 | $$PWD/quazip.h \ | ||
18 | $$PWD/quazipnewinfo.h \ | ||
19 | $$PWD/quazip_global.h \ | ||
20 | $$PWD/unzip.h \ | ||
21 | $$PWD/zip.h \ | ||
22 | |||
23 | DEFINES += \ | ||
24 | QUAZIP_STATIC | ||
25 | |||
diff --git a/utils/rbutilqt/quazip/quazip_global.h b/utils/rbutilqt/quazip/quazip_global.h new file mode 100644 index 0000000000..de581bd7c4 --- /dev/null +++ b/utils/rbutilqt/quazip/quazip_global.h | |||
@@ -0,0 +1,63 @@ | |||
1 | #ifndef QUAZIP_GLOBAL_H | ||
2 | #define QUAZIP_GLOBAL_H | ||
3 | |||
4 | /* | ||
5 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
6 | |||
7 | This file is part of QuaZIP. | ||
8 | |||
9 | QuaZIP is free software: you can redistribute it and/or modify | ||
10 | it under the terms of the GNU Lesser General Public License as published by | ||
11 | the Free Software Foundation, either version 2.1 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | QuaZIP is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU Lesser General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU Lesser General Public License | ||
20 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | See COPYING file for the full LGPL text. | ||
23 | |||
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors, | ||
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license. | ||
26 | */ | ||
27 | |||
28 | #include <QtCore/qglobal.h> | ||
29 | |||
30 | /** | ||
31 | This is automatically defined when building a static library, but when | ||
32 | including QuaZip sources directly into a project, QUAZIP_STATIC should | ||
33 | be defined explicitly to avoid possible troubles with unnecessary | ||
34 | importing/exporting. | ||
35 | */ | ||
36 | #ifdef QUAZIP_STATIC | ||
37 | #define QUAZIP_EXPORT | ||
38 | #else | ||
39 | /** | ||
40 | * When building a DLL with MSVC, QUAZIP_BUILD must be defined. | ||
41 | * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc. | ||
42 | */ | ||
43 | #if defined(QUAZIP_BUILD) | ||
44 | #define QUAZIP_EXPORT Q_DECL_EXPORT | ||
45 | #else | ||
46 | #define QUAZIP_EXPORT Q_DECL_IMPORT | ||
47 | #endif | ||
48 | #endif // QUAZIP_STATIC | ||
49 | |||
50 | #ifdef __GNUC__ | ||
51 | #define QUAZIP_UNUSED __attribute__((__unused__)) | ||
52 | #else | ||
53 | #define QUAZIP_UNUSED | ||
54 | #endif | ||
55 | |||
56 | #define QUAZIP_EXTRA_NTFS_MAGIC 0x000Au | ||
57 | #define QUAZIP_EXTRA_NTFS_TIME_MAGIC 0x0001u | ||
58 | #define QUAZIP_EXTRA_EXT_TIME_MAGIC 0x5455u | ||
59 | #define QUAZIP_EXTRA_EXT_MOD_TIME_FLAG 1 | ||
60 | #define QUAZIP_EXTRA_EXT_AC_TIME_FLAG 2 | ||
61 | #define QUAZIP_EXTRA_EXT_CR_TIME_FLAG 4 | ||
62 | |||
63 | #endif // QUAZIP_GLOBAL_H | ||
diff --git a/utils/rbutilqt/quazip/quazipfile.cpp b/utils/rbutilqt/quazip/quazipfile.cpp new file mode 100644 index 0000000000..b984de7279 --- /dev/null +++ b/utils/rbutilqt/quazip/quazipfile.cpp | |||
@@ -0,0 +1,570 @@ | |||
1 | /* | ||
2 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
3 | |||
4 | This file is part of QuaZIP. | ||
5 | |||
6 | QuaZIP is free software: you can redistribute it and/or modify | ||
7 | it under the terms of the GNU Lesser General Public License as published by | ||
8 | the Free Software Foundation, either version 2.1 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | QuaZIP is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU Lesser General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Lesser General Public License | ||
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
18 | |||
19 | See COPYING file for the full LGPL text. | ||
20 | |||
21 | Original ZIP package is copyrighted by Gilles Vollant, see | ||
22 | quazip/(un)zip.h files for details, basically it's zlib license. | ||
23 | **/ | ||
24 | |||
25 | #include "quazipfile.h" | ||
26 | |||
27 | #include "quazipfileinfo.h" | ||
28 | |||
29 | using namespace std; | ||
30 | |||
31 | #define QUAZIP_VERSION_MADE_BY 0x1Eu | ||
32 | |||
33 | /// The implementation class for QuaZip. | ||
34 | /** | ||
35 | \internal | ||
36 | |||
37 | This class contains all the private stuff for the QuaZipFile class, thus | ||
38 | allowing to preserve binary compatibility between releases, the | ||
39 | technique known as the Pimpl (private implementation) idiom. | ||
40 | */ | ||
41 | class QuaZipFilePrivate { | ||
42 | friend class QuaZipFile; | ||
43 | private: | ||
44 | Q_DISABLE_COPY(QuaZipFilePrivate) | ||
45 | /// The pointer to the associated QuaZipFile instance. | ||
46 | QuaZipFile *q; | ||
47 | /// The QuaZip object to work with. | ||
48 | QuaZip *zip; | ||
49 | /// The file name. | ||
50 | QString fileName; | ||
51 | /// Case sensitivity mode. | ||
52 | QuaZip::CaseSensitivity caseSensitivity; | ||
53 | /// Whether this file is opened in the raw mode. | ||
54 | bool raw; | ||
55 | /// Write position to keep track of. | ||
56 | /** | ||
57 | QIODevice::pos() is broken for non-seekable devices, so we need | ||
58 | our own position. | ||
59 | */ | ||
60 | qint64 writePos; | ||
61 | /// Uncompressed size to write along with a raw file. | ||
62 | quint64 uncompressedSize; | ||
63 | /// CRC to write along with a raw file. | ||
64 | quint32 crc; | ||
65 | /// Whether \ref zip points to an internal QuaZip instance. | ||
66 | /** | ||
67 | This is true if the archive was opened by name, rather than by | ||
68 | supplying an existing QuaZip instance. | ||
69 | */ | ||
70 | bool internal; | ||
71 | /// The last error. | ||
72 | int zipError; | ||
73 | /// Resets \ref zipError. | ||
74 | inline void resetZipError() const {setZipError(UNZ_OK);} | ||
75 | /// Sets the zip error. | ||
76 | /** | ||
77 | This function is marked as const although it changes one field. | ||
78 | This allows to call it from const functions that don't change | ||
79 | anything by themselves. | ||
80 | */ | ||
81 | void setZipError(int zipError) const; | ||
82 | /// The constructor for the corresponding QuaZipFile constructor. | ||
83 | inline QuaZipFilePrivate(QuaZipFile *q): | ||
84 | q(q), | ||
85 | zip(NULL), | ||
86 | caseSensitivity(QuaZip::csDefault), | ||
87 | raw(false), | ||
88 | writePos(0), | ||
89 | uncompressedSize(0), | ||
90 | crc(0), | ||
91 | internal(true), | ||
92 | zipError(UNZ_OK) {} | ||
93 | /// The constructor for the corresponding QuaZipFile constructor. | ||
94 | inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName): | ||
95 | q(q), | ||
96 | caseSensitivity(QuaZip::csDefault), | ||
97 | raw(false), | ||
98 | writePos(0), | ||
99 | uncompressedSize(0), | ||
100 | crc(0), | ||
101 | internal(true), | ||
102 | zipError(UNZ_OK) | ||
103 | { | ||
104 | zip=new QuaZip(zipName); | ||
105 | } | ||
106 | /// The constructor for the corresponding QuaZipFile constructor. | ||
107 | inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName, | ||
108 | QuaZip::CaseSensitivity cs): | ||
109 | q(q), | ||
110 | raw(false), | ||
111 | writePos(0), | ||
112 | uncompressedSize(0), | ||
113 | crc(0), | ||
114 | internal(true), | ||
115 | zipError(UNZ_OK) | ||
116 | { | ||
117 | zip=new QuaZip(zipName); | ||
118 | this->fileName=fileName; | ||
119 | if (this->fileName.startsWith(QLatin1String("/"))) | ||
120 | this->fileName = this->fileName.mid(1); | ||
121 | this->caseSensitivity=cs; | ||
122 | } | ||
123 | /// The constructor for the QuaZipFile constructor accepting a file name. | ||
124 | inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip): | ||
125 | q(q), | ||
126 | zip(zip), | ||
127 | raw(false), | ||
128 | writePos(0), | ||
129 | uncompressedSize(0), | ||
130 | crc(0), | ||
131 | internal(false), | ||
132 | zipError(UNZ_OK) {} | ||
133 | /// The destructor. | ||
134 | inline ~QuaZipFilePrivate() | ||
135 | { | ||
136 | if (internal) | ||
137 | delete zip; | ||
138 | } | ||
139 | }; | ||
140 | |||
141 | QuaZipFile::QuaZipFile(): | ||
142 | p(new QuaZipFilePrivate(this)) | ||
143 | { | ||
144 | } | ||
145 | |||
146 | QuaZipFile::QuaZipFile(QObject *parent): | ||
147 | QIODevice(parent), | ||
148 | p(new QuaZipFilePrivate(this)) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent): | ||
153 | QIODevice(parent), | ||
154 | p(new QuaZipFilePrivate(this, zipName)) | ||
155 | { | ||
156 | } | ||
157 | |||
158 | QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName, | ||
159 | QuaZip::CaseSensitivity cs, QObject *parent): | ||
160 | QIODevice(parent), | ||
161 | p(new QuaZipFilePrivate(this, zipName, fileName, cs)) | ||
162 | { | ||
163 | } | ||
164 | |||
165 | QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent): | ||
166 | QIODevice(parent), | ||
167 | p(new QuaZipFilePrivate(this, zip)) | ||
168 | { | ||
169 | } | ||
170 | |||
171 | QuaZipFile::~QuaZipFile() | ||
172 | { | ||
173 | if (isOpen()) | ||
174 | close(); | ||
175 | delete p; | ||
176 | } | ||
177 | |||
178 | QString QuaZipFile::getZipName() const | ||
179 | { | ||
180 | return p->zip==NULL ? QString() : p->zip->getZipName(); | ||
181 | } | ||
182 | |||
183 | QuaZip *QuaZipFile::getZip() const | ||
184 | { | ||
185 | return p->internal ? NULL : p->zip; | ||
186 | } | ||
187 | |||
188 | QString QuaZipFile::getActualFileName()const | ||
189 | { | ||
190 | p->setZipError(UNZ_OK); | ||
191 | if (p->zip == NULL || (openMode() & WriteOnly)) | ||
192 | return QString(); | ||
193 | QString name=p->zip->getCurrentFileName(); | ||
194 | if(name.isNull()) | ||
195 | p->setZipError(p->zip->getZipError()); | ||
196 | return name; | ||
197 | } | ||
198 | |||
199 | void QuaZipFile::setZipName(const QString& zipName) | ||
200 | { | ||
201 | if(isOpen()) { | ||
202 | qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name"); | ||
203 | return; | ||
204 | } | ||
205 | if(p->zip!=NULL && p->internal) | ||
206 | delete p->zip; | ||
207 | p->zip=new QuaZip(zipName); | ||
208 | p->internal=true; | ||
209 | } | ||
210 | |||
211 | void QuaZipFile::setZip(QuaZip *zip) | ||
212 | { | ||
213 | if(isOpen()) { | ||
214 | qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP"); | ||
215 | return; | ||
216 | } | ||
217 | if(p->zip!=NULL && p->internal) | ||
218 | delete p->zip; | ||
219 | p->zip=zip; | ||
220 | p->fileName=QString(); | ||
221 | p->internal=false; | ||
222 | } | ||
223 | |||
224 | void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs) | ||
225 | { | ||
226 | if(p->zip==NULL) { | ||
227 | qWarning("QuaZipFile::setFileName(): call setZipName() first"); | ||
228 | return; | ||
229 | } | ||
230 | if(!p->internal) { | ||
231 | qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip"); | ||
232 | return; | ||
233 | } | ||
234 | if(isOpen()) { | ||
235 | qWarning("QuaZipFile::setFileName(): can not set file name for already opened file"); | ||
236 | return; | ||
237 | } | ||
238 | p->fileName=fileName; | ||
239 | if (p->fileName.startsWith(QLatin1String("/"))) | ||
240 | p->fileName = p->fileName.mid(1); | ||
241 | p->caseSensitivity=cs; | ||
242 | } | ||
243 | |||
244 | void QuaZipFilePrivate::setZipError(int zipError) const | ||
245 | { | ||
246 | QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const | ||
247 | fakeThis->zipError=zipError; | ||
248 | if(zipError==UNZ_OK) | ||
249 | q->setErrorString(QString()); | ||
250 | else | ||
251 | q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError)); | ||
252 | } | ||
253 | |||
254 | bool QuaZipFile::open(OpenMode mode) | ||
255 | { | ||
256 | return open(mode, NULL); | ||
257 | } | ||
258 | |||
259 | bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password) | ||
260 | { | ||
261 | p->resetZipError(); | ||
262 | if(isOpen()) { | ||
263 | qWarning("QuaZipFile::open(): already opened"); | ||
264 | return false; | ||
265 | } | ||
266 | if(mode&Unbuffered) { | ||
267 | qWarning("QuaZipFile::open(): Unbuffered mode is not supported"); | ||
268 | return false; | ||
269 | } | ||
270 | if((mode&ReadOnly)&&!(mode&WriteOnly)) { | ||
271 | if(p->internal) { | ||
272 | if(!p->zip->open(QuaZip::mdUnzip)) { | ||
273 | p->setZipError(p->zip->getZipError()); | ||
274 | return false; | ||
275 | } | ||
276 | if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) { | ||
277 | p->setZipError(p->zip->getZipError()); | ||
278 | p->zip->close(); | ||
279 | return false; | ||
280 | } | ||
281 | } else { | ||
282 | if(p->zip==NULL) { | ||
283 | qWarning("QuaZipFile::open(): zip is NULL"); | ||
284 | return false; | ||
285 | } | ||
286 | if(p->zip->getMode()!=QuaZip::mdUnzip) { | ||
287 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", | ||
288 | (int)mode, (int)p->zip->getMode()); | ||
289 | return false; | ||
290 | } | ||
291 | if(!p->zip->hasCurrentFile()) { | ||
292 | qWarning("QuaZipFile::open(): zip does not have current file"); | ||
293 | return false; | ||
294 | } | ||
295 | } | ||
296 | p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password)); | ||
297 | if(p->zipError==UNZ_OK) { | ||
298 | setOpenMode(mode); | ||
299 | p->raw=raw; | ||
300 | return true; | ||
301 | } else | ||
302 | return false; | ||
303 | } | ||
304 | qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); | ||
305 | return false; | ||
306 | } | ||
307 | |||
308 | bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info, | ||
309 | const char *password, quint32 crc, | ||
310 | int method, int level, bool raw, | ||
311 | int windowBits, int memLevel, int strategy) | ||
312 | { | ||
313 | zip_fileinfo info_z; | ||
314 | p->resetZipError(); | ||
315 | if(isOpen()) { | ||
316 | qWarning("QuaZipFile::open(): already opened"); | ||
317 | return false; | ||
318 | } | ||
319 | if((mode&WriteOnly)&&!(mode&ReadOnly)) { | ||
320 | if(p->internal) { | ||
321 | qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach"); | ||
322 | return false; | ||
323 | } | ||
324 | if(p->zip==NULL) { | ||
325 | qWarning("QuaZipFile::open(): zip is NULL"); | ||
326 | return false; | ||
327 | } | ||
328 | if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) { | ||
329 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", | ||
330 | (int)mode, (int)p->zip->getMode()); | ||
331 | return false; | ||
332 | } | ||
333 | info_z.tmz_date.tm_year=info.dateTime.date().year(); | ||
334 | info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1; | ||
335 | info_z.tmz_date.tm_mday=info.dateTime.date().day(); | ||
336 | info_z.tmz_date.tm_hour=info.dateTime.time().hour(); | ||
337 | info_z.tmz_date.tm_min=info.dateTime.time().minute(); | ||
338 | info_z.tmz_date.tm_sec=info.dateTime.time().second(); | ||
339 | info_z.dosDate = 0; | ||
340 | info_z.internal_fa=(uLong)info.internalAttr; | ||
341 | info_z.external_fa=(uLong)info.externalAttr; | ||
342 | if (p->zip->isDataDescriptorWritingEnabled()) | ||
343 | zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); | ||
344 | else | ||
345 | zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); | ||
346 | p->setZipError(zipOpenNewFileInZip4_64(p->zip->getZipFile(), | ||
347 | p->zip->isUtf8Enabled() | ||
348 | ? info.name.toUtf8().constData() | ||
349 | : p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), | ||
350 | &info_z, | ||
351 | info.extraLocal.constData(), info.extraLocal.length(), | ||
352 | info.extraGlobal.constData(), info.extraGlobal.length(), | ||
353 | p->zip->isUtf8Enabled() | ||
354 | ? info.comment.toUtf8().constData() | ||
355 | : p->zip->getCommentCodec()->fromUnicode(info.comment).constData(), | ||
356 | method, level, (int)raw, | ||
357 | windowBits, memLevel, strategy, | ||
358 | password, (uLong)crc, | ||
359 | (p->zip->getOsCode() << 8) | QUAZIP_VERSION_MADE_BY, | ||
360 | 0, | ||
361 | p->zip->isZip64Enabled())); | ||
362 | if(p->zipError==UNZ_OK) { | ||
363 | p->writePos=0; | ||
364 | setOpenMode(mode); | ||
365 | p->raw=raw; | ||
366 | if(raw) { | ||
367 | p->crc=crc; | ||
368 | p->uncompressedSize=info.uncompressedSize; | ||
369 | } | ||
370 | return true; | ||
371 | } else | ||
372 | return false; | ||
373 | } | ||
374 | qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); | ||
375 | return false; | ||
376 | } | ||
377 | |||
378 | bool QuaZipFile::isSequential()const | ||
379 | { | ||
380 | return true; | ||
381 | } | ||
382 | |||
383 | qint64 QuaZipFile::pos()const | ||
384 | { | ||
385 | if(p->zip==NULL) { | ||
386 | qWarning("QuaZipFile::pos(): call setZipName() or setZip() first"); | ||
387 | return -1; | ||
388 | } | ||
389 | if(!isOpen()) { | ||
390 | qWarning("QuaZipFile::pos(): file is not open"); | ||
391 | return -1; | ||
392 | } | ||
393 | if(openMode()&ReadOnly) | ||
394 | // QIODevice::pos() is broken for sequential devices, | ||
395 | // but thankfully bytesAvailable() returns the number of | ||
396 | // bytes buffered, so we know how far ahead we are. | ||
397 | return unztell64(p->zip->getUnzFile()) - QIODevice::bytesAvailable(); | ||
398 | else | ||
399 | return p->writePos; | ||
400 | } | ||
401 | |||
402 | bool QuaZipFile::atEnd()const | ||
403 | { | ||
404 | if(p->zip==NULL) { | ||
405 | qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first"); | ||
406 | return false; | ||
407 | } | ||
408 | if(!isOpen()) { | ||
409 | qWarning("QuaZipFile::atEnd(): file is not open"); | ||
410 | return false; | ||
411 | } | ||
412 | if(openMode()&ReadOnly) | ||
413 | // the same problem as with pos() | ||
414 | return QIODevice::bytesAvailable() == 0 | ||
415 | && unzeof(p->zip->getUnzFile())==1; | ||
416 | else | ||
417 | return true; | ||
418 | } | ||
419 | |||
420 | qint64 QuaZipFile::size()const | ||
421 | { | ||
422 | if(!isOpen()) { | ||
423 | qWarning("QuaZipFile::atEnd(): file is not open"); | ||
424 | return -1; | ||
425 | } | ||
426 | if(openMode()&ReadOnly) | ||
427 | return p->raw?csize():usize(); | ||
428 | else | ||
429 | return p->writePos; | ||
430 | } | ||
431 | |||
432 | qint64 QuaZipFile::csize()const | ||
433 | { | ||
434 | unz_file_info64 info_z; | ||
435 | p->setZipError(UNZ_OK); | ||
436 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1; | ||
437 | p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); | ||
438 | if(p->zipError!=UNZ_OK) | ||
439 | return -1; | ||
440 | return info_z.compressed_size; | ||
441 | } | ||
442 | |||
443 | qint64 QuaZipFile::usize()const | ||
444 | { | ||
445 | unz_file_info64 info_z; | ||
446 | p->setZipError(UNZ_OK); | ||
447 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1; | ||
448 | p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0)); | ||
449 | if(p->zipError!=UNZ_OK) | ||
450 | return -1; | ||
451 | return info_z.uncompressed_size; | ||
452 | } | ||
453 | |||
454 | bool QuaZipFile::getFileInfo(QuaZipFileInfo *info) | ||
455 | { | ||
456 | QuaZipFileInfo64 info64; | ||
457 | if (getFileInfo(&info64)) { | ||
458 | info64.toQuaZipFileInfo(*info); | ||
459 | return true; | ||
460 | } else { | ||
461 | return false; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | bool QuaZipFile::getFileInfo(QuaZipFileInfo64 *info) | ||
466 | { | ||
467 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false; | ||
468 | p->zip->getCurrentFileInfo(info); | ||
469 | p->setZipError(p->zip->getZipError()); | ||
470 | return p->zipError==UNZ_OK; | ||
471 | } | ||
472 | |||
473 | void QuaZipFile::close() | ||
474 | { | ||
475 | p->resetZipError(); | ||
476 | if(p->zip==NULL||!p->zip->isOpen()) return; | ||
477 | if(!isOpen()) { | ||
478 | qWarning("QuaZipFile::close(): file isn't open"); | ||
479 | return; | ||
480 | } | ||
481 | if(openMode()&ReadOnly) | ||
482 | p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile())); | ||
483 | else if(openMode()&WriteOnly) | ||
484 | if(isRaw()) p->setZipError(zipCloseFileInZipRaw64(p->zip->getZipFile(), p->uncompressedSize, p->crc)); | ||
485 | else p->setZipError(zipCloseFileInZip(p->zip->getZipFile())); | ||
486 | else { | ||
487 | qWarning("Wrong open mode: %d", (int)openMode()); | ||
488 | return; | ||
489 | } | ||
490 | if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen); | ||
491 | else return; | ||
492 | if(p->internal) { | ||
493 | p->zip->close(); | ||
494 | p->setZipError(p->zip->getZipError()); | ||
495 | } | ||
496 | } | ||
497 | |||
498 | qint64 QuaZipFile::readData(char *data, qint64 maxSize) | ||
499 | { | ||
500 | p->setZipError(UNZ_OK); | ||
501 | qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize); | ||
502 | if (bytesRead < 0) { | ||
503 | p->setZipError((int) bytesRead); | ||
504 | return -1; | ||
505 | } | ||
506 | return bytesRead; | ||
507 | } | ||
508 | |||
509 | qint64 QuaZipFile::writeData(const char* data, qint64 maxSize) | ||
510 | { | ||
511 | p->setZipError(ZIP_OK); | ||
512 | p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize)); | ||
513 | if(p->zipError!=ZIP_OK) return -1; | ||
514 | else { | ||
515 | p->writePos+=maxSize; | ||
516 | return maxSize; | ||
517 | } | ||
518 | } | ||
519 | |||
520 | QString QuaZipFile::getFileName() const | ||
521 | { | ||
522 | return p->fileName; | ||
523 | } | ||
524 | |||
525 | QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const | ||
526 | { | ||
527 | return p->caseSensitivity; | ||
528 | } | ||
529 | |||
530 | bool QuaZipFile::isRaw() const | ||
531 | { | ||
532 | return p->raw; | ||
533 | } | ||
534 | |||
535 | int QuaZipFile::getZipError() const | ||
536 | { | ||
537 | return p->zipError; | ||
538 | } | ||
539 | |||
540 | qint64 QuaZipFile::bytesAvailable() const | ||
541 | { | ||
542 | return size() - pos(); | ||
543 | } | ||
544 | |||
545 | QByteArray QuaZipFile::getLocalExtraField() | ||
546 | { | ||
547 | int size = unzGetLocalExtrafield(p->zip->getUnzFile(), NULL, 0); | ||
548 | QByteArray extra(size, '\0'); | ||
549 | int err = unzGetLocalExtrafield(p->zip->getUnzFile(), extra.data(), static_cast<uint>(extra.size())); | ||
550 | if (err < 0) { | ||
551 | p->setZipError(err); | ||
552 | return QByteArray(); | ||
553 | } | ||
554 | return extra; | ||
555 | } | ||
556 | |||
557 | QDateTime QuaZipFile::getExtModTime() | ||
558 | { | ||
559 | return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_MOD_TIME_FLAG); | ||
560 | } | ||
561 | |||
562 | QDateTime QuaZipFile::getExtAcTime() | ||
563 | { | ||
564 | return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_AC_TIME_FLAG); | ||
565 | } | ||
566 | |||
567 | QDateTime QuaZipFile::getExtCrTime() | ||
568 | { | ||
569 | return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_CR_TIME_FLAG); | ||
570 | } | ||
diff --git a/utils/rbutilqt/quazip/quazipfile.h b/utils/rbutilqt/quazip/quazipfile.h new file mode 100644 index 0000000000..0fd6829f36 --- /dev/null +++ b/utils/rbutilqt/quazip/quazipfile.h | |||
@@ -0,0 +1,508 @@ | |||
1 | #ifndef QUA_ZIPFILE_H | ||
2 | #define QUA_ZIPFILE_H | ||
3 | |||
4 | /* | ||
5 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
6 | |||
7 | This file is part of QuaZIP. | ||
8 | |||
9 | QuaZIP is free software: you can redistribute it and/or modify | ||
10 | it under the terms of the GNU Lesser General Public License as published by | ||
11 | the Free Software Foundation, either version 2.1 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | QuaZIP is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU Lesser General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU Lesser General Public License | ||
20 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | See COPYING file for the full LGPL text. | ||
23 | |||
24 | Original ZIP package is copyrighted by Gilles Vollant, see | ||
25 | quazip/(un)zip.h files for details, basically it's zlib license. | ||
26 | **/ | ||
27 | |||
28 | #include <QtCore/QIODevice> | ||
29 | |||
30 | #include "quazip_global.h" | ||
31 | #include "quazip.h" | ||
32 | #include "quazipnewinfo.h" | ||
33 | |||
34 | class QuaZipFilePrivate; | ||
35 | |||
36 | /// A file inside ZIP archive. | ||
37 | /** \class QuaZipFile quazipfile.h <quazip/quazipfile.h> | ||
38 | * This is the most interesting class. Not only it provides C++ | ||
39 | * interface to the ZIP/UNZIP package, but also integrates it with Qt by | ||
40 | * subclassing QIODevice. This makes possible to access files inside ZIP | ||
41 | * archive using QTextStream or QDataStream, for example. Actually, this | ||
42 | * is the main purpose of the whole QuaZIP library. | ||
43 | * | ||
44 | * You can either use existing QuaZip instance to create instance of | ||
45 | * this class or pass ZIP archive file name to this class, in which case | ||
46 | * it will create internal QuaZip object. See constructors' descriptions | ||
47 | * for details. Writing is only possible with the existing instance. | ||
48 | * | ||
49 | * Note that due to the underlying library's limitation it is not | ||
50 | * possible to use multiple QuaZipFile instances to open several files | ||
51 | * in the same archive at the same time. If you need to write to | ||
52 | * multiple files in parallel, then you should write to temporary files | ||
53 | * first, then pack them all at once when you have finished writing. If | ||
54 | * you need to read multiple files inside the same archive in parallel, | ||
55 | * you should extract them all into a temporary directory first. | ||
56 | * | ||
57 | * \section quazipfile-sequential Sequential or random-access? | ||
58 | * | ||
59 | * At the first thought, QuaZipFile has fixed size, the start and the | ||
60 | * end and should be therefore considered random-access device. But | ||
61 | * there is one major obstacle to making it random-access: ZIP/UNZIP API | ||
62 | * does not support seek() operation and the only way to implement it is | ||
63 | * through reopening the file and re-reading to the required position, | ||
64 | * but this is prohibitively slow. | ||
65 | * | ||
66 | * Therefore, QuaZipFile is considered to be a sequential device. This | ||
67 | * has advantage of availability of the ungetChar() operation (QIODevice | ||
68 | * does not implement it properly for non-sequential devices unless they | ||
69 | * support seek()). Disadvantage is a somewhat strange behaviour of the | ||
70 | * size() and pos() functions. This should be kept in mind while using | ||
71 | * this class. | ||
72 | * | ||
73 | **/ | ||
74 | class QUAZIP_EXPORT QuaZipFile: public QIODevice { | ||
75 | friend class QuaZipFilePrivate; | ||
76 | Q_OBJECT | ||
77 | private: | ||
78 | QuaZipFilePrivate *p; | ||
79 | // these are not supported nor implemented | ||
80 | QuaZipFile(const QuaZipFile& that); | ||
81 | QuaZipFile& operator=(const QuaZipFile& that); | ||
82 | protected: | ||
83 | /// Implementation of the QIODevice::readData(). | ||
84 | qint64 readData(char *data, qint64 maxSize); | ||
85 | /// Implementation of the QIODevice::writeData(). | ||
86 | qint64 writeData(const char *data, qint64 maxSize); | ||
87 | public: | ||
88 | /// Constructs a QuaZipFile instance. | ||
89 | /** You should use setZipName() and setFileName() or setZip() before | ||
90 | * trying to call open() on the constructed object. | ||
91 | **/ | ||
92 | QuaZipFile(); | ||
93 | /// Constructs a QuaZipFile instance. | ||
94 | /** \a parent argument specifies this object's parent object. | ||
95 | * | ||
96 | * You should use setZipName() and setFileName() or setZip() before | ||
97 | * trying to call open() on the constructed object. | ||
98 | **/ | ||
99 | QuaZipFile(QObject *parent); | ||
100 | /// Constructs a QuaZipFile instance. | ||
101 | /** \a parent argument specifies this object's parent object and \a | ||
102 | * zipName specifies ZIP archive file name. | ||
103 | * | ||
104 | * You should use setFileName() before trying to call open() on the | ||
105 | * constructed object. | ||
106 | * | ||
107 | * QuaZipFile constructed by this constructor can be used for read | ||
108 | * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. | ||
109 | **/ | ||
110 | QuaZipFile(const QString& zipName, QObject *parent =NULL); | ||
111 | /// Constructs a QuaZipFile instance. | ||
112 | /** \a parent argument specifies this object's parent object, \a | ||
113 | * zipName specifies ZIP archive file name and \a fileName and \a cs | ||
114 | * specify a name of the file to open inside archive. | ||
115 | * | ||
116 | * QuaZipFile constructed by this constructor can be used for read | ||
117 | * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. | ||
118 | * | ||
119 | * \sa QuaZip::setCurrentFile() | ||
120 | **/ | ||
121 | QuaZipFile(const QString& zipName, const QString& fileName, | ||
122 | QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL); | ||
123 | /// Constructs a QuaZipFile instance. | ||
124 | /** \a parent argument specifies this object's parent object. | ||
125 | * | ||
126 | * \a zip is the pointer to the existing QuaZip object. This | ||
127 | * QuaZipFile object then can be used to read current file in the | ||
128 | * \a zip or to write to the file inside it. | ||
129 | * | ||
130 | * \warning Using this constructor for reading current file can be | ||
131 | * tricky. Let's take the following example: | ||
132 | * \code | ||
133 | * QuaZip zip("archive.zip"); | ||
134 | * zip.open(QuaZip::mdUnzip); | ||
135 | * zip.setCurrentFile("file-in-archive"); | ||
136 | * QuaZipFile file(&zip); | ||
137 | * file.open(QIODevice::ReadOnly); | ||
138 | * // ok, now we can read from the file | ||
139 | * file.read(somewhere, some); | ||
140 | * zip.setCurrentFile("another-file-in-archive"); // oops... | ||
141 | * QuaZipFile anotherFile(&zip); | ||
142 | * anotherFile.open(QIODevice::ReadOnly); | ||
143 | * anotherFile.read(somewhere, some); // this is still ok... | ||
144 | * file.read(somewhere, some); // and this is NOT | ||
145 | * \endcode | ||
146 | * So, what exactly happens here? When we change current file in the | ||
147 | * \c zip archive, \c file that references it becomes invalid | ||
148 | * (actually, as far as I understand ZIP/UNZIP sources, it becomes | ||
149 | * closed, but QuaZipFile has no means to detect it). | ||
150 | * | ||
151 | * Summary: do not close \c zip object or change its current file as | ||
152 | * long as QuaZipFile is open. Even better - use another constructors | ||
153 | * which create internal QuaZip instances, one per object, and | ||
154 | * therefore do not cause unnecessary trouble. This constructor may | ||
155 | * be useful, though, if you already have a QuaZip instance and do | ||
156 | * not want to access several files at once. Good example: | ||
157 | * \code | ||
158 | * QuaZip zip("archive.zip"); | ||
159 | * zip.open(QuaZip::mdUnzip); | ||
160 | * // first, we need some information about archive itself | ||
161 | * QByteArray comment=zip.getComment(); | ||
162 | * // and now we are going to access files inside it | ||
163 | * QuaZipFile file(&zip); | ||
164 | * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { | ||
165 | * file.open(QIODevice::ReadOnly); | ||
166 | * // do something cool with file here | ||
167 | * file.close(); // do not forget to close! | ||
168 | * } | ||
169 | * zip.close(); | ||
170 | * \endcode | ||
171 | **/ | ||
172 | QuaZipFile(QuaZip *zip, QObject *parent =NULL); | ||
173 | /// Destroys a QuaZipFile instance. | ||
174 | /** Closes file if open, destructs internal QuaZip object (if it | ||
175 | * exists and \em is internal, of course). | ||
176 | **/ | ||
177 | virtual ~QuaZipFile(); | ||
178 | /// Returns the ZIP archive file name. | ||
179 | /** If this object was created by passing QuaZip pointer to the | ||
180 | * constructor, this function will return that QuaZip's file name | ||
181 | * (or null string if that object does not have file name yet). | ||
182 | * | ||
183 | * Otherwise, returns associated ZIP archive file name or null | ||
184 | * string if there are no name set yet. | ||
185 | * | ||
186 | * \sa setZipName() getFileName() | ||
187 | **/ | ||
188 | QString getZipName()const; | ||
189 | /// Returns a pointer to the associated QuaZip object. | ||
190 | /** Returns \c NULL if there is no associated QuaZip or it is | ||
191 | * internal (so you will not mess with it). | ||
192 | **/ | ||
193 | QuaZip* getZip()const; | ||
194 | /// Returns file name. | ||
195 | /** This function returns file name you passed to this object either | ||
196 | * by using | ||
197 | * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) | ||
198 | * or by calling setFileName(). Real name of the file may differ in | ||
199 | * case if you used case-insensitivity. | ||
200 | * | ||
201 | * Returns null string if there is no file name set yet. This is the | ||
202 | * case when this QuaZipFile operates on the existing QuaZip object | ||
203 | * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used). | ||
204 | * | ||
205 | * \sa getActualFileName | ||
206 | **/ | ||
207 | QString getFileName() const; | ||
208 | /// Returns case sensitivity of the file name. | ||
209 | /** This function returns case sensitivity argument you passed to | ||
210 | * this object either by using | ||
211 | * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) | ||
212 | * or by calling setFileName(). | ||
213 | * | ||
214 | * Returns unpredictable value if getFileName() returns null string | ||
215 | * (this is the case when you did not used setFileName() or | ||
216 | * constructor above). | ||
217 | * | ||
218 | * \sa getFileName | ||
219 | **/ | ||
220 | QuaZip::CaseSensitivity getCaseSensitivity() const; | ||
221 | /// Returns the actual file name in the archive. | ||
222 | /** This is \em not a ZIP archive file name, but a name of file inside | ||
223 | * archive. It is not necessary the same name that you have passed | ||
224 | * to the | ||
225 | * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), | ||
226 | * setFileName() or QuaZip::setCurrentFile() - this is the real file | ||
227 | * name inside archive, so it may differ in case if the file name | ||
228 | * search was case-insensitive. | ||
229 | * | ||
230 | * Equivalent to calling getCurrentFileName() on the associated | ||
231 | * QuaZip object. Returns null string if there is no associated | ||
232 | * QuaZip object or if it does not have a current file yet. And this | ||
233 | * is the case if you called setFileName() but did not open the | ||
234 | * file yet. So this is perfectly fine: | ||
235 | * \code | ||
236 | * QuaZipFile file("somezip.zip"); | ||
237 | * file.setFileName("somefile"); | ||
238 | * QString name=file.getName(); // name=="somefile" | ||
239 | * QString actual=file.getActualFileName(); // actual is null string | ||
240 | * file.open(QIODevice::ReadOnly); | ||
241 | * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows | ||
242 | * \endcode | ||
243 | * | ||
244 | * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity | ||
245 | **/ | ||
246 | QString getActualFileName()const; | ||
247 | /// Sets the ZIP archive file name. | ||
248 | /** Automatically creates internal QuaZip object and destroys | ||
249 | * previously created internal QuaZip object, if any. | ||
250 | * | ||
251 | * Will do nothing if this file is already open. You must close() it | ||
252 | * first. | ||
253 | **/ | ||
254 | void setZipName(const QString& zipName); | ||
255 | /// Returns \c true if the file was opened in raw mode. | ||
256 | /** If the file is not open, the returned value is undefined. | ||
257 | * | ||
258 | * \sa open(OpenMode,int*,int*,bool,const char*) | ||
259 | **/ | ||
260 | bool isRaw() const; | ||
261 | /// Binds to the existing QuaZip instance. | ||
262 | /** This function destroys internal QuaZip object, if any, and makes | ||
263 | * this QuaZipFile to use current file in the \a zip object for any | ||
264 | * further operations. See QuaZipFile(QuaZip*,QObject*) for the | ||
265 | * possible pitfalls. | ||
266 | * | ||
267 | * Will do nothing if the file is currently open. You must close() | ||
268 | * it first. | ||
269 | **/ | ||
270 | void setZip(QuaZip *zip); | ||
271 | /// Sets the file name. | ||
272 | /** Will do nothing if at least one of the following conditions is | ||
273 | * met: | ||
274 | * - ZIP name has not been set yet (getZipName() returns null | ||
275 | * string). | ||
276 | * - This QuaZipFile is associated with external QuaZip. In this | ||
277 | * case you should call that QuaZip's setCurrentFile() function | ||
278 | * instead! | ||
279 | * - File is already open so setting the name is meaningless. | ||
280 | * | ||
281 | * \sa QuaZip::setCurrentFile | ||
282 | **/ | ||
283 | void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault); | ||
284 | /// Opens a file for reading. | ||
285 | /** Returns \c true on success, \c false otherwise. | ||
286 | * Call getZipError() to get error code. | ||
287 | * | ||
288 | * \note Since ZIP/UNZIP API provides buffered reading only, | ||
289 | * QuaZipFile does not support unbuffered reading. So do not pass | ||
290 | * QIODevice::Unbuffered flag in \a mode, or open will fail. | ||
291 | **/ | ||
292 | virtual bool open(OpenMode mode); | ||
293 | /// Opens a file for reading. | ||
294 | /** \overload | ||
295 | * Argument \a password specifies a password to decrypt the file. If | ||
296 | * it is NULL then this function behaves just like open(OpenMode). | ||
297 | **/ | ||
298 | inline bool open(OpenMode mode, const char *password) | ||
299 | {return open(mode, NULL, NULL, false, password);} | ||
300 | /// Opens a file for reading. | ||
301 | /** \overload | ||
302 | * Argument \a password specifies a password to decrypt the file. | ||
303 | * | ||
304 | * An integers pointed by \a method and \a level will receive codes | ||
305 | * of the compression method and level used. See unzip.h. | ||
306 | * | ||
307 | * If raw is \c true then no decompression is performed. | ||
308 | * | ||
309 | * \a method should not be \c NULL. \a level can be \c NULL if you | ||
310 | * don't want to know the compression level. | ||
311 | **/ | ||
312 | bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL); | ||
313 | /// Opens a file for writing. | ||
314 | /** \a info argument specifies information about file. It should at | ||
315 | * least specify a correct file name. Also, it is a good idea to | ||
316 | * specify correct timestamp (by default, current time will be | ||
317 | * used). See QuaZipNewInfo. | ||
318 | * | ||
319 | * The \a password argument specifies the password for crypting. Pass NULL | ||
320 | * if you don't need any crypting. The \a crc argument was supposed | ||
321 | * to be used for crypting too, but then it turned out that it's | ||
322 | * false information, so you need to set it to 0 unless you want to | ||
323 | * use the raw mode (see below). | ||
324 | * | ||
325 | * Arguments \a method and \a level specify compression method and | ||
326 | * level. The only method supported is Z_DEFLATED, but you may also | ||
327 | * specify 0 for no compression. If all of the files in the archive | ||
328 | * use both method 0 and either level 0 is explicitly specified or | ||
329 | * data descriptor writing is disabled with | ||
330 | * QuaZip::setDataDescriptorWritingEnabled(), then the | ||
331 | * resulting archive is supposed to be compatible with the 1.0 ZIP | ||
332 | * format version, should you need that. Except for this, \a level | ||
333 | * has no other effects with method 0. | ||
334 | * | ||
335 | * If \a raw is \c true, no compression is performed. In this case, | ||
336 | * \a crc and uncompressedSize field of the \a info are required. | ||
337 | * | ||
338 | * Arguments \a windowBits, \a memLevel, \a strategy provide zlib | ||
339 | * algorithms tuning. See deflateInit2() in zlib. | ||
340 | **/ | ||
341 | bool open(OpenMode mode, const QuaZipNewInfo& info, | ||
342 | const char *password =NULL, quint32 crc =0, | ||
343 | int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false, | ||
344 | int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY); | ||
345 | /// Returns \c true, but \ref quazipfile-sequential "beware"! | ||
346 | virtual bool isSequential()const; | ||
347 | /// Returns current position in the file. | ||
348 | /** Implementation of the QIODevice::pos(). When reading, this | ||
349 | * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is | ||
350 | * unable to keep track of the ungetChar() calls (which is | ||
351 | * non-virtual and therefore is dangerous to reimplement). So if you | ||
352 | * are using ungetChar() feature of the QIODevice, this function | ||
353 | * reports incorrect value until you get back characters which you | ||
354 | * ungot. | ||
355 | * | ||
356 | * When writing, pos() returns number of bytes already written | ||
357 | * (uncompressed unless you use raw mode). | ||
358 | * | ||
359 | * \note Although | ||
360 | * \ref quazipfile-sequential "QuaZipFile is a sequential device" | ||
361 | * and therefore pos() should always return zero, it does not, | ||
362 | * because it would be misguiding. Keep this in mind. | ||
363 | * | ||
364 | * This function returns -1 if the file or archive is not open. | ||
365 | * | ||
366 | * Error code returned by getZipError() is not affected by this | ||
367 | * function call. | ||
368 | **/ | ||
369 | virtual qint64 pos()const; | ||
370 | /// Returns \c true if the end of file was reached. | ||
371 | /** This function returns \c false in the case of error. This means | ||
372 | * that you called this function on either not open file, or a file | ||
373 | * in the not open archive or even on a QuaZipFile instance that | ||
374 | * does not even have QuaZip instance associated. Do not do that | ||
375 | * because there is no means to determine whether \c false is | ||
376 | * returned because of error or because end of file was reached. | ||
377 | * Well, on the other side you may interpret \c false return value | ||
378 | * as "there is no file open to check for end of file and there is | ||
379 | * no end of file therefore". | ||
380 | * | ||
381 | * When writing, this function always returns \c true (because you | ||
382 | * are always writing to the end of file). | ||
383 | * | ||
384 | * Error code returned by getZipError() is not affected by this | ||
385 | * function call. | ||
386 | **/ | ||
387 | virtual bool atEnd()const; | ||
388 | /// Returns file size. | ||
389 | /** This function returns csize() if the file is open for reading in | ||
390 | * raw mode, usize() if it is open for reading in normal mode and | ||
391 | * pos() if it is open for writing. | ||
392 | * | ||
393 | * Returns -1 on error, call getZipError() to get error code. | ||
394 | * | ||
395 | * \note This function returns file size despite that | ||
396 | * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device", | ||
397 | * for which size() should return bytesAvailable() instead. But its | ||
398 | * name would be very misguiding otherwise, so just keep in mind | ||
399 | * this inconsistence. | ||
400 | **/ | ||
401 | virtual qint64 size()const; | ||
402 | /// Returns compressed file size. | ||
403 | /** Equivalent to calling getFileInfo() and then getting | ||
404 | * compressedSize field, but more convenient and faster. | ||
405 | * | ||
406 | * File must be open for reading before calling this function. | ||
407 | * | ||
408 | * Returns -1 on error, call getZipError() to get error code. | ||
409 | **/ | ||
410 | qint64 csize()const; | ||
411 | /// Returns uncompressed file size. | ||
412 | /** Equivalent to calling getFileInfo() and then getting | ||
413 | * uncompressedSize field, but more convenient and faster. See | ||
414 | * getFileInfo() for a warning. | ||
415 | * | ||
416 | * File must be open for reading before calling this function. | ||
417 | * | ||
418 | * Returns -1 on error, call getZipError() to get error code. | ||
419 | **/ | ||
420 | qint64 usize()const; | ||
421 | /// Gets information about current file. | ||
422 | /** This function does the same thing as calling | ||
423 | * QuaZip::getCurrentFileInfo() on the associated QuaZip object, | ||
424 | * but you can not call getCurrentFileInfo() if the associated | ||
425 | * QuaZip is internal (because you do not have access to it), while | ||
426 | * you still can call this function in that case. | ||
427 | * | ||
428 | * File must be open for reading before calling this function. | ||
429 | * | ||
430 | * \return \c false in the case of an error. | ||
431 | * | ||
432 | * This function doesn't support zip64, but will still work fine on zip64 | ||
433 | * archives if file sizes are below 4 GB, otherwise the values will be set | ||
434 | * as if converted using QuaZipFileInfo64::toQuaZipFileInfo(). | ||
435 | * | ||
436 | * \sa getFileInfo(QuaZipFileInfo64*) | ||
437 | **/ | ||
438 | bool getFileInfo(QuaZipFileInfo *info); | ||
439 | /// Gets information about current file with zip64 support. | ||
440 | /** | ||
441 | * @overload | ||
442 | * | ||
443 | * \sa getFileInfo(QuaZipFileInfo*) | ||
444 | */ | ||
445 | bool getFileInfo(QuaZipFileInfo64 *info); | ||
446 | /// Closes the file. | ||
447 | /** Call getZipError() to determine if the close was successful. | ||
448 | **/ | ||
449 | virtual void close(); | ||
450 | /// Returns the error code returned by the last ZIP/UNZIP API call. | ||
451 | int getZipError() const; | ||
452 | /// Returns the number of bytes available for reading. | ||
453 | virtual qint64 bytesAvailable() const; | ||
454 | /// Returns the local extra field | ||
455 | /** | ||
456 | There are two (optional) local extra fields associated with a file. | ||
457 | One is located in the central header and is available along | ||
458 | with the rest of the file information in @ref QuaZipFileInfo64::extra. | ||
459 | Another is located before the file itself, | ||
460 | and is returned by this function. The file must be open first. | ||
461 | |||
462 | @return the local extra field, or an empty array if there is none | ||
463 | (or file is not open) | ||
464 | */ | ||
465 | QByteArray getLocalExtraField(); | ||
466 | /// Returns the extended modification timestamp | ||
467 | /** | ||
468 | * The getExt*Time() functions only work if there is an extended timestamp | ||
469 | * extra field (ID 0x5455) present. Otherwise, they all return invalid null | ||
470 | * timestamps. | ||
471 | * | ||
472 | * Modification time, but not other times, can also be accessed through | ||
473 | * @ref QuaZipFileInfo64 without the need to open the file first. | ||
474 | * | ||
475 | * @sa dateTime | ||
476 | * @sa QuaZipFileInfo64::getExtModTime() | ||
477 | * @sa getExtAcTime() | ||
478 | * @sa getExtCrTime() | ||
479 | * @return The extended modification time, UTC | ||
480 | */ | ||
481 | QDateTime getExtModTime(); | ||
482 | /// Returns the extended access timestamp | ||
483 | /** | ||
484 | * The getExt*Time() functions only work if there is an extended timestamp | ||
485 | * extra field (ID 0x5455) present. Otherwise, they all return invalid null | ||
486 | * timestamps. | ||
487 | * @sa dateTime | ||
488 | * @sa QuaZipFileInfo64::getExtModTime() | ||
489 | * @sa getExtModTime() | ||
490 | * @sa getExtCrTime() | ||
491 | * @return The extended access time, UTC | ||
492 | */ | ||
493 | QDateTime getExtAcTime(); | ||
494 | /// Returns the extended creation timestamp | ||
495 | /** | ||
496 | * The getExt*Time() functions only work if there is an extended timestamp | ||
497 | * extra field (ID 0x5455) present. Otherwise, they all return invalid null | ||
498 | * timestamps. | ||
499 | * @sa dateTime | ||
500 | * @sa QuaZipFileInfo64::getExtModTime() | ||
501 | * @sa getExtModTime() | ||
502 | * @sa getExtAcTime() | ||
503 | * @return The extended creation time, UTC | ||
504 | */ | ||
505 | QDateTime getExtCrTime(); | ||
506 | }; | ||
507 | |||
508 | #endif | ||
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.cpp b/utils/rbutilqt/quazip/quazipfileinfo.cpp new file mode 100644 index 0000000000..d5798ea771 --- /dev/null +++ b/utils/rbutilqt/quazip/quazipfileinfo.cpp | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
3 | |||
4 | This file is part of QuaZIP. | ||
5 | |||
6 | QuaZIP is free software: you can redistribute it and/or modify | ||
7 | it under the terms of the GNU Lesser General Public License as published by | ||
8 | the Free Software Foundation, either version 2.1 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | QuaZIP is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU Lesser General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Lesser General Public License | ||
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
18 | |||
19 | See COPYING file for the full LGPL text. | ||
20 | |||
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors, | ||
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license. | ||
23 | */ | ||
24 | |||
25 | #include "quazipfileinfo.h" | ||
26 | |||
27 | #include <QtCore/QDataStream> | ||
28 | |||
29 | static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) { | ||
30 | quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16; | ||
31 | QFile::Permissions perm = QFile::Permissions(); | ||
32 | if ((uPerm & 0400) != 0) | ||
33 | perm |= QFile::ReadOwner; | ||
34 | if ((uPerm & 0200) != 0) | ||
35 | perm |= QFile::WriteOwner; | ||
36 | if ((uPerm & 0100) != 0) | ||
37 | perm |= QFile::ExeOwner; | ||
38 | if ((uPerm & 0040) != 0) | ||
39 | perm |= QFile::ReadGroup; | ||
40 | if ((uPerm & 0020) != 0) | ||
41 | perm |= QFile::WriteGroup; | ||
42 | if ((uPerm & 0010) != 0) | ||
43 | perm |= QFile::ExeGroup; | ||
44 | if ((uPerm & 0004) != 0) | ||
45 | perm |= QFile::ReadOther; | ||
46 | if ((uPerm & 0002) != 0) | ||
47 | perm |= QFile::WriteOther; | ||
48 | if ((uPerm & 0001) != 0) | ||
49 | perm |= QFile::ExeOther; | ||
50 | return perm; | ||
51 | |||
52 | } | ||
53 | |||
54 | QFile::Permissions QuaZipFileInfo::getPermissions() const | ||
55 | { | ||
56 | return permissionsFromExternalAttr(externalAttr); | ||
57 | } | ||
58 | |||
59 | QFile::Permissions QuaZipFileInfo64::getPermissions() const | ||
60 | { | ||
61 | return permissionsFromExternalAttr(externalAttr); | ||
62 | } | ||
63 | |||
64 | bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const | ||
65 | { | ||
66 | bool noOverflow = true; | ||
67 | info.name = name; | ||
68 | info.versionCreated = versionCreated; | ||
69 | info.versionNeeded = versionNeeded; | ||
70 | info.flags = flags; | ||
71 | info.method = method; | ||
72 | info.dateTime = dateTime; | ||
73 | info.crc = crc; | ||
74 | if (compressedSize > 0xFFFFFFFFu) { | ||
75 | info.compressedSize = 0xFFFFFFFFu; | ||
76 | noOverflow = false; | ||
77 | } else { | ||
78 | info.compressedSize = compressedSize; | ||
79 | } | ||
80 | if (uncompressedSize > 0xFFFFFFFFu) { | ||
81 | info.uncompressedSize = 0xFFFFFFFFu; | ||
82 | noOverflow = false; | ||
83 | } else { | ||
84 | info.uncompressedSize = uncompressedSize; | ||
85 | } | ||
86 | info.diskNumberStart = diskNumberStart; | ||
87 | info.internalAttr = internalAttr; | ||
88 | info.externalAttr = externalAttr; | ||
89 | info.comment = comment; | ||
90 | info.extra = extra; | ||
91 | return noOverflow; | ||
92 | } | ||
93 | |||
94 | static QDateTime getNTFSTime(const QByteArray &extra, int position, | ||
95 | int *fineTicks) | ||
96 | { | ||
97 | QDateTime dateTime; | ||
98 | QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra); | ||
99 | QList<QByteArray> ntfsExtraFields = extraHash[QUAZIP_EXTRA_NTFS_MAGIC]; | ||
100 | if (ntfsExtraFields.isEmpty()) | ||
101 | return dateTime; | ||
102 | QByteArray ntfsExtraField = ntfsExtraFields.at(0); | ||
103 | if (ntfsExtraField.length() <= 4) | ||
104 | return dateTime; | ||
105 | QByteArray ntfsAttributes = ntfsExtraField.mid(4); | ||
106 | QuaExtraFieldHash ntfsHash = QuaZipFileInfo64::parseExtraField(ntfsAttributes); | ||
107 | QList<QByteArray> ntfsTimeAttributes = ntfsHash[QUAZIP_EXTRA_NTFS_TIME_MAGIC]; | ||
108 | if (ntfsTimeAttributes.isEmpty()) | ||
109 | return dateTime; | ||
110 | QByteArray ntfsTimes = ntfsTimeAttributes.at(0); | ||
111 | if (ntfsTimes.size() < 24) | ||
112 | return dateTime; | ||
113 | QDataStream timeReader(ntfsTimes); | ||
114 | timeReader.setByteOrder(QDataStream::LittleEndian); | ||
115 | timeReader.device()->seek(position); | ||
116 | quint64 time; | ||
117 | timeReader >> time; | ||
118 | QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC); | ||
119 | dateTime = base.addMSecs(time / 10000); | ||
120 | if (fineTicks != NULL) { | ||
121 | *fineTicks = static_cast<int>(time % 10000); | ||
122 | } | ||
123 | return dateTime; | ||
124 | } | ||
125 | |||
126 | QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const | ||
127 | { | ||
128 | return getNTFSTime(extra, 0, fineTicks); | ||
129 | } | ||
130 | |||
131 | QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const | ||
132 | { | ||
133 | return getNTFSTime(extra, 8, fineTicks); | ||
134 | } | ||
135 | |||
136 | QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const | ||
137 | { | ||
138 | return getNTFSTime(extra, 16, fineTicks); | ||
139 | } | ||
140 | |||
141 | QDateTime QuaZipFileInfo64::getExtTime(const QByteArray &extra, int flag) | ||
142 | { | ||
143 | QDateTime dateTime; | ||
144 | QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra); | ||
145 | QList<QByteArray> extTimeFields = extraHash[QUAZIP_EXTRA_EXT_TIME_MAGIC]; | ||
146 | if (extTimeFields.isEmpty()) | ||
147 | return dateTime; | ||
148 | QByteArray extTimeField = extTimeFields.at(0); | ||
149 | if (extTimeField.length() < 1) | ||
150 | return dateTime; | ||
151 | QDataStream input(extTimeField); | ||
152 | input.setByteOrder(QDataStream::LittleEndian); | ||
153 | quint8 flags; | ||
154 | input >> flags; | ||
155 | int flagsRemaining = flags; | ||
156 | while (!input.atEnd()) { | ||
157 | int nextFlag = flagsRemaining & -flagsRemaining; | ||
158 | flagsRemaining &= flagsRemaining - 1; | ||
159 | qint32 time; | ||
160 | input >> time; | ||
161 | if (nextFlag == flag) { | ||
162 | QDateTime base(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC); | ||
163 | dateTime = base.addSecs(time); | ||
164 | return dateTime; | ||
165 | } | ||
166 | } | ||
167 | return dateTime; | ||
168 | } | ||
169 | |||
170 | QDateTime QuaZipFileInfo64::getExtModTime() const | ||
171 | { | ||
172 | return getExtTime(extra, 1); | ||
173 | } | ||
174 | |||
175 | QuaExtraFieldHash QuaZipFileInfo64::parseExtraField(const QByteArray &extraField) | ||
176 | { | ||
177 | QDataStream input(extraField); | ||
178 | input.setByteOrder(QDataStream::LittleEndian); | ||
179 | QHash<quint16, QList<QByteArray> > result; | ||
180 | while (!input.atEnd()) { | ||
181 | quint16 id, size; | ||
182 | input >> id; | ||
183 | if (input.status() == QDataStream::ReadPastEnd) | ||
184 | return result; | ||
185 | input >> size; | ||
186 | if (input.status() == QDataStream::ReadPastEnd) | ||
187 | return result; | ||
188 | QByteArray data; | ||
189 | data.resize(size); | ||
190 | int read = input.readRawData(data.data(), data.size()); | ||
191 | if (read < data.size()) | ||
192 | return result; | ||
193 | result[id] << data; | ||
194 | } | ||
195 | return result; | ||
196 | } | ||
diff --git a/utils/rbutilqt/quazip/quazipfileinfo.h b/utils/rbutilqt/quazip/quazipfileinfo.h new file mode 100644 index 0000000000..43665b4ac2 --- /dev/null +++ b/utils/rbutilqt/quazip/quazipfileinfo.h | |||
@@ -0,0 +1,226 @@ | |||
1 | #ifndef QUA_ZIPFILEINFO_H | ||
2 | #define QUA_ZIPFILEINFO_H | ||
3 | |||
4 | /* | ||
5 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
6 | |||
7 | This file is part of QuaZIP. | ||
8 | |||
9 | QuaZIP is free software: you can redistribute it and/or modify | ||
10 | it under the terms of the GNU Lesser General Public License as published by | ||
11 | the Free Software Foundation, either version 2.1 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | QuaZIP is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU Lesser General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU Lesser General Public License | ||
20 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | See COPYING file for the full LGPL text. | ||
23 | |||
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors, | ||
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license. | ||
26 | */ | ||
27 | |||
28 | #include <QtCore/QByteArray> | ||
29 | #include <QtCore/QDateTime> | ||
30 | #include <QtCore/QFile> | ||
31 | #include <QtCore/QHash> | ||
32 | |||
33 | #include "quazip_global.h" | ||
34 | |||
35 | /// The typedef to store extra field parse results | ||
36 | typedef QHash<quint16, QList<QByteArray> > QuaExtraFieldHash; | ||
37 | |||
38 | /// Information about a file inside archive. | ||
39 | /** | ||
40 | * \deprecated Use QuaZipFileInfo64 instead. Not only it supports large files, | ||
41 | * but also more convenience methods as well. | ||
42 | * | ||
43 | * Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to | ||
44 | * fill this structure. */ | ||
45 | struct QUAZIP_EXPORT QuaZipFileInfo { | ||
46 | /// File name. | ||
47 | QString name; | ||
48 | /// Version created by. | ||
49 | quint16 versionCreated; | ||
50 | /// Version needed to extract. | ||
51 | quint16 versionNeeded; | ||
52 | /// General purpose flags. | ||
53 | quint16 flags; | ||
54 | /// Compression method. | ||
55 | quint16 method; | ||
56 | /// Last modification date and time. | ||
57 | QDateTime dateTime; | ||
58 | /// CRC. | ||
59 | quint32 crc; | ||
60 | /// Compressed file size. | ||
61 | quint32 compressedSize; | ||
62 | /// Uncompressed file size. | ||
63 | quint32 uncompressedSize; | ||
64 | /// Disk number start. | ||
65 | quint16 diskNumberStart; | ||
66 | /// Internal file attributes. | ||
67 | quint16 internalAttr; | ||
68 | /// External file attributes. | ||
69 | quint32 externalAttr; | ||
70 | /// Comment. | ||
71 | QString comment; | ||
72 | /// Extra field. | ||
73 | QByteArray extra; | ||
74 | /// Get the file permissions. | ||
75 | /** | ||
76 | Returns the high 16 bits of external attributes converted to | ||
77 | QFile::Permissions. | ||
78 | */ | ||
79 | QFile::Permissions getPermissions() const; | ||
80 | }; | ||
81 | |||
82 | /// Information about a file inside archive (with zip64 support). | ||
83 | /** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to | ||
84 | * fill this structure. */ | ||
85 | struct QUAZIP_EXPORT QuaZipFileInfo64 { | ||
86 | /// File name. | ||
87 | QString name; | ||
88 | /// Version created by. | ||
89 | quint16 versionCreated; | ||
90 | /// Version needed to extract. | ||
91 | quint16 versionNeeded; | ||
92 | /// General purpose flags. | ||
93 | quint16 flags; | ||
94 | /// Compression method. | ||
95 | quint16 method; | ||
96 | /// Last modification date and time. | ||
97 | /** | ||
98 | * This is the time stored in the standard ZIP header. This format only allows | ||
99 | * to store time with 2-second precision, so the seconds will always be even | ||
100 | * and the milliseconds will always be zero. If you need more precise | ||
101 | * date and time, you can try to call the getNTFSmTime() function or | ||
102 | * its siblings, provided that the archive itself contains these NTFS times. | ||
103 | */ | ||
104 | QDateTime dateTime; | ||
105 | /// CRC. | ||
106 | quint32 crc; | ||
107 | /// Compressed file size. | ||
108 | quint64 compressedSize; | ||
109 | /// Uncompressed file size. | ||
110 | quint64 uncompressedSize; | ||
111 | /// Disk number start. | ||
112 | quint16 diskNumberStart; | ||
113 | /// Internal file attributes. | ||
114 | quint16 internalAttr; | ||
115 | /// External file attributes. | ||
116 | quint32 externalAttr; | ||
117 | /// Comment. | ||
118 | QString comment; | ||
119 | /// Extra field. | ||
120 | QByteArray extra; | ||
121 | /// Get the file permissions. | ||
122 | /** | ||
123 | Returns the high 16 bits of external attributes converted to | ||
124 | QFile::Permissions. | ||
125 | */ | ||
126 | QFile::Permissions getPermissions() const; | ||
127 | /// Converts to QuaZipFileInfo | ||
128 | /** | ||
129 | If any of the fields are greater than 0xFFFFFFFFu, they are set to | ||
130 | 0xFFFFFFFFu exactly, not just truncated. This function should be mainly used | ||
131 | for compatibility with the old code expecting QuaZipFileInfo, in the cases | ||
132 | when it's impossible or otherwise unadvisable (due to ABI compatibility | ||
133 | reasons, for example) to modify that old code to use QuaZipFileInfo64. | ||
134 | |||
135 | \return \c true if all fields converted correctly, \c false if an overflow | ||
136 | occured. | ||
137 | */ | ||
138 | bool toQuaZipFileInfo(QuaZipFileInfo &info) const; | ||
139 | /// Returns the NTFS modification time | ||
140 | /** | ||
141 | * The getNTFS*Time() functions only work if there is an NTFS extra field | ||
142 | * present. Otherwise, they all return invalid null timestamps. | ||
143 | * @param fineTicks If not NULL, the fractional part of milliseconds returned | ||
144 | * there, measured in 100-nanosecond ticks. Will be set to | ||
145 | * zero if there is no NTFS extra field. | ||
146 | * @sa dateTime | ||
147 | * @sa getNTFSaTime() | ||
148 | * @sa getNTFScTime() | ||
149 | * @return The NTFS modification time, UTC | ||
150 | */ | ||
151 | QDateTime getNTFSmTime(int *fineTicks = NULL) const; | ||
152 | /// Returns the NTFS access time | ||
153 | /** | ||
154 | * The getNTFS*Time() functions only work if there is an NTFS extra field | ||
155 | * present. Otherwise, they all return invalid null timestamps. | ||
156 | * @param fineTicks If not NULL, the fractional part of milliseconds returned | ||
157 | * there, measured in 100-nanosecond ticks. Will be set to | ||
158 | * zero if there is no NTFS extra field. | ||
159 | * @sa dateTime | ||
160 | * @sa getNTFSmTime() | ||
161 | * @sa getNTFScTime() | ||
162 | * @return The NTFS access time, UTC | ||
163 | */ | ||
164 | QDateTime getNTFSaTime(int *fineTicks = NULL) const; | ||
165 | /// Returns the NTFS creation time | ||
166 | /** | ||
167 | * The getNTFS*Time() functions only work if there is an NTFS extra field | ||
168 | * present. Otherwise, they all return invalid null timestamps. | ||
169 | * @param fineTicks If not NULL, the fractional part of milliseconds returned | ||
170 | * there, measured in 100-nanosecond ticks. Will be set to | ||
171 | * zero if there is no NTFS extra field. | ||
172 | * @sa dateTime | ||
173 | * @sa getNTFSmTime() | ||
174 | * @sa getNTFSaTime() | ||
175 | * @return The NTFS creation time, UTC | ||
176 | */ | ||
177 | QDateTime getNTFScTime(int *fineTicks = NULL) const; | ||
178 | /// Returns the extended modification timestamp | ||
179 | /** | ||
180 | * The getExt*Time() functions only work if there is an extended timestamp | ||
181 | * extra field (ID 0x5455) present. Otherwise, they all return invalid null | ||
182 | * timestamps. | ||
183 | * | ||
184 | * QuaZipFileInfo64 only contains the modification time because it's extracted | ||
185 | * from @ref extra, which contains the global extra field, and access and | ||
186 | * creation time are in the local header which can be accessed through | ||
187 | * @ref QuaZipFile. | ||
188 | * | ||
189 | * @sa dateTime | ||
190 | * @sa QuaZipFile::getExtModTime() | ||
191 | * @sa QuaZipFile::getExtAcTime() | ||
192 | * @sa QuaZipFile::getExtCrTime() | ||
193 | * @return The extended modification time, UTC | ||
194 | */ | ||
195 | QDateTime getExtModTime() const; | ||
196 | /// Checks whether the file is encrypted. | ||
197 | bool isEncrypted() const {return (flags & 1) != 0;} | ||
198 | /// Parses extra field | ||
199 | /** | ||
200 | * The returned hash table contains a list of data blocks for every header ID | ||
201 | * in the provided extra field. The number of data blocks in a hash table value | ||
202 | * equals to the number of occurrences of the appropriate header id. In most cases, | ||
203 | * a block with a specific header ID only occurs once, and therefore the returned | ||
204 | * hash table will contain a list consisting of a single element for that header ID. | ||
205 | * | ||
206 | * @param extraField extra field to parse | ||
207 | * @return header id to list of data block hash | ||
208 | */ | ||
209 | static QuaExtraFieldHash parseExtraField(const QByteArray &extraField); | ||
210 | /// Extracts extended time from the extra field | ||
211 | /** | ||
212 | * Utility function used by various getExt*Time() functions, but can be used directly | ||
213 | * if the extra field is obtained elsewhere (from a third party library, for example). | ||
214 | * | ||
215 | * @param extra the extra field for a file | ||
216 | * @param flag 1 - modification time, 2 - access time, 4 - creation time | ||
217 | * @return the extracted time or null QDateTime if not present | ||
218 | * @sa getExtModTime() | ||
219 | * @sa QuaZipFile::getExtModTime() | ||
220 | * @sa QuaZipFile::getExtAcTime() | ||
221 | * @sa QuaZipFile::getExtCrTime() | ||
222 | */ | ||
223 | static QDateTime getExtTime(const QByteArray &extra, int flag); | ||
224 | }; | ||
225 | |||
226 | #endif | ||
diff --git a/utils/rbutilqt/quazip/quazipnewinfo.cpp b/utils/rbutilqt/quazip/quazipnewinfo.cpp new file mode 100644 index 0000000000..98630e086a --- /dev/null +++ b/utils/rbutilqt/quazip/quazipnewinfo.cpp | |||
@@ -0,0 +1,290 @@ | |||
1 | /* | ||
2 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
3 | |||
4 | This file is part of QuaZIP. | ||
5 | |||
6 | QuaZIP is free software: you can redistribute it and/or modify | ||
7 | it under the terms of the GNU Lesser General Public License as published by | ||
8 | the Free Software Foundation, either version 2.1 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | QuaZIP is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU Lesser General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU Lesser General Public License | ||
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
18 | |||
19 | See COPYING file for the full LGPL text. | ||
20 | |||
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors, | ||
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license. | ||
23 | */ | ||
24 | |||
25 | #include <QtCore/QFileInfo> | ||
26 | |||
27 | #include "quazipnewinfo.h" | ||
28 | |||
29 | #include <string.h> | ||
30 | |||
31 | static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info, | ||
32 | QFile::Permissions perm, bool isDir, bool isSymLink = false) | ||
33 | { | ||
34 | quint32 uPerm = isDir ? 0040000 : 0100000; | ||
35 | |||
36 | if ( isSymLink ) { | ||
37 | #ifdef Q_OS_WIN | ||
38 | uPerm = 0200000; | ||
39 | #else | ||
40 | uPerm = 0120000; | ||
41 | #endif | ||
42 | } | ||
43 | |||
44 | if ((perm & QFile::ReadOwner) != 0) | ||
45 | uPerm |= 0400; | ||
46 | if ((perm & QFile::WriteOwner) != 0) | ||
47 | uPerm |= 0200; | ||
48 | if ((perm & QFile::ExeOwner) != 0) | ||
49 | uPerm |= 0100; | ||
50 | if ((perm & QFile::ReadGroup) != 0) | ||
51 | uPerm |= 0040; | ||
52 | if ((perm & QFile::WriteGroup) != 0) | ||
53 | uPerm |= 0020; | ||
54 | if ((perm & QFile::ExeGroup) != 0) | ||
55 | uPerm |= 0010; | ||
56 | if ((perm & QFile::ReadOther) != 0) | ||
57 | uPerm |= 0004; | ||
58 | if ((perm & QFile::WriteOther) != 0) | ||
59 | uPerm |= 0002; | ||
60 | if ((perm & QFile::ExeOther) != 0) | ||
61 | uPerm |= 0001; | ||
62 | info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16); | ||
63 | } | ||
64 | |||
65 | template<typename FileInfo> | ||
66 | void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing) | ||
67 | { | ||
68 | self.name = existing.name; | ||
69 | self.dateTime = existing.dateTime; | ||
70 | self.internalAttr = existing.internalAttr; | ||
71 | self.externalAttr = existing.externalAttr; | ||
72 | self.comment = existing.comment; | ||
73 | self.extraLocal = existing.extra; | ||
74 | self.extraGlobal = existing.extra; | ||
75 | self.uncompressedSize = existing.uncompressedSize; | ||
76 | } | ||
77 | |||
78 | QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo &existing) | ||
79 | { | ||
80 | QuaZipNewInfo_init(*this, existing); | ||
81 | } | ||
82 | |||
83 | QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo64 &existing) | ||
84 | { | ||
85 | QuaZipNewInfo_init(*this, existing); | ||
86 | } | ||
87 | |||
88 | QuaZipNewInfo::QuaZipNewInfo(const QString& name): | ||
89 | name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0), | ||
90 | uncompressedSize(0) | ||
91 | { | ||
92 | } | ||
93 | |||
94 | QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file): | ||
95 | name(name), internalAttr(0), externalAttr(0), uncompressedSize(0) | ||
96 | { | ||
97 | QFileInfo info(file); | ||
98 | QDateTime lm = info.lastModified(); | ||
99 | if (!info.exists()) { | ||
100 | dateTime = QDateTime::currentDateTime(); | ||
101 | } else { | ||
102 | dateTime = lm; | ||
103 | QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir(), info.isSymLink()); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | void QuaZipNewInfo::setFileDateTime(const QString& file) | ||
108 | { | ||
109 | QFileInfo info(file); | ||
110 | QDateTime lm = info.lastModified(); | ||
111 | if (info.exists()) | ||
112 | dateTime = lm; | ||
113 | } | ||
114 | |||
115 | void QuaZipNewInfo::setFilePermissions(const QString &file) | ||
116 | { | ||
117 | QFileInfo info = QFileInfo(file); | ||
118 | QFile::Permissions perm = info.permissions(); | ||
119 | QuaZipNewInfo_setPermissions(this, perm, info.isDir(), info.isSymLink()); | ||
120 | } | ||
121 | |||
122 | void QuaZipNewInfo::setPermissions(QFile::Permissions permissions) | ||
123 | { | ||
124 | QuaZipNewInfo_setPermissions(this, permissions, name.endsWith(QLatin1String("/"))); | ||
125 | } | ||
126 | |||
127 | void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName) | ||
128 | { | ||
129 | QFileInfo fi(fileName); | ||
130 | if (!fi.exists()) { | ||
131 | qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist", | ||
132 | fileName.toUtf8().constData()); | ||
133 | return; | ||
134 | } | ||
135 | setFileNTFSmTime(fi.lastModified()); | ||
136 | setFileNTFSaTime(fi.lastRead()); | ||
137 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) | ||
138 | setFileNTFScTime(fi.birthTime()); | ||
139 | #else | ||
140 | setFileNTFScTime(fi.created()); | ||
141 | #endif | ||
142 | } | ||
143 | |||
144 | static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position, | ||
145 | int fineTicks) { | ||
146 | int ntfsPos = -1, timesPos = -1; | ||
147 | unsigned ntfsLength = 0, ntfsTimesLength = 0; | ||
148 | for (int i = 0; i <= extra.size() - 4; ) { | ||
149 | unsigned type = static_cast<unsigned>(static_cast<unsigned char>( | ||
150 | extra.at(i))) | ||
151 | | (static_cast<unsigned>(static_cast<unsigned char>( | ||
152 | extra.at(i + 1))) << 8); | ||
153 | i += 2; | ||
154 | unsigned length = static_cast<unsigned>(static_cast<unsigned char>( | ||
155 | extra.at(i))) | ||
156 | | (static_cast<unsigned>(static_cast<unsigned char>( | ||
157 | extra.at(i + 1))) << 8); | ||
158 | i += 2; | ||
159 | if (type == QUAZIP_EXTRA_NTFS_MAGIC) { | ||
160 | ntfsPos = i - 4; // the beginning of the NTFS record | ||
161 | ntfsLength = length; | ||
162 | if (length <= 4) { | ||
163 | break; // no times in the NTFS record | ||
164 | } | ||
165 | i += 4; // reserved | ||
166 | while (i <= extra.size() - 4) { | ||
167 | unsigned tag = static_cast<unsigned>( | ||
168 | static_cast<unsigned char>(extra.at(i))) | ||
169 | | (static_cast<unsigned>( | ||
170 | static_cast<unsigned char>(extra.at(i + 1))) | ||
171 | << 8); | ||
172 | i += 2; | ||
173 | unsigned tagsize = static_cast<unsigned>( | ||
174 | static_cast<unsigned char>(extra.at(i))) | ||
175 | | (static_cast<unsigned>( | ||
176 | static_cast<unsigned char>(extra.at(i + 1))) | ||
177 | << 8); | ||
178 | i += 2; | ||
179 | if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) { | ||
180 | timesPos = i - 4; // the beginning of the NTFS times tag | ||
181 | ntfsTimesLength = tagsize; | ||
182 | break; | ||
183 | } else { | ||
184 | i += tagsize; | ||
185 | } | ||
186 | } | ||
187 | break; // I ain't going to search for yet another NTFS record! | ||
188 | } else { | ||
189 | i += length; | ||
190 | } | ||
191 | } | ||
192 | if (ntfsPos == -1) { | ||
193 | // No NTFS record, need to create one. | ||
194 | ntfsPos = extra.size(); | ||
195 | ntfsLength = 32; | ||
196 | extra.resize(extra.size() + 4 + ntfsLength); | ||
197 | // the NTFS record header | ||
198 | extra[ntfsPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC); | ||
199 | extra[ntfsPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_MAGIC >> 8); | ||
200 | extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian | ||
201 | extra[ntfsPos + 3] = 0; | ||
202 | // zero the record | ||
203 | memset(extra.data() + ntfsPos + 4, 0, 32); | ||
204 | timesPos = ntfsPos + 8; | ||
205 | // now set the tag data | ||
206 | extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC); | ||
207 | extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC | ||
208 | >> 8); | ||
209 | // the size: | ||
210 | extra[timesPos + 2] = 24; | ||
211 | extra[timesPos + 3] = 0; | ||
212 | ntfsTimesLength = 24; | ||
213 | } | ||
214 | if (timesPos == -1) { | ||
215 | // No time tag in the NTFS record, need to add one. | ||
216 | timesPos = ntfsPos + 4 + ntfsLength; | ||
217 | extra.resize(extra.size() + 28); | ||
218 | // Now we need to move the rest of the field | ||
219 | // (possibly zero bytes, but memmove() is OK with that). | ||
220 | // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos | ||
221 | // <some data> <header> <NTFS record> <need-to-move data> <end> | ||
222 | memmove(extra.data() + timesPos + 28, extra.data() + timesPos, | ||
223 | extra.size() - 28 - timesPos); | ||
224 | ntfsLength += 28; | ||
225 | // now set the tag data | ||
226 | extra[timesPos] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC); | ||
227 | extra[timesPos + 1] = static_cast<char>(QUAZIP_EXTRA_NTFS_TIME_MAGIC | ||
228 | >> 8); | ||
229 | // the size: | ||
230 | extra[timesPos + 2] = 24; | ||
231 | extra[timesPos + 3] = 0; | ||
232 | // zero the record | ||
233 | memset(extra.data() + timesPos + 4, 0, 24); | ||
234 | ntfsTimesLength = 24; | ||
235 | } | ||
236 | if (ntfsTimesLength < 24) { | ||
237 | // Broken times field. OK, this is really unlikely, but just in case... | ||
238 | size_t timesEnd = timesPos + 4 + ntfsTimesLength; | ||
239 | extra.resize(extra.size() + (24 - ntfsTimesLength)); | ||
240 | // Move it! | ||
241 | // 0 ......... timesPos .... timesPos + 4 .. timesEnd | ||
242 | // <some data> <time header> <broken times> <need-to-move data> <end> | ||
243 | memmove(extra.data() + timesEnd + (24 - ntfsTimesLength), | ||
244 | extra.data() + timesEnd, | ||
245 | extra.size() - (24 - ntfsTimesLength) - timesEnd); | ||
246 | // Now we have to increase the NTFS record and time tag lengths. | ||
247 | ntfsLength += (24 - ntfsTimesLength); | ||
248 | ntfsTimesLength = 24; | ||
249 | extra[ntfsPos + 2] = static_cast<char>(ntfsLength); | ||
250 | extra[ntfsPos + 3] = static_cast<char>(ntfsLength >> 8); | ||
251 | extra[timesPos + 2] = static_cast<char>(ntfsTimesLength); | ||
252 | extra[timesPos + 3] = static_cast<char>(ntfsTimesLength >> 8); | ||
253 | } | ||
254 | QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC); | ||
255 | #if (QT_VERSION >= 0x040700) | ||
256 | quint64 ticks = base.msecsTo(time) * 10000 + fineTicks; | ||
257 | #else | ||
258 | QDateTime utc = time.toUTC(); | ||
259 | quint64 ticks = (static_cast<qint64>(base.date().daysTo(utc.date())) | ||
260 | * Q_INT64_C(86400000) | ||
261 | + static_cast<qint64>(base.time().msecsTo(utc.time()))) | ||
262 | * Q_INT64_C(10000) + fineTicks; | ||
263 | #endif | ||
264 | extra[timesPos + 4 + position] = static_cast<char>(ticks); | ||
265 | extra[timesPos + 5 + position] = static_cast<char>(ticks >> 8); | ||
266 | extra[timesPos + 6 + position] = static_cast<char>(ticks >> 16); | ||
267 | extra[timesPos + 7 + position] = static_cast<char>(ticks >> 24); | ||
268 | extra[timesPos + 8 + position] = static_cast<char>(ticks >> 32); | ||
269 | extra[timesPos + 9 + position] = static_cast<char>(ticks >> 40); | ||
270 | extra[timesPos + 10 + position] = static_cast<char>(ticks >> 48); | ||
271 | extra[timesPos + 11 + position] = static_cast<char>(ticks >> 56); | ||
272 | } | ||
273 | |||
274 | void QuaZipNewInfo::setFileNTFSmTime(const QDateTime &mTime, int fineTicks) | ||
275 | { | ||
276 | setNTFSTime(extraLocal, mTime, 0, fineTicks); | ||
277 | setNTFSTime(extraGlobal, mTime, 0, fineTicks); | ||
278 | } | ||
279 | |||
280 | void QuaZipNewInfo::setFileNTFSaTime(const QDateTime &aTime, int fineTicks) | ||
281 | { | ||
282 | setNTFSTime(extraLocal, aTime, 8, fineTicks); | ||
283 | setNTFSTime(extraGlobal, aTime, 8, fineTicks); | ||
284 | } | ||
285 | |||
286 | void QuaZipNewInfo::setFileNTFScTime(const QDateTime &cTime, int fineTicks) | ||
287 | { | ||
288 | setNTFSTime(extraLocal, cTime, 16, fineTicks); | ||
289 | setNTFSTime(extraGlobal, cTime, 16, fineTicks); | ||
290 | } | ||
diff --git a/utils/rbutilqt/quazip/quazipnewinfo.h b/utils/rbutilqt/quazip/quazipnewinfo.h new file mode 100644 index 0000000000..43a1e6fd08 --- /dev/null +++ b/utils/rbutilqt/quazip/quazipnewinfo.h | |||
@@ -0,0 +1,208 @@ | |||
1 | #ifndef QUA_ZIPNEWINFO_H | ||
2 | #define QUA_ZIPNEWINFO_H | ||
3 | |||
4 | /* | ||
5 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
6 | |||
7 | This file is part of QuaZIP. | ||
8 | |||
9 | QuaZIP is free software: you can redistribute it and/or modify | ||
10 | it under the terms of the GNU Lesser General Public License as published by | ||
11 | the Free Software Foundation, either version 2.1 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | QuaZIP is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU Lesser General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU Lesser General Public License | ||
20 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. | ||
21 | |||
22 | See COPYING file for the full LGPL text. | ||
23 | |||
24 | Original ZIP package is copyrighted by Gilles Vollant, see | ||
25 | quazip/(un)zip.h files for details, basically it's zlib license. | ||
26 | **/ | ||
27 | |||
28 | #include <QtCore/QDateTime> | ||
29 | #include <QtCore/QFile> | ||
30 | #include <QtCore/QString> | ||
31 | |||
32 | #include "quazip_global.h" | ||
33 | |||
34 | #include "quazipfileinfo.h" | ||
35 | |||
36 | /// Information about a file to be created. | ||
37 | /** This structure holds information about a file to be created inside | ||
38 | * ZIP archive. At least name should be set to something correct before | ||
39 | * passing this structure to | ||
40 | * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool). | ||
41 | * | ||
42 | * Zip64 support of this structure is slightly limited: in the raw mode (when | ||
43 | * a pre-compressed file is written into a ZIP file as-is), it is necessary | ||
44 | * to specify the uncompressed file size and the appropriate field is 32 bit. | ||
45 | * Since the raw mode is used extremely rare, there is no real need to have | ||
46 | * a separate QuaZipNewInfo64 structure like QuaZipFileInfo64. It may be added | ||
47 | * in the future though, if there is a demand for the raw mode with zip64 | ||
48 | * archives. | ||
49 | **/ | ||
50 | struct QUAZIP_EXPORT QuaZipNewInfo { | ||
51 | /// File name. | ||
52 | /** This field holds file name inside archive, including path relative | ||
53 | * to archive root. | ||
54 | **/ | ||
55 | QString name; | ||
56 | /// File timestamp. | ||
57 | /** This is the last file modification date and time. Will be stored | ||
58 | * in the archive central directory. It is a good practice to set it | ||
59 | * to the source file timestamp instead of archive creating time. Use | ||
60 | * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&). | ||
61 | **/ | ||
62 | QDateTime dateTime; | ||
63 | /// File internal attributes. | ||
64 | quint16 internalAttr; | ||
65 | /// File external attributes. | ||
66 | /** | ||
67 | The highest 16 bits contain Unix file permissions and type (dir or | ||
68 | file). The constructor QuaZipNewInfo(const QString&, const QString&) | ||
69 | takes permissions from the provided file. | ||
70 | */ | ||
71 | quint32 externalAttr; | ||
72 | /// File comment. | ||
73 | /** Will be encoded in UTF-8 encoding. | ||
74 | **/ | ||
75 | QString comment; | ||
76 | /// File local extra field. | ||
77 | QByteArray extraLocal; | ||
78 | /// File global extra field. | ||
79 | QByteArray extraGlobal; | ||
80 | /// Uncompressed file size. | ||
81 | /** This is only needed if you are using raw file zipping mode, i. e. | ||
82 | * adding precompressed file in the zip archive. | ||
83 | **/ | ||
84 | ulong uncompressedSize; | ||
85 | /// Constructs QuaZipNewInfo instance. | ||
86 | /** Initializes name with \a name, dateTime with current date and | ||
87 | * time. Attributes are initialized with zeros, comment and extra | ||
88 | * field with null values. | ||
89 | **/ | ||
90 | QuaZipNewInfo(const QString& name); | ||
91 | /// Constructs QuaZipNewInfo instance. | ||
92 | /** Initializes name with \a name. Timestamp and permissions are taken | ||
93 | * from the specified file. If the \a file does not exists or its timestamp | ||
94 | * is inaccessible (e. g. you do not have read permission for the | ||
95 | * directory file in), uses current time and zero permissions. Other attributes are | ||
96 | * initialized with zeros, comment and extra field with null values. | ||
97 | * | ||
98 | * \sa setFileDateTime() | ||
99 | **/ | ||
100 | QuaZipNewInfo(const QString& name, const QString& file); | ||
101 | /// Initializes the new instance from existing file info. | ||
102 | /** Mainly used when copying files between archives. | ||
103 | * | ||
104 | * Both extra fields are initialized to existing.extra. | ||
105 | * @brief QuaZipNewInfo | ||
106 | * @param existing | ||
107 | */ | ||
108 | QuaZipNewInfo(const QuaZipFileInfo &existing); | ||
109 | /// Initializes the new instance from existing file info. | ||
110 | /** Mainly used when copying files between archives. | ||
111 | * | ||
112 | * Both extra fields are initialized to existing.extra. | ||
113 | * @brief QuaZipNewInfo | ||
114 | * @param existing | ||
115 | */ | ||
116 | QuaZipNewInfo(const QuaZipFileInfo64 &existing); | ||
117 | /// Sets the file timestamp from the existing file. | ||
118 | /** Use this function to set the file timestamp from the existing | ||
119 | * file. Use it like this: | ||
120 | * \code | ||
121 | * QuaZipFile zipFile(&zip); | ||
122 | * QFile file("file-to-add"); | ||
123 | * file.open(QIODevice::ReadOnly); | ||
124 | * QuaZipNewInfo info("file-name-in-archive"); | ||
125 | * info.setFileDateTime("file-to-add"); // take the timestamp from file | ||
126 | * zipFile.open(QIODevice::WriteOnly, info); | ||
127 | * \endcode | ||
128 | * | ||
129 | * This function does not change dateTime if some error occured (e. g. | ||
130 | * file is inaccessible). | ||
131 | **/ | ||
132 | void setFileDateTime(const QString& file); | ||
133 | /// Sets the file permissions from the existing file. | ||
134 | /** | ||
135 | Takes permissions from the file and sets the high 16 bits of | ||
136 | external attributes. Uses QFileInfo to get permissions on all | ||
137 | platforms. | ||
138 | */ | ||
139 | void setFilePermissions(const QString &file); | ||
140 | /// Sets the file permissions. | ||
141 | /** | ||
142 | Modifies the highest 16 bits of external attributes. The type part | ||
143 | is set to dir if the name ends with a slash, and to regular file | ||
144 | otherwise. | ||
145 | */ | ||
146 | void setPermissions(QFile::Permissions permissions); | ||
147 | /// Sets the NTFS times from an existing file. | ||
148 | /** | ||
149 | * If the file doesn't exist, a warning is printed to the stderr and nothing | ||
150 | * is done. Otherwise, all three times, as reported by | ||
151 | * QFileInfo::lastModified(), QFileInfo::lastRead() and | ||
152 | * QFileInfo::birthTime() (>=Qt5.10) or QFileInfo::created(), are written to | ||
153 | * the NTFS extra field record. | ||
154 | * | ||
155 | * The NTFS record is written to | ||
156 | * both the local and the global extra fields, updating the existing record | ||
157 | * if there is one, or creating a new one and appending it to the end | ||
158 | * of each extra field. | ||
159 | * | ||
160 | * The microseconds will be zero, as they aren't reported by QFileInfo. | ||
161 | * @param fileName | ||
162 | */ | ||
163 | void setFileNTFSTimes(const QString &fileName); | ||
164 | /// Sets the NTFS modification time. | ||
165 | /** | ||
166 | * The time is written into the NTFS record in | ||
167 | * both the local and the global extra fields, updating the existing record | ||
168 | * if there is one, or creating a new one and appending it to the end | ||
169 | * of each extra field. When updating an existing record, all other fields | ||
170 | * are left intact. | ||
171 | * @param mTime The new modification time. | ||
172 | * @param fineTicks The fractional part of milliseconds, in 100-nanosecond | ||
173 | * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than | ||
174 | * 9999 will add milliseconds or even seconds, but this can be | ||
175 | * confusing and therefore is discouraged. | ||
176 | */ | ||
177 | void setFileNTFSmTime(const QDateTime &mTime, int fineTicks = 0); | ||
178 | /// Sets the NTFS access time. | ||
179 | /** | ||
180 | * The time is written into the NTFS record in | ||
181 | * both the local and the global extra fields, updating the existing record | ||
182 | * if there is one, or creating a new one and appending it to the end | ||
183 | * of each extra field. When updating an existing record, all other fields | ||
184 | * are left intact. | ||
185 | * @param aTime The new access time. | ||
186 | * @param fineTicks The fractional part of milliseconds, in 100-nanosecond | ||
187 | * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than | ||
188 | * 9999 will add milliseconds or even seconds, but this can be | ||
189 | * confusing and therefore is discouraged. | ||
190 | */ | ||
191 | void setFileNTFSaTime(const QDateTime &aTime, int fineTicks = 0); | ||
192 | /// Sets the NTFS creation time. | ||
193 | /** | ||
194 | * The time is written into the NTFS record in | ||
195 | * both the local and the global extra fields, updating the existing record | ||
196 | * if there is one, or creating a new one and appending it to the end | ||
197 | * of each extra field. When updating an existing record, all other fields | ||
198 | * are left intact. | ||
199 | * @param cTime The new creation time. | ||
200 | * @param fineTicks The fractional part of milliseconds, in 100-nanosecond | ||
201 | * ticks (i. e. 9999 ticks = 999.9 microsecond). Values greater than | ||
202 | * 9999 will add milliseconds or even seconds, but this can be | ||
203 | * confusing and therefore is discouraged. | ||
204 | */ | ||
205 | void setFileNTFScTime(const QDateTime &cTime, int fineTicks = 0); | ||
206 | }; | ||
207 | |||
208 | #endif | ||
diff --git a/utils/rbutilqt/quazip/unzip.c b/utils/rbutilqt/quazip/unzip.c new file mode 100644 index 0000000000..6aaeba6930 --- /dev/null +++ b/utils/rbutilqt/quazip/unzip.c | |||
@@ -0,0 +1,2163 @@ | |||
1 | /* unzip.c -- IO for uncompress .zip files using zlib | ||
2 | Version 1.1, February 14h, 2010 | ||
3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | ||
4 | |||
5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) | ||
6 | |||
7 | Modifications of Unzip for Zip64 | ||
8 | Copyright (C) 2007-2008 Even Rouault | ||
9 | |||
10 | Modifications for Zip64 support on both zip and unzip | ||
11 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | ||
12 | |||
13 | Modifications for QIODevice support and other QuaZIP fixes | ||
14 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
15 | |||
16 | For more info read MiniZip_info.txt | ||
17 | |||
18 | Modifications for static code analysis report | ||
19 | Copyright (C) 2016 Intel Deutschland GmbH | ||
20 | |||
21 | ------------------------------------------------------------------------------------ | ||
22 | Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of | ||
23 | compatibility with older software. The following is from the original crypt.c. | ||
24 | Code woven in by Terry Thorsen 1/2003. | ||
25 | |||
26 | Copyright (c) 1990-2000 Info-ZIP. All rights reserved. | ||
27 | |||
28 | See the accompanying file LICENSE, version 2000-Apr-09 or later | ||
29 | (the contents of which are also included in zip.h) for terms of use. | ||
30 | If, for some reason, all these files are missing, the Info-ZIP license | ||
31 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html | ||
32 | |||
33 | crypt.c (full version) by Info-ZIP. Last revised: [see minizip_crypt.h] | ||
34 | |||
35 | The encryption/decryption parts of this source code (as opposed to the | ||
36 | non-echoing password parts) were originally written in Europe. The | ||
37 | whole source package can be freely distributed, including from the USA. | ||
38 | (Prior to January 2000, re-export from the US was a violation of US law.) | ||
39 | |||
40 | This encryption code is a direct transcription of the algorithm from | ||
41 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This | ||
42 | file (appnote.txt) is distributed with the PKZIP program (even in the | ||
43 | version without encryption capabilities). | ||
44 | |||
45 | ------------------------------------------------------------------------------------ | ||
46 | |||
47 | Changes in unzip.c | ||
48 | |||
49 | 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos | ||
50 | 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* | ||
51 | 2007-2008 - Even Rouault - Remove old C style function prototypes | ||
52 | 2007-2008 - Even Rouault - Add unzip support for ZIP64 | ||
53 | |||
54 | Copyright (C) 2007-2008 Even Rouault | ||
55 | |||
56 | |||
57 | Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). | ||
58 | Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G | ||
59 | should only read the compressed/uncompressed size from the Zip64 format if | ||
60 | the size from normal header was 0xFFFFFFFF | ||
61 | Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant | ||
62 | Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) | ||
63 | Patch created by Daniel Borca | ||
64 | |||
65 | Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer | ||
66 | |||
67 | Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson | ||
68 | |||
69 | */ | ||
70 | |||
71 | |||
72 | #include <stdio.h> | ||
73 | #include <stdlib.h> | ||
74 | #include <string.h> | ||
75 | |||
76 | #include <zlib.h> | ||
77 | #if (ZLIB_VERNUM < 0x1270) | ||
78 | typedef uLongf z_crc_t; | ||
79 | #endif | ||
80 | #include "unzip.h" | ||
81 | |||
82 | #ifdef STDC | ||
83 | # include <stddef.h> | ||
84 | # include <string.h> | ||
85 | # include <stdlib.h> | ||
86 | #endif | ||
87 | #ifdef NO_ERRNO_H | ||
88 | extern int errno; | ||
89 | #else | ||
90 | # include <errno.h> | ||
91 | #endif | ||
92 | |||
93 | |||
94 | #ifndef local | ||
95 | # define local static | ||
96 | #endif | ||
97 | /* compile with -Dlocal if your debugger can't find static symbols */ | ||
98 | |||
99 | |||
100 | #ifndef CASESENSITIVITYDEFAULT_NO | ||
101 | # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) | ||
102 | # define CASESENSITIVITYDEFAULT_NO | ||
103 | # endif | ||
104 | #endif | ||
105 | |||
106 | |||
107 | #ifndef UNZ_BUFSIZE | ||
108 | #define UNZ_BUFSIZE (16384) | ||
109 | #endif | ||
110 | |||
111 | #ifndef UNZ_MAXFILENAMEINZIP | ||
112 | #define UNZ_MAXFILENAMEINZIP (256) | ||
113 | #endif | ||
114 | |||
115 | #ifndef ALLOC | ||
116 | # define ALLOC(size) (malloc(size)) | ||
117 | #endif | ||
118 | #ifndef TRYFREE | ||
119 | # define TRYFREE(p) {if (p) free(p);} | ||
120 | #endif | ||
121 | |||
122 | #define SIZECENTRALDIRITEM (0x2e) | ||
123 | #define SIZEZIPLOCALHEADER (0x1e) | ||
124 | |||
125 | |||
126 | const char unz_copyright[] = | ||
127 | " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; | ||
128 | |||
129 | /* unz_file_info_interntal contain internal info about a file in zipfile*/ | ||
130 | typedef struct unz_file_info64_internal_s | ||
131 | { | ||
132 | ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ | ||
133 | } unz_file_info64_internal; | ||
134 | |||
135 | |||
136 | /* file_in_zip_read_info_s contain internal information about a file in zipfile, | ||
137 | when reading and decompress it */ | ||
138 | typedef struct | ||
139 | { | ||
140 | char *read_buffer; /* internal buffer for compressed data */ | ||
141 | z_stream stream; /* zLib stream structure for inflate */ | ||
142 | |||
143 | #ifdef HAVE_BZIP2 | ||
144 | bz_stream bstream; /* bzLib stream structure for bziped */ | ||
145 | #endif | ||
146 | |||
147 | ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ | ||
148 | uLong stream_initialised; /* flag set if stream structure is initialised*/ | ||
149 | |||
150 | ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ | ||
151 | uInt size_local_extrafield;/* size of the local extra field */ | ||
152 | ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ | ||
153 | ZPOS64_T total_out_64; | ||
154 | |||
155 | uLong crc32; /* crc32 of all data uncompressed */ | ||
156 | uLong crc32_wait; /* crc32 we must obtain after decompress all */ | ||
157 | ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ | ||
158 | ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ | ||
159 | zlib_filefunc64_32_def z_filefunc; | ||
160 | voidpf filestream; /* io structore of the zipfile */ | ||
161 | uLong compression_method; /* compression method (0==store) */ | ||
162 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | ||
163 | int raw; | ||
164 | } file_in_zip64_read_info_s; | ||
165 | |||
166 | |||
167 | /* unz64_s contain internal information about the zipfile | ||
168 | */ | ||
169 | typedef struct | ||
170 | { | ||
171 | zlib_filefunc64_32_def z_filefunc; | ||
172 | int is64bitOpenFunction; | ||
173 | voidpf filestream; /* io structore of the zipfile */ | ||
174 | unz_global_info64 gi; /* public global information */ | ||
175 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | ||
176 | ZPOS64_T num_file; /* number of the current file in the zipfile*/ | ||
177 | ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ | ||
178 | ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ | ||
179 | ZPOS64_T central_pos; /* position of the beginning of the central dir*/ | ||
180 | |||
181 | ZPOS64_T size_central_dir; /* size of the central directory */ | ||
182 | ZPOS64_T offset_central_dir; /* offset of start of central directory with | ||
183 | respect to the starting disk number */ | ||
184 | |||
185 | unz_file_info64 cur_file_info; /* public info about the current file in zip*/ | ||
186 | unz_file_info64_internal cur_file_info_internal; /* private info about it*/ | ||
187 | file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current | ||
188 | file if we are decompressing it */ | ||
189 | int encrypted; | ||
190 | |||
191 | int isZip64; | ||
192 | unsigned flags; | ||
193 | |||
194 | # ifndef NOUNCRYPT | ||
195 | unsigned long keys[3]; /* keys defining the pseudo-random sequence */ | ||
196 | const z_crc_t FAR * pcrc_32_tab; | ||
197 | # endif | ||
198 | } unz64_s; | ||
199 | |||
200 | |||
201 | #ifndef NOUNCRYPT | ||
202 | #include "minizip_crypt.h" | ||
203 | #endif | ||
204 | |||
205 | /* =========================================================================== | ||
206 | Read a byte from a gz_stream; update next_in and avail_in. Return EOF | ||
207 | for end of file. | ||
208 | IN assertion: the stream s has been sucessfully opened for reading. | ||
209 | */ | ||
210 | |||
211 | |||
212 | local int unz64local_getByte OF(( | ||
213 | const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
214 | voidpf filestream, | ||
215 | int *pi)); | ||
216 | |||
217 | local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) | ||
218 | { | ||
219 | unsigned char c; | ||
220 | int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); | ||
221 | if (err==1) | ||
222 | { | ||
223 | *pi = (int)c; | ||
224 | return UNZ_OK; | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | if (ZERROR64(*pzlib_filefunc_def,filestream)) | ||
229 | return UNZ_ERRNO; | ||
230 | else | ||
231 | return UNZ_EOF; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | |||
236 | /* =========================================================================== | ||
237 | Reads a long in LSB order from the given gz_stream. Sets | ||
238 | */ | ||
239 | local int unz64local_getShort OF(( | ||
240 | const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
241 | voidpf filestream, | ||
242 | uLong *pX)); | ||
243 | |||
244 | local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
245 | voidpf filestream, | ||
246 | uLong *pX) | ||
247 | { | ||
248 | uLong x ; | ||
249 | int i = 0; | ||
250 | int err; | ||
251 | |||
252 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
253 | x = (uLong)i; | ||
254 | |||
255 | if (err==UNZ_OK) | ||
256 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
257 | x |= ((uLong)i)<<8; | ||
258 | |||
259 | if (err==UNZ_OK) | ||
260 | *pX = x; | ||
261 | else | ||
262 | *pX = 0; | ||
263 | return err; | ||
264 | } | ||
265 | |||
266 | local int unz64local_getLong OF(( | ||
267 | const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
268 | voidpf filestream, | ||
269 | uLong *pX)); | ||
270 | |||
271 | local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
272 | voidpf filestream, | ||
273 | uLong *pX) | ||
274 | { | ||
275 | uLong x ; | ||
276 | int i = 0; | ||
277 | int err; | ||
278 | |||
279 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
280 | x = (uLong)i; | ||
281 | |||
282 | if (err==UNZ_OK) | ||
283 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
284 | x |= ((uLong)i)<<8; | ||
285 | |||
286 | if (err==UNZ_OK) | ||
287 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
288 | x |= ((uLong)i)<<16; | ||
289 | |||
290 | if (err==UNZ_OK) | ||
291 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
292 | x += ((uLong)i)<<24; | ||
293 | |||
294 | if (err==UNZ_OK) | ||
295 | *pX = x; | ||
296 | else | ||
297 | *pX = 0; | ||
298 | return err; | ||
299 | } | ||
300 | |||
301 | local int unz64local_getLong64 OF(( | ||
302 | const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
303 | voidpf filestream, | ||
304 | ZPOS64_T *pX)); | ||
305 | |||
306 | |||
307 | local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
308 | voidpf filestream, | ||
309 | ZPOS64_T *pX) | ||
310 | { | ||
311 | ZPOS64_T x ; | ||
312 | int i = 0; | ||
313 | int err; | ||
314 | |||
315 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
316 | x = (ZPOS64_T)i; | ||
317 | |||
318 | if (err==UNZ_OK) | ||
319 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
320 | x |= ((ZPOS64_T)i)<<8; | ||
321 | |||
322 | if (err==UNZ_OK) | ||
323 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
324 | x |= ((ZPOS64_T)i)<<16; | ||
325 | |||
326 | if (err==UNZ_OK) | ||
327 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
328 | x |= ((ZPOS64_T)i)<<24; | ||
329 | |||
330 | if (err==UNZ_OK) | ||
331 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
332 | x |= ((ZPOS64_T)i)<<32; | ||
333 | |||
334 | if (err==UNZ_OK) | ||
335 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
336 | x |= ((ZPOS64_T)i)<<40; | ||
337 | |||
338 | if (err==UNZ_OK) | ||
339 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
340 | x |= ((ZPOS64_T)i)<<48; | ||
341 | |||
342 | if (err==UNZ_OK) | ||
343 | err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
344 | x |= ((ZPOS64_T)i)<<56; | ||
345 | |||
346 | if (err==UNZ_OK) | ||
347 | *pX = x; | ||
348 | else | ||
349 | *pX = 0; | ||
350 | return err; | ||
351 | } | ||
352 | |||
353 | /* My own strcmpi / strcasecmp */ | ||
354 | local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) | ||
355 | { | ||
356 | for (;;) | ||
357 | { | ||
358 | char c1=*(fileName1++); | ||
359 | char c2=*(fileName2++); | ||
360 | if ((c1>='a') && (c1<='z')) | ||
361 | c1 -= 0x20; | ||
362 | if ((c2>='a') && (c2<='z')) | ||
363 | c2 -= 0x20; | ||
364 | if (c1=='\0') | ||
365 | return ((c2=='\0') ? 0 : -1); | ||
366 | if (c2=='\0') | ||
367 | return 1; | ||
368 | if (c1<c2) | ||
369 | return -1; | ||
370 | if (c1>c2) | ||
371 | return 1; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | |||
376 | #ifdef CASESENSITIVITYDEFAULT_NO | ||
377 | #define CASESENSITIVITYDEFAULTVALUE 2 | ||
378 | #else | ||
379 | #define CASESENSITIVITYDEFAULTVALUE 1 | ||
380 | #endif | ||
381 | |||
382 | #ifndef STRCMPCASENOSENTIVEFUNCTION | ||
383 | #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal | ||
384 | #endif | ||
385 | |||
386 | /* | ||
387 | Compare two filename (fileName1,fileName2). | ||
388 | If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) | ||
389 | If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi | ||
390 | or strcasecmp) | ||
391 | If iCaseSenisivity = 0, case sensitivity is defaut of your operating system | ||
392 | (like 1 on Unix, 2 on Windows) | ||
393 | |||
394 | */ | ||
395 | extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, | ||
396 | const char* fileName2, | ||
397 | int iCaseSensitivity) | ||
398 | |||
399 | { | ||
400 | if (iCaseSensitivity==0) | ||
401 | iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; | ||
402 | |||
403 | if (iCaseSensitivity==1) | ||
404 | return strcmp(fileName1,fileName2); | ||
405 | |||
406 | return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); | ||
407 | } | ||
408 | |||
409 | #ifndef BUFREADCOMMENT | ||
410 | #define BUFREADCOMMENT (0x400) | ||
411 | #endif | ||
412 | |||
413 | /* | ||
414 | Locate the Central directory of a zipfile (at the end, just before | ||
415 | the global comment) | ||
416 | */ | ||
417 | local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); | ||
418 | local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) | ||
419 | { | ||
420 | unsigned char* buf; | ||
421 | ZPOS64_T uSizeFile; | ||
422 | ZPOS64_T uBackRead; | ||
423 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | ||
424 | ZPOS64_T uPosFound=0; | ||
425 | |||
426 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | ||
427 | return 0; | ||
428 | |||
429 | |||
430 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | ||
431 | |||
432 | if (uMaxBack>uSizeFile) | ||
433 | uMaxBack = uSizeFile; | ||
434 | |||
435 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | ||
436 | if (buf==NULL) | ||
437 | return 0; | ||
438 | |||
439 | uBackRead = 4; | ||
440 | while (uBackRead<uMaxBack) | ||
441 | { | ||
442 | uLong uReadSize; | ||
443 | ZPOS64_T uReadPos ; | ||
444 | int i; | ||
445 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | ||
446 | uBackRead = uMaxBack; | ||
447 | else | ||
448 | uBackRead+=BUFREADCOMMENT; | ||
449 | uReadPos = uSizeFile-uBackRead ; | ||
450 | |||
451 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | ||
452 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | ||
453 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
454 | break; | ||
455 | |||
456 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | ||
457 | break; | ||
458 | |||
459 | for (i=(int)uReadSize-3; (i--)>0;) | ||
460 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | ||
461 | ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) | ||
462 | { | ||
463 | uPosFound = uReadPos+i; | ||
464 | break; | ||
465 | } | ||
466 | |||
467 | if (uPosFound!=0) | ||
468 | break; | ||
469 | } | ||
470 | TRYFREE(buf); | ||
471 | return uPosFound; | ||
472 | } | ||
473 | |||
474 | |||
475 | /* | ||
476 | Locate the Central directory 64 of a zipfile (at the end, just before | ||
477 | the global comment) | ||
478 | */ | ||
479 | local ZPOS64_T unz64local_SearchCentralDir64 OF(( | ||
480 | const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
481 | voidpf filestream)); | ||
482 | |||
483 | local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, | ||
484 | voidpf filestream) | ||
485 | { | ||
486 | unsigned char* buf; | ||
487 | ZPOS64_T uSizeFile; | ||
488 | ZPOS64_T uBackRead; | ||
489 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | ||
490 | ZPOS64_T uPosFound=0; | ||
491 | uLong uL; | ||
492 | ZPOS64_T relativeOffset; | ||
493 | |||
494 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | ||
495 | return 0; | ||
496 | |||
497 | |||
498 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | ||
499 | |||
500 | if (uMaxBack>uSizeFile) | ||
501 | uMaxBack = uSizeFile; | ||
502 | |||
503 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | ||
504 | if (buf==NULL) | ||
505 | return 0; | ||
506 | |||
507 | uBackRead = 4; | ||
508 | while (uBackRead<uMaxBack) | ||
509 | { | ||
510 | uLong uReadSize; | ||
511 | ZPOS64_T uReadPos; | ||
512 | int i; | ||
513 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | ||
514 | uBackRead = uMaxBack; | ||
515 | else | ||
516 | uBackRead+=BUFREADCOMMENT; | ||
517 | uReadPos = uSizeFile-uBackRead ; | ||
518 | |||
519 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | ||
520 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | ||
521 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
522 | break; | ||
523 | |||
524 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | ||
525 | break; | ||
526 | |||
527 | for (i=(int)uReadSize-3; (i--)>0;) | ||
528 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | ||
529 | ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) | ||
530 | { | ||
531 | uPosFound = uReadPos+i; | ||
532 | break; | ||
533 | } | ||
534 | |||
535 | if (uPosFound!=0) | ||
536 | break; | ||
537 | } | ||
538 | TRYFREE(buf); | ||
539 | if (uPosFound == 0) | ||
540 | return 0; | ||
541 | |||
542 | /* Zip64 end of central directory locator */ | ||
543 | if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
544 | return 0; | ||
545 | |||
546 | /* the signature, already checked */ | ||
547 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | ||
548 | return 0; | ||
549 | |||
550 | /* number of the disk with the start of the zip64 end of central directory */ | ||
551 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | ||
552 | return 0; | ||
553 | if (uL != 0) | ||
554 | return 0; | ||
555 | |||
556 | /* relative offset of the zip64 end of central directory record */ | ||
557 | if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) | ||
558 | return 0; | ||
559 | |||
560 | /* total number of disks */ | ||
561 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | ||
562 | return 0; | ||
563 | if (uL != 1) | ||
564 | return 0; | ||
565 | |||
566 | /* Goto end of central directory record */ | ||
567 | if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
568 | return 0; | ||
569 | |||
570 | /* the signature */ | ||
571 | if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) | ||
572 | return 0; | ||
573 | |||
574 | if (uL != 0x06064b50) | ||
575 | return 0; | ||
576 | |||
577 | return relativeOffset; | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | Open a Zip file. path contain the full pathname (by example, | ||
582 | on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer | ||
583 | "zlib/zlib114.zip". | ||
584 | If the zipfile cannot be opened (file doesn't exist or in not valid), the | ||
585 | return value is NULL. | ||
586 | Else, the return value is a unzFile Handle, usable with other function | ||
587 | of this unzip package. | ||
588 | */ | ||
589 | extern unzFile unzOpenInternal (voidpf file, | ||
590 | zlib_filefunc64_32_def* pzlib_filefunc64_32_def, | ||
591 | int is64bitOpenFunction, unsigned flags) | ||
592 | { | ||
593 | unz64_s us; | ||
594 | unz64_s *s; | ||
595 | ZPOS64_T central_pos; | ||
596 | uLong uL; | ||
597 | |||
598 | uLong number_disk; /* number of the current dist, used for | ||
599 | spaning ZIP, unsupported, always 0*/ | ||
600 | uLong number_disk_with_CD; /* number the the disk with central dir, used | ||
601 | for spaning ZIP, unsupported, always 0*/ | ||
602 | ZPOS64_T number_entry_CD; /* total number of entries in | ||
603 | the central dir | ||
604 | (same than number_entry on nospan) */ | ||
605 | |||
606 | int err=UNZ_OK; | ||
607 | |||
608 | if (unz_copyright[0]!=' ') | ||
609 | return NULL; | ||
610 | |||
611 | us.flags = flags; | ||
612 | us.z_filefunc.zseek32_file = NULL; | ||
613 | us.z_filefunc.ztell32_file = NULL; | ||
614 | if (pzlib_filefunc64_32_def==NULL) | ||
615 | fill_qiodevice64_filefunc(&us.z_filefunc.zfile_func64); | ||
616 | else | ||
617 | us.z_filefunc = *pzlib_filefunc64_32_def; | ||
618 | us.is64bitOpenFunction = is64bitOpenFunction; | ||
619 | |||
620 | |||
621 | |||
622 | us.filestream = ZOPEN64(us.z_filefunc, | ||
623 | file, | ||
624 | ZLIB_FILEFUNC_MODE_READ | | ||
625 | ZLIB_FILEFUNC_MODE_EXISTING); | ||
626 | if (us.filestream==NULL) | ||
627 | return NULL; | ||
628 | |||
629 | central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); | ||
630 | if (central_pos) | ||
631 | { | ||
632 | uLong uS; | ||
633 | ZPOS64_T uL64; | ||
634 | |||
635 | us.isZip64 = 1; | ||
636 | |||
637 | if (ZSEEK64(us.z_filefunc, us.filestream, | ||
638 | central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
639 | err=UNZ_ERRNO; | ||
640 | |||
641 | /* the signature, already checked */ | ||
642 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | ||
643 | err=UNZ_ERRNO; | ||
644 | |||
645 | /* size of zip64 end of central directory record */ | ||
646 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) | ||
647 | err=UNZ_ERRNO; | ||
648 | |||
649 | /* version made by */ | ||
650 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) | ||
651 | err=UNZ_ERRNO; | ||
652 | |||
653 | /* version needed to extract */ | ||
654 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) | ||
655 | err=UNZ_ERRNO; | ||
656 | |||
657 | /* number of this disk */ | ||
658 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) | ||
659 | err=UNZ_ERRNO; | ||
660 | |||
661 | /* number of the disk with the start of the central directory */ | ||
662 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) | ||
663 | err=UNZ_ERRNO; | ||
664 | |||
665 | /* total number of entries in the central directory on this disk */ | ||
666 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) | ||
667 | err=UNZ_ERRNO; | ||
668 | |||
669 | /* total number of entries in the central directory */ | ||
670 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) | ||
671 | err=UNZ_ERRNO; | ||
672 | |||
673 | if ((number_entry_CD!=us.gi.number_entry) || | ||
674 | (number_disk_with_CD!=0) || | ||
675 | (number_disk!=0)) | ||
676 | err=UNZ_BADZIPFILE; | ||
677 | |||
678 | /* size of the central directory */ | ||
679 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) | ||
680 | err=UNZ_ERRNO; | ||
681 | |||
682 | /* offset of start of central directory with respect to the | ||
683 | starting disk number */ | ||
684 | if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) | ||
685 | err=UNZ_ERRNO; | ||
686 | |||
687 | us.gi.size_comment = 0; | ||
688 | } | ||
689 | else | ||
690 | { | ||
691 | central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); | ||
692 | if (central_pos==0) | ||
693 | err=UNZ_ERRNO; | ||
694 | |||
695 | us.isZip64 = 0; | ||
696 | |||
697 | if (ZSEEK64(us.z_filefunc, us.filestream, | ||
698 | central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
699 | err=UNZ_ERRNO; | ||
700 | |||
701 | /* the signature, already checked */ | ||
702 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | ||
703 | err=UNZ_ERRNO; | ||
704 | |||
705 | /* number of this disk */ | ||
706 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) | ||
707 | err=UNZ_ERRNO; | ||
708 | |||
709 | /* number of the disk with the start of the central directory */ | ||
710 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) | ||
711 | err=UNZ_ERRNO; | ||
712 | |||
713 | /* total number of entries in the central dir on this disk */ | ||
714 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | ||
715 | err=UNZ_ERRNO; | ||
716 | us.gi.number_entry = uL; | ||
717 | |||
718 | /* total number of entries in the central dir */ | ||
719 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | ||
720 | err=UNZ_ERRNO; | ||
721 | number_entry_CD = uL; | ||
722 | |||
723 | if ((number_entry_CD!=us.gi.number_entry) || | ||
724 | (number_disk_with_CD!=0) || | ||
725 | (number_disk!=0)) | ||
726 | err=UNZ_BADZIPFILE; | ||
727 | |||
728 | /* size of the central directory */ | ||
729 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | ||
730 | err=UNZ_ERRNO; | ||
731 | us.size_central_dir = uL; | ||
732 | |||
733 | /* offset of start of central directory with respect to the | ||
734 | starting disk number */ | ||
735 | if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) | ||
736 | err=UNZ_ERRNO; | ||
737 | us.offset_central_dir = uL; | ||
738 | |||
739 | /* zipfile comment length */ | ||
740 | if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) | ||
741 | err=UNZ_ERRNO; | ||
742 | } | ||
743 | |||
744 | if ((central_pos<us.offset_central_dir+us.size_central_dir) && | ||
745 | (err==UNZ_OK)) | ||
746 | err=UNZ_BADZIPFILE; | ||
747 | |||
748 | if (err!=UNZ_OK) | ||
749 | { | ||
750 | if ((us.flags & UNZ_AUTO_CLOSE) != 0) | ||
751 | ZCLOSE64(us.z_filefunc, us.filestream); | ||
752 | else | ||
753 | ZFAKECLOSE64(us.z_filefunc, us.filestream); | ||
754 | return NULL; | ||
755 | } | ||
756 | |||
757 | us.byte_before_the_zipfile = central_pos - | ||
758 | (us.offset_central_dir+us.size_central_dir); | ||
759 | us.central_pos = central_pos; | ||
760 | us.pfile_in_zip_read = NULL; | ||
761 | us.encrypted = 0; | ||
762 | |||
763 | |||
764 | s=(unz64_s*)ALLOC(sizeof(unz64_s)); | ||
765 | if( s != NULL) | ||
766 | { | ||
767 | *s=us; | ||
768 | unzGoToFirstFile((unzFile)s); | ||
769 | } | ||
770 | return (unzFile)s; | ||
771 | } | ||
772 | |||
773 | |||
774 | extern unzFile ZEXPORT unzOpen2 (voidpf file, | ||
775 | zlib_filefunc_def* pzlib_filefunc32_def) | ||
776 | { | ||
777 | if (pzlib_filefunc32_def != NULL) | ||
778 | { | ||
779 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | ||
780 | fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); | ||
781 | return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 0, UNZ_DEFAULT_FLAGS); | ||
782 | } | ||
783 | else | ||
784 | return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS); | ||
785 | } | ||
786 | |||
787 | extern unzFile ZEXPORT unzOpen2_64 (voidpf file, | ||
788 | zlib_filefunc64_def* pzlib_filefunc_def) | ||
789 | { | ||
790 | if (pzlib_filefunc_def != NULL) | ||
791 | { | ||
792 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | ||
793 | zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; | ||
794 | zlib_filefunc64_32_def_fill.ztell32_file = NULL; | ||
795 | zlib_filefunc64_32_def_fill.zseek32_file = NULL; | ||
796 | return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 1, UNZ_DEFAULT_FLAGS); | ||
797 | } | ||
798 | else | ||
799 | return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS); | ||
800 | } | ||
801 | |||
802 | extern unzFile ZEXPORT unzOpen (voidpf file) | ||
803 | { | ||
804 | return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS); | ||
805 | } | ||
806 | |||
807 | extern unzFile ZEXPORT unzOpen64 (voidpf file) | ||
808 | { | ||
809 | return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS); | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | Close a ZipFile opened with unzipOpen. | ||
814 | If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), | ||
815 | these files MUST be closed with unzipCloseCurrentFile before call unzipClose. | ||
816 | return UNZ_OK if there is no problem. */ | ||
817 | extern int ZEXPORT unzClose (unzFile file) | ||
818 | { | ||
819 | unz64_s* s; | ||
820 | if (file==NULL) | ||
821 | return UNZ_PARAMERROR; | ||
822 | s=(unz64_s*)file; | ||
823 | |||
824 | if (s->pfile_in_zip_read!=NULL) | ||
825 | unzCloseCurrentFile(file); | ||
826 | |||
827 | if ((s->flags & UNZ_AUTO_CLOSE) != 0) | ||
828 | ZCLOSE64(s->z_filefunc, s->filestream); | ||
829 | else | ||
830 | ZFAKECLOSE64(s->z_filefunc, s->filestream); | ||
831 | TRYFREE(s); | ||
832 | return UNZ_OK; | ||
833 | } | ||
834 | |||
835 | |||
836 | /* | ||
837 | Write info about the ZipFile in the *pglobal_info structure. | ||
838 | No preparation of the structure is needed | ||
839 | return UNZ_OK if there is no problem. */ | ||
840 | extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) | ||
841 | { | ||
842 | unz64_s* s; | ||
843 | if (file==NULL) | ||
844 | return UNZ_PARAMERROR; | ||
845 | s=(unz64_s*)file; | ||
846 | *pglobal_info=s->gi; | ||
847 | return UNZ_OK; | ||
848 | } | ||
849 | |||
850 | extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) | ||
851 | { | ||
852 | unz64_s* s; | ||
853 | if (file==NULL) | ||
854 | return UNZ_PARAMERROR; | ||
855 | s=(unz64_s*)file; | ||
856 | /* to do : check if number_entry is not truncated */ | ||
857 | pglobal_info32->number_entry = (uLong)s->gi.number_entry; | ||
858 | pglobal_info32->size_comment = s->gi.size_comment; | ||
859 | return UNZ_OK; | ||
860 | } | ||
861 | |||
862 | extern int ZEXPORT unzGetFileFlags (unzFile file, unsigned* pflags) | ||
863 | { | ||
864 | unz64_s* s; | ||
865 | if (file==NULL) | ||
866 | return UNZ_PARAMERROR; | ||
867 | s=(unz64_s*)file; | ||
868 | *pflags = s->flags; | ||
869 | return UNZ_OK; | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | Translate date/time from Dos format to tm_unz (readable more easilty) | ||
874 | */ | ||
875 | local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) | ||
876 | { | ||
877 | ZPOS64_T uDate; | ||
878 | uDate = (ZPOS64_T)(ulDosDate>>16); | ||
879 | ptm->tm_mday = (uInt)(uDate&0x1f) ; | ||
880 | ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; | ||
881 | ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; | ||
882 | |||
883 | ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); | ||
884 | ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; | ||
885 | ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; | ||
886 | } | ||
887 | |||
888 | /* | ||
889 | Get Info about the current file in the zipfile, with internal only info | ||
890 | */ | ||
891 | local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, | ||
892 | unz_file_info64 *pfile_info, | ||
893 | unz_file_info64_internal | ||
894 | *pfile_info_internal, | ||
895 | char *szFileName, | ||
896 | uLong fileNameBufferSize, | ||
897 | void *extraField, | ||
898 | uLong extraFieldBufferSize, | ||
899 | char *szComment, | ||
900 | uLong commentBufferSize)); | ||
901 | |||
902 | local int unz64local_GetCurrentFileInfoInternal (unzFile file, | ||
903 | unz_file_info64 *pfile_info, | ||
904 | unz_file_info64_internal | ||
905 | *pfile_info_internal, | ||
906 | char *szFileName, | ||
907 | uLong fileNameBufferSize, | ||
908 | void *extraField, | ||
909 | uLong extraFieldBufferSize, | ||
910 | char *szComment, | ||
911 | uLong commentBufferSize) | ||
912 | { | ||
913 | unz64_s* s; | ||
914 | unz_file_info64 file_info; | ||
915 | unz_file_info64_internal file_info_internal; | ||
916 | int err=UNZ_OK; | ||
917 | uLong uMagic; | ||
918 | ZPOS64_T llSeek=0; | ||
919 | uLong uL; | ||
920 | |||
921 | if (file==NULL) | ||
922 | return UNZ_PARAMERROR; | ||
923 | s=(unz64_s*)file; | ||
924 | if (ZSEEK64(s->z_filefunc, s->filestream, | ||
925 | s->pos_in_central_dir+s->byte_before_the_zipfile, | ||
926 | ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
927 | err=UNZ_ERRNO; | ||
928 | |||
929 | |||
930 | /* we check the magic */ | ||
931 | if (err==UNZ_OK) | ||
932 | { | ||
933 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) | ||
934 | err=UNZ_ERRNO; | ||
935 | else if (uMagic!=0x02014b50) | ||
936 | err=UNZ_BADZIPFILE; | ||
937 | } | ||
938 | |||
939 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) | ||
940 | err=UNZ_ERRNO; | ||
941 | |||
942 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) | ||
943 | err=UNZ_ERRNO; | ||
944 | |||
945 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) | ||
946 | err=UNZ_ERRNO; | ||
947 | |||
948 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) | ||
949 | err=UNZ_ERRNO; | ||
950 | |||
951 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) | ||
952 | err=UNZ_ERRNO; | ||
953 | |||
954 | unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); | ||
955 | |||
956 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) | ||
957 | err=UNZ_ERRNO; | ||
958 | |||
959 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | ||
960 | err=UNZ_ERRNO; | ||
961 | file_info.compressed_size = uL; | ||
962 | |||
963 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | ||
964 | err=UNZ_ERRNO; | ||
965 | file_info.uncompressed_size = uL; | ||
966 | |||
967 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) | ||
968 | err=UNZ_ERRNO; | ||
969 | |||
970 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) | ||
971 | err=UNZ_ERRNO; | ||
972 | |||
973 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) | ||
974 | err=UNZ_ERRNO; | ||
975 | |||
976 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) | ||
977 | err=UNZ_ERRNO; | ||
978 | |||
979 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) | ||
980 | err=UNZ_ERRNO; | ||
981 | |||
982 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) | ||
983 | err=UNZ_ERRNO; | ||
984 | |||
985 | /* relative offset of local header */ | ||
986 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | ||
987 | err=UNZ_ERRNO; | ||
988 | file_info_internal.offset_curfile = uL; | ||
989 | |||
990 | llSeek+=file_info.size_filename; | ||
991 | if ((err==UNZ_OK) && (szFileName!=NULL)) | ||
992 | { | ||
993 | uLong uSizeRead ; | ||
994 | if (file_info.size_filename<fileNameBufferSize) | ||
995 | { | ||
996 | *(szFileName+file_info.size_filename)='\0'; | ||
997 | uSizeRead = file_info.size_filename; | ||
998 | } | ||
999 | else | ||
1000 | uSizeRead = fileNameBufferSize; | ||
1001 | |||
1002 | if ((file_info.size_filename>0) && (fileNameBufferSize>0)) | ||
1003 | if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) | ||
1004 | err=UNZ_ERRNO; | ||
1005 | llSeek -= uSizeRead; | ||
1006 | } | ||
1007 | |||
1008 | /* Read extrafield */ | ||
1009 | if ((err==UNZ_OK) && (extraField!=NULL)) | ||
1010 | { | ||
1011 | ZPOS64_T uSizeRead ; | ||
1012 | if (file_info.size_file_extra<extraFieldBufferSize) | ||
1013 | uSizeRead = file_info.size_file_extra; | ||
1014 | else | ||
1015 | uSizeRead = extraFieldBufferSize; | ||
1016 | |||
1017 | if (llSeek!=0) | ||
1018 | { | ||
1019 | if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) | ||
1020 | llSeek=0; | ||
1021 | else | ||
1022 | err=UNZ_ERRNO; | ||
1023 | } | ||
1024 | |||
1025 | if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) | ||
1026 | if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) | ||
1027 | err=UNZ_ERRNO; | ||
1028 | |||
1029 | llSeek += file_info.size_file_extra - (uLong)uSizeRead; | ||
1030 | } | ||
1031 | else | ||
1032 | llSeek += file_info.size_file_extra; | ||
1033 | |||
1034 | |||
1035 | if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) | ||
1036 | { | ||
1037 | uLong acc = 0; | ||
1038 | |||
1039 | /* since lSeek now points to after the extra field we need to move back */ | ||
1040 | llSeek -= file_info.size_file_extra; | ||
1041 | |||
1042 | if (llSeek!=0) | ||
1043 | { | ||
1044 | if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) | ||
1045 | llSeek=0; | ||
1046 | else | ||
1047 | err=UNZ_ERRNO; | ||
1048 | } | ||
1049 | |||
1050 | while(acc < file_info.size_file_extra) | ||
1051 | { | ||
1052 | uLong headerId; | ||
1053 | uLong dataSize; | ||
1054 | |||
1055 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) | ||
1056 | err=UNZ_ERRNO; | ||
1057 | |||
1058 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) | ||
1059 | err=UNZ_ERRNO; | ||
1060 | |||
1061 | /* ZIP64 extra fields */ | ||
1062 | if (headerId == 0x0001) | ||
1063 | { | ||
1064 | uLong uL; | ||
1065 | |||
1066 | if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu) | ||
1067 | { | ||
1068 | if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) | ||
1069 | err=UNZ_ERRNO; | ||
1070 | } | ||
1071 | |||
1072 | if(file_info.compressed_size == (ZPOS64_T)0xFFFFFFFFu) | ||
1073 | { | ||
1074 | if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) | ||
1075 | err=UNZ_ERRNO; | ||
1076 | } | ||
1077 | |||
1078 | if(file_info_internal.offset_curfile == (ZPOS64_T)0xFFFFFFFFu) | ||
1079 | { | ||
1080 | /* Relative Header offset */ | ||
1081 | if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) | ||
1082 | err=UNZ_ERRNO; | ||
1083 | } | ||
1084 | |||
1085 | if(file_info.disk_num_start == 0xFFFFFFFFu) | ||
1086 | { | ||
1087 | /* Disk Start Number */ | ||
1088 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) | ||
1089 | err=UNZ_ERRNO; | ||
1090 | } | ||
1091 | |||
1092 | } | ||
1093 | else | ||
1094 | { | ||
1095 | if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) | ||
1096 | err=UNZ_ERRNO; | ||
1097 | } | ||
1098 | |||
1099 | acc += 2 + 2 + dataSize; | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | if ((err==UNZ_OK) && (szComment!=NULL)) | ||
1104 | { | ||
1105 | uLong uSizeRead ; | ||
1106 | if (file_info.size_file_comment<commentBufferSize) | ||
1107 | { | ||
1108 | *(szComment+file_info.size_file_comment)='\0'; | ||
1109 | uSizeRead = file_info.size_file_comment; | ||
1110 | } | ||
1111 | else | ||
1112 | uSizeRead = commentBufferSize; | ||
1113 | |||
1114 | if (llSeek!=0) | ||
1115 | { | ||
1116 | if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) | ||
1117 | llSeek=0; | ||
1118 | else | ||
1119 | err=UNZ_ERRNO; | ||
1120 | } | ||
1121 | |||
1122 | if ((file_info.size_file_comment>0) && (commentBufferSize>0)) | ||
1123 | if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) | ||
1124 | err=UNZ_ERRNO; | ||
1125 | llSeek+=file_info.size_file_comment - uSizeRead; | ||
1126 | } | ||
1127 | else | ||
1128 | llSeek+=file_info.size_file_comment; | ||
1129 | |||
1130 | |||
1131 | if ((err==UNZ_OK) && (pfile_info!=NULL)) | ||
1132 | *pfile_info=file_info; | ||
1133 | |||
1134 | if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) | ||
1135 | *pfile_info_internal=file_info_internal; | ||
1136 | |||
1137 | return err; | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | |||
1142 | /* | ||
1143 | Write info about the ZipFile in the *pglobal_info structure. | ||
1144 | No preparation of the structure is needed | ||
1145 | return UNZ_OK if there is no problem. | ||
1146 | */ | ||
1147 | extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, | ||
1148 | unz_file_info64 * pfile_info, | ||
1149 | char * szFileName, uLong fileNameBufferSize, | ||
1150 | void *extraField, uLong extraFieldBufferSize, | ||
1151 | char* szComment, uLong commentBufferSize) | ||
1152 | { | ||
1153 | return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, | ||
1154 | szFileName,fileNameBufferSize, | ||
1155 | extraField,extraFieldBufferSize, | ||
1156 | szComment,commentBufferSize); | ||
1157 | } | ||
1158 | |||
1159 | extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, | ||
1160 | unz_file_info * pfile_info, | ||
1161 | char * szFileName, uLong fileNameBufferSize, | ||
1162 | void *extraField, uLong extraFieldBufferSize, | ||
1163 | char* szComment, uLong commentBufferSize) | ||
1164 | { | ||
1165 | int err; | ||
1166 | unz_file_info64 file_info64; | ||
1167 | err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, | ||
1168 | szFileName,fileNameBufferSize, | ||
1169 | extraField,extraFieldBufferSize, | ||
1170 | szComment,commentBufferSize); | ||
1171 | if (err==UNZ_OK && pfile_info != NULL) | ||
1172 | { | ||
1173 | pfile_info->version = file_info64.version; | ||
1174 | pfile_info->version_needed = file_info64.version_needed; | ||
1175 | pfile_info->flag = file_info64.flag; | ||
1176 | pfile_info->compression_method = file_info64.compression_method; | ||
1177 | pfile_info->dosDate = file_info64.dosDate; | ||
1178 | pfile_info->crc = file_info64.crc; | ||
1179 | |||
1180 | pfile_info->size_filename = file_info64.size_filename; | ||
1181 | pfile_info->size_file_extra = file_info64.size_file_extra; | ||
1182 | pfile_info->size_file_comment = file_info64.size_file_comment; | ||
1183 | |||
1184 | pfile_info->disk_num_start = file_info64.disk_num_start; | ||
1185 | pfile_info->internal_fa = file_info64.internal_fa; | ||
1186 | pfile_info->external_fa = file_info64.external_fa; | ||
1187 | |||
1188 | pfile_info->tmu_date = file_info64.tmu_date, | ||
1189 | |||
1190 | |||
1191 | pfile_info->compressed_size = (uLong)file_info64.compressed_size; | ||
1192 | pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; | ||
1193 | |||
1194 | } | ||
1195 | return err; | ||
1196 | } | ||
1197 | /* | ||
1198 | Set the current file of the zipfile to the first file. | ||
1199 | return UNZ_OK if there is no problem | ||
1200 | */ | ||
1201 | extern int ZEXPORT unzGoToFirstFile (unzFile file) | ||
1202 | { | ||
1203 | int err=UNZ_OK; | ||
1204 | unz64_s* s; | ||
1205 | if (file==NULL) | ||
1206 | return UNZ_PARAMERROR; | ||
1207 | s=(unz64_s*)file; | ||
1208 | s->pos_in_central_dir=s->offset_central_dir; | ||
1209 | s->num_file=0; | ||
1210 | err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | ||
1211 | &s->cur_file_info_internal, | ||
1212 | NULL,0,NULL,0,NULL,0); | ||
1213 | s->current_file_ok = (err == UNZ_OK); | ||
1214 | if (s->cur_file_info.flag & UNZ_ENCODING_UTF8) | ||
1215 | unzSetFlags(file, UNZ_ENCODING_UTF8); | ||
1216 | return err; | ||
1217 | } | ||
1218 | |||
1219 | /* | ||
1220 | Set the current file of the zipfile to the next file. | ||
1221 | return UNZ_OK if there is no problem | ||
1222 | return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. | ||
1223 | */ | ||
1224 | extern int ZEXPORT unzGoToNextFile (unzFile file) | ||
1225 | { | ||
1226 | unz64_s* s; | ||
1227 | int err; | ||
1228 | |||
1229 | if (file==NULL) | ||
1230 | return UNZ_PARAMERROR; | ||
1231 | s=(unz64_s*)file; | ||
1232 | if (!s->current_file_ok) | ||
1233 | return UNZ_END_OF_LIST_OF_FILE; | ||
1234 | if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ | ||
1235 | if (s->num_file+1==s->gi.number_entry) | ||
1236 | return UNZ_END_OF_LIST_OF_FILE; | ||
1237 | |||
1238 | s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + | ||
1239 | s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; | ||
1240 | s->num_file++; | ||
1241 | err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | ||
1242 | &s->cur_file_info_internal, | ||
1243 | NULL,0,NULL,0,NULL,0); | ||
1244 | s->current_file_ok = (err == UNZ_OK); | ||
1245 | return err; | ||
1246 | } | ||
1247 | |||
1248 | |||
1249 | /* | ||
1250 | Try locate the file szFileName in the zipfile. | ||
1251 | For the iCaseSensitivity signification, see unzipStringFileNameCompare | ||
1252 | |||
1253 | return value : | ||
1254 | UNZ_OK if the file is found. It becomes the current file. | ||
1255 | UNZ_END_OF_LIST_OF_FILE if the file is not found | ||
1256 | */ | ||
1257 | extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) | ||
1258 | { | ||
1259 | unz64_s* s; | ||
1260 | int err; | ||
1261 | |||
1262 | /* We remember the 'current' position in the file so that we can jump | ||
1263 | * back there if we fail. | ||
1264 | */ | ||
1265 | unz_file_info64 cur_file_infoSaved; | ||
1266 | unz_file_info64_internal cur_file_info_internalSaved; | ||
1267 | ZPOS64_T num_fileSaved; | ||
1268 | ZPOS64_T pos_in_central_dirSaved; | ||
1269 | |||
1270 | |||
1271 | if (file==NULL) | ||
1272 | return UNZ_PARAMERROR; | ||
1273 | |||
1274 | if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) | ||
1275 | return UNZ_PARAMERROR; | ||
1276 | |||
1277 | s=(unz64_s*)file; | ||
1278 | if (!s->current_file_ok) | ||
1279 | return UNZ_END_OF_LIST_OF_FILE; | ||
1280 | |||
1281 | /* Save the current state */ | ||
1282 | num_fileSaved = s->num_file; | ||
1283 | pos_in_central_dirSaved = s->pos_in_central_dir; | ||
1284 | cur_file_infoSaved = s->cur_file_info; | ||
1285 | cur_file_info_internalSaved = s->cur_file_info_internal; | ||
1286 | |||
1287 | err = unzGoToFirstFile(file); | ||
1288 | |||
1289 | while (err == UNZ_OK) | ||
1290 | { | ||
1291 | char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; | ||
1292 | err = unzGetCurrentFileInfo64(file,NULL, | ||
1293 | szCurrentFileName,sizeof(szCurrentFileName)-1, | ||
1294 | NULL,0,NULL,0); | ||
1295 | if (err == UNZ_OK) | ||
1296 | { | ||
1297 | if (unzStringFileNameCompare(szCurrentFileName, | ||
1298 | szFileName,iCaseSensitivity)==0) | ||
1299 | return UNZ_OK; | ||
1300 | err = unzGoToNextFile(file); | ||
1301 | } | ||
1302 | } | ||
1303 | |||
1304 | /* We failed, so restore the state of the 'current file' to where we | ||
1305 | * were. | ||
1306 | */ | ||
1307 | s->num_file = num_fileSaved ; | ||
1308 | s->pos_in_central_dir = pos_in_central_dirSaved ; | ||
1309 | s->cur_file_info = cur_file_infoSaved; | ||
1310 | s->cur_file_info_internal = cur_file_info_internalSaved; | ||
1311 | return err; | ||
1312 | } | ||
1313 | |||
1314 | |||
1315 | /* | ||
1316 | /////////////////////////////////////////// | ||
1317 | // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) | ||
1318 | // I need random access | ||
1319 | // | ||
1320 | // Further optimization could be realized by adding an ability | ||
1321 | // to cache the directory in memory. The goal being a single | ||
1322 | // comprehensive file read to put the file I need in a memory. | ||
1323 | */ | ||
1324 | |||
1325 | /* | ||
1326 | typedef struct unz_file_pos_s | ||
1327 | { | ||
1328 | ZPOS64_T pos_in_zip_directory; // offset in file | ||
1329 | ZPOS64_T num_of_file; // # of file | ||
1330 | } unz_file_pos; | ||
1331 | */ | ||
1332 | |||
1333 | extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) | ||
1334 | { | ||
1335 | unz64_s* s; | ||
1336 | |||
1337 | if (file==NULL || file_pos==NULL) | ||
1338 | return UNZ_PARAMERROR; | ||
1339 | s=(unz64_s*)file; | ||
1340 | if (!s->current_file_ok) | ||
1341 | return UNZ_END_OF_LIST_OF_FILE; | ||
1342 | |||
1343 | file_pos->pos_in_zip_directory = s->pos_in_central_dir; | ||
1344 | file_pos->num_of_file = s->num_file; | ||
1345 | |||
1346 | return UNZ_OK; | ||
1347 | } | ||
1348 | |||
1349 | extern int ZEXPORT unzGetFilePos( | ||
1350 | unzFile file, | ||
1351 | unz_file_pos* file_pos) | ||
1352 | { | ||
1353 | unz64_file_pos file_pos64; | ||
1354 | int err = unzGetFilePos64(file,&file_pos64); | ||
1355 | if (err==UNZ_OK) | ||
1356 | { | ||
1357 | file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; | ||
1358 | file_pos->num_of_file = (uLong)file_pos64.num_of_file; | ||
1359 | } | ||
1360 | return err; | ||
1361 | } | ||
1362 | |||
1363 | extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) | ||
1364 | { | ||
1365 | unz64_s* s; | ||
1366 | int err; | ||
1367 | |||
1368 | if (file==NULL || file_pos==NULL) | ||
1369 | return UNZ_PARAMERROR; | ||
1370 | s=(unz64_s*)file; | ||
1371 | |||
1372 | /* jump to the right spot */ | ||
1373 | s->pos_in_central_dir = file_pos->pos_in_zip_directory; | ||
1374 | s->num_file = file_pos->num_of_file; | ||
1375 | |||
1376 | /* set the current file */ | ||
1377 | err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | ||
1378 | &s->cur_file_info_internal, | ||
1379 | NULL,0,NULL,0,NULL,0); | ||
1380 | /* return results */ | ||
1381 | s->current_file_ok = (err == UNZ_OK); | ||
1382 | return err; | ||
1383 | } | ||
1384 | |||
1385 | extern int ZEXPORT unzGoToFilePos( | ||
1386 | unzFile file, | ||
1387 | unz_file_pos* file_pos) | ||
1388 | { | ||
1389 | unz64_file_pos file_pos64; | ||
1390 | if (file_pos == NULL) | ||
1391 | return UNZ_PARAMERROR; | ||
1392 | |||
1393 | file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; | ||
1394 | file_pos64.num_of_file = file_pos->num_of_file; | ||
1395 | return unzGoToFilePos64(file,&file_pos64); | ||
1396 | } | ||
1397 | |||
1398 | /* Unzip Helper Functions - should be here? */ | ||
1399 | /*///////////////////////////////////////// */ | ||
1400 | |||
1401 | /* | ||
1402 | Read the local header of the current zipfile | ||
1403 | Check the coherency of the local header and info in the end of central | ||
1404 | directory about this file | ||
1405 | store in *piSizeVar the size of extra info in local header | ||
1406 | (filename and size of extra field data) | ||
1407 | */ | ||
1408 | local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, | ||
1409 | ZPOS64_T * poffset_local_extrafield, | ||
1410 | uInt * psize_local_extrafield) | ||
1411 | { | ||
1412 | uLong uMagic,uData,uFlags; | ||
1413 | uLong size_filename; | ||
1414 | uLong size_extra_field; | ||
1415 | int err=UNZ_OK; | ||
1416 | |||
1417 | *piSizeVar = 0; | ||
1418 | *poffset_local_extrafield = 0; | ||
1419 | *psize_local_extrafield = 0; | ||
1420 | |||
1421 | if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + | ||
1422 | s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1423 | return UNZ_ERRNO; | ||
1424 | |||
1425 | |||
1426 | if (err==UNZ_OK) | ||
1427 | { | ||
1428 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) | ||
1429 | err=UNZ_ERRNO; | ||
1430 | else if (uMagic!=0x04034b50) | ||
1431 | err=UNZ_BADZIPFILE; | ||
1432 | } | ||
1433 | |||
1434 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) | ||
1435 | err=UNZ_ERRNO; | ||
1436 | /* | ||
1437 | else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) | ||
1438 | err=UNZ_BADZIPFILE; | ||
1439 | */ | ||
1440 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) | ||
1441 | err=UNZ_ERRNO; | ||
1442 | |||
1443 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) | ||
1444 | err=UNZ_ERRNO; | ||
1445 | else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) | ||
1446 | err=UNZ_BADZIPFILE; | ||
1447 | |||
1448 | if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && | ||
1449 | /* #ifdef HAVE_BZIP2 */ | ||
1450 | (s->cur_file_info.compression_method!=Z_BZIP2ED) && | ||
1451 | /* #endif */ | ||
1452 | (s->cur_file_info.compression_method!=Z_DEFLATED)) | ||
1453 | err=UNZ_BADZIPFILE; | ||
1454 | |||
1455 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ | ||
1456 | err=UNZ_ERRNO; | ||
1457 | |||
1458 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ | ||
1459 | err=UNZ_ERRNO; | ||
1460 | else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) | ||
1461 | err=UNZ_BADZIPFILE; | ||
1462 | |||
1463 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ | ||
1464 | err=UNZ_ERRNO; | ||
1465 | else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) | ||
1466 | err=UNZ_BADZIPFILE; | ||
1467 | |||
1468 | if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ | ||
1469 | err=UNZ_ERRNO; | ||
1470 | else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) | ||
1471 | err=UNZ_BADZIPFILE; | ||
1472 | |||
1473 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) | ||
1474 | err=UNZ_ERRNO; | ||
1475 | else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) | ||
1476 | err=UNZ_BADZIPFILE; | ||
1477 | |||
1478 | *piSizeVar += (uInt)size_filename; | ||
1479 | |||
1480 | if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) | ||
1481 | err=UNZ_ERRNO; | ||
1482 | *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + | ||
1483 | SIZEZIPLOCALHEADER + size_filename; | ||
1484 | *psize_local_extrafield = (uInt)size_extra_field; | ||
1485 | |||
1486 | *piSizeVar += (uInt)size_extra_field; | ||
1487 | |||
1488 | return err; | ||
1489 | } | ||
1490 | |||
1491 | /* | ||
1492 | Open for reading data the current file in the zipfile. | ||
1493 | If there is no error and the file is opened, the return value is UNZ_OK. | ||
1494 | */ | ||
1495 | extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, | ||
1496 | int* level, int raw, const char* password) | ||
1497 | { | ||
1498 | int err=UNZ_OK; | ||
1499 | uInt iSizeVar; | ||
1500 | unz64_s* s; | ||
1501 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1502 | ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ | ||
1503 | uInt size_local_extrafield; /* size of the local extra field */ | ||
1504 | # ifndef NOUNCRYPT | ||
1505 | char source[12]; | ||
1506 | # else | ||
1507 | if (password != NULL) | ||
1508 | return UNZ_PARAMERROR; | ||
1509 | # endif | ||
1510 | |||
1511 | if (file==NULL) | ||
1512 | return UNZ_PARAMERROR; | ||
1513 | s=(unz64_s*)file; | ||
1514 | if (!s->current_file_ok) | ||
1515 | return UNZ_PARAMERROR; | ||
1516 | |||
1517 | if (s->pfile_in_zip_read != NULL) | ||
1518 | unzCloseCurrentFile(file); | ||
1519 | |||
1520 | if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) | ||
1521 | return UNZ_BADZIPFILE; | ||
1522 | |||
1523 | pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); | ||
1524 | if (pfile_in_zip_read_info==NULL) | ||
1525 | return UNZ_INTERNALERROR; | ||
1526 | |||
1527 | pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); | ||
1528 | pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; | ||
1529 | pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; | ||
1530 | pfile_in_zip_read_info->pos_local_extrafield=0; | ||
1531 | pfile_in_zip_read_info->raw=raw; | ||
1532 | |||
1533 | if (pfile_in_zip_read_info->read_buffer==NULL) | ||
1534 | { | ||
1535 | TRYFREE(pfile_in_zip_read_info); | ||
1536 | return UNZ_INTERNALERROR; | ||
1537 | } | ||
1538 | |||
1539 | pfile_in_zip_read_info->stream_initialised=0; | ||
1540 | |||
1541 | if (method!=NULL) | ||
1542 | *method = (int)s->cur_file_info.compression_method; | ||
1543 | |||
1544 | if (level!=NULL) | ||
1545 | { | ||
1546 | *level = 6; | ||
1547 | switch (s->cur_file_info.flag & 0x06) | ||
1548 | { | ||
1549 | case 6 : *level = 1; break; | ||
1550 | case 4 : *level = 2; break; | ||
1551 | case 2 : *level = 9; break; | ||
1552 | } | ||
1553 | } | ||
1554 | |||
1555 | if ((s->cur_file_info.compression_method!=0) && | ||
1556 | /* #ifdef HAVE_BZIP2 */ | ||
1557 | (s->cur_file_info.compression_method!=Z_BZIP2ED) && | ||
1558 | /* #endif */ | ||
1559 | (s->cur_file_info.compression_method!=Z_DEFLATED)) | ||
1560 | |||
1561 | err=UNZ_BADZIPFILE; | ||
1562 | |||
1563 | pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; | ||
1564 | pfile_in_zip_read_info->crc32=0; | ||
1565 | pfile_in_zip_read_info->total_out_64=0; | ||
1566 | pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; | ||
1567 | pfile_in_zip_read_info->filestream=s->filestream; | ||
1568 | pfile_in_zip_read_info->z_filefunc=s->z_filefunc; | ||
1569 | pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; | ||
1570 | |||
1571 | pfile_in_zip_read_info->stream.total_out = 0; | ||
1572 | |||
1573 | if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) | ||
1574 | { | ||
1575 | #ifdef HAVE_BZIP2 | ||
1576 | pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; | ||
1577 | pfile_in_zip_read_info->bstream.bzfree = (free_func)0; | ||
1578 | pfile_in_zip_read_info->bstream.opaque = (voidpf)0; | ||
1579 | pfile_in_zip_read_info->bstream.state = (voidpf)0; | ||
1580 | |||
1581 | pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; | ||
1582 | pfile_in_zip_read_info->stream.zfree = (free_func)0; | ||
1583 | pfile_in_zip_read_info->stream.opaque = (voidpf)0; | ||
1584 | pfile_in_zip_read_info->stream.next_in = (voidpf)0; | ||
1585 | pfile_in_zip_read_info->stream.avail_in = 0; | ||
1586 | |||
1587 | err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); | ||
1588 | if (err == Z_OK) | ||
1589 | pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; | ||
1590 | else | ||
1591 | { | ||
1592 | TRYFREE(pfile_in_zip_read_info); | ||
1593 | return err; | ||
1594 | } | ||
1595 | #else | ||
1596 | pfile_in_zip_read_info->raw=1; | ||
1597 | #endif | ||
1598 | } | ||
1599 | else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) | ||
1600 | { | ||
1601 | pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; | ||
1602 | pfile_in_zip_read_info->stream.zfree = (free_func)0; | ||
1603 | pfile_in_zip_read_info->stream.opaque = (voidpf)0; | ||
1604 | pfile_in_zip_read_info->stream.next_in = 0; | ||
1605 | pfile_in_zip_read_info->stream.avail_in = 0; | ||
1606 | |||
1607 | err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); | ||
1608 | if (err == Z_OK) | ||
1609 | pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; | ||
1610 | else | ||
1611 | { | ||
1612 | TRYFREE(pfile_in_zip_read_info->read_buffer); | ||
1613 | TRYFREE(pfile_in_zip_read_info); | ||
1614 | return err; | ||
1615 | } | ||
1616 | /* windowBits is passed < 0 to tell that there is no zlib header. | ||
1617 | * Note that in this case inflate *requires* an extra "dummy" byte | ||
1618 | * after the compressed stream in order to complete decompression and | ||
1619 | * return Z_STREAM_END. | ||
1620 | * In unzip, i don't wait absolutely Z_STREAM_END because I known the | ||
1621 | * size of both compressed and uncompressed data | ||
1622 | */ | ||
1623 | } | ||
1624 | pfile_in_zip_read_info->rest_read_compressed = | ||
1625 | s->cur_file_info.compressed_size ; | ||
1626 | pfile_in_zip_read_info->rest_read_uncompressed = | ||
1627 | s->cur_file_info.uncompressed_size ; | ||
1628 | |||
1629 | |||
1630 | pfile_in_zip_read_info->pos_in_zipfile = | ||
1631 | s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + | ||
1632 | iSizeVar; | ||
1633 | |||
1634 | pfile_in_zip_read_info->stream.avail_in = (uInt)0; | ||
1635 | |||
1636 | s->pfile_in_zip_read = pfile_in_zip_read_info; | ||
1637 | s->encrypted = 0; | ||
1638 | |||
1639 | # ifndef NOUNCRYPT | ||
1640 | if (password != NULL) | ||
1641 | { | ||
1642 | int i; | ||
1643 | s->pcrc_32_tab = get_crc_table(); | ||
1644 | init_keys(password,s->keys,s->pcrc_32_tab); | ||
1645 | if (ZSEEK64(s->z_filefunc, s->filestream, | ||
1646 | s->pfile_in_zip_read->pos_in_zipfile + | ||
1647 | s->pfile_in_zip_read->byte_before_the_zipfile, | ||
1648 | SEEK_SET)!=0) | ||
1649 | return UNZ_INTERNALERROR; | ||
1650 | if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) | ||
1651 | return UNZ_INTERNALERROR; | ||
1652 | |||
1653 | for (i = 0; i<12; i++) | ||
1654 | zdecode(s->keys,s->pcrc_32_tab,source[i]); | ||
1655 | |||
1656 | s->pfile_in_zip_read->pos_in_zipfile+=12; | ||
1657 | s->encrypted=1; | ||
1658 | } | ||
1659 | # endif | ||
1660 | |||
1661 | |||
1662 | return UNZ_OK; | ||
1663 | } | ||
1664 | |||
1665 | extern int ZEXPORT unzOpenCurrentFile (unzFile file) | ||
1666 | { | ||
1667 | return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); | ||
1668 | } | ||
1669 | |||
1670 | extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) | ||
1671 | { | ||
1672 | return unzOpenCurrentFile3(file, NULL, NULL, 0, password); | ||
1673 | } | ||
1674 | |||
1675 | extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) | ||
1676 | { | ||
1677 | return unzOpenCurrentFile3(file, method, level, raw, NULL); | ||
1678 | } | ||
1679 | |||
1680 | /** Addition for GDAL : START */ | ||
1681 | |||
1682 | extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) | ||
1683 | { | ||
1684 | unz64_s* s; | ||
1685 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1686 | s=(unz64_s*)file; | ||
1687 | if (file==NULL) | ||
1688 | return 0; /*UNZ_PARAMERROR; */ | ||
1689 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
1690 | if (pfile_in_zip_read_info==NULL) | ||
1691 | return 0; /*UNZ_PARAMERROR; */ | ||
1692 | return pfile_in_zip_read_info->pos_in_zipfile + | ||
1693 | pfile_in_zip_read_info->byte_before_the_zipfile; | ||
1694 | } | ||
1695 | |||
1696 | /** Addition for GDAL : END */ | ||
1697 | |||
1698 | /* | ||
1699 | Read bytes from the current file. | ||
1700 | buf contain buffer where data must be copied | ||
1701 | len the size of buf. | ||
1702 | |||
1703 | return the number of byte copied if somes bytes are copied | ||
1704 | return 0 if the end of file was reached | ||
1705 | return <0 with error code if there is an error | ||
1706 | (UNZ_ERRNO for IO error, or zLib error for uncompress error) | ||
1707 | */ | ||
1708 | extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) | ||
1709 | { | ||
1710 | int err=UNZ_OK; | ||
1711 | uInt iRead = 0; | ||
1712 | unz64_s* s; | ||
1713 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1714 | if (file==NULL) | ||
1715 | return UNZ_PARAMERROR; | ||
1716 | s=(unz64_s*)file; | ||
1717 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
1718 | |||
1719 | if (pfile_in_zip_read_info==NULL) | ||
1720 | return UNZ_PARAMERROR; | ||
1721 | |||
1722 | |||
1723 | if (pfile_in_zip_read_info->read_buffer == NULL) | ||
1724 | return UNZ_END_OF_LIST_OF_FILE; | ||
1725 | if (len==0) | ||
1726 | return 0; | ||
1727 | |||
1728 | pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; | ||
1729 | |||
1730 | pfile_in_zip_read_info->stream.avail_out = (uInt)len; | ||
1731 | |||
1732 | if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && | ||
1733 | (!(pfile_in_zip_read_info->raw))) | ||
1734 | pfile_in_zip_read_info->stream.avail_out = | ||
1735 | (uInt)pfile_in_zip_read_info->rest_read_uncompressed; | ||
1736 | |||
1737 | if ((len>pfile_in_zip_read_info->rest_read_compressed+ | ||
1738 | pfile_in_zip_read_info->stream.avail_in) && | ||
1739 | (pfile_in_zip_read_info->raw)) | ||
1740 | pfile_in_zip_read_info->stream.avail_out = | ||
1741 | (uInt)pfile_in_zip_read_info->rest_read_compressed+ | ||
1742 | pfile_in_zip_read_info->stream.avail_in; | ||
1743 | |||
1744 | while (pfile_in_zip_read_info->stream.avail_out>0) | ||
1745 | { | ||
1746 | if ((pfile_in_zip_read_info->stream.avail_in==0) && | ||
1747 | (pfile_in_zip_read_info->rest_read_compressed>0)) | ||
1748 | { | ||
1749 | uInt uReadThis = UNZ_BUFSIZE; | ||
1750 | if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) | ||
1751 | uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; | ||
1752 | if (uReadThis == 0) | ||
1753 | return UNZ_EOF; | ||
1754 | if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, | ||
1755 | pfile_in_zip_read_info->filestream, | ||
1756 | pfile_in_zip_read_info->pos_in_zipfile + | ||
1757 | pfile_in_zip_read_info->byte_before_the_zipfile, | ||
1758 | ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1759 | return UNZ_ERRNO; | ||
1760 | if (ZREAD64(pfile_in_zip_read_info->z_filefunc, | ||
1761 | pfile_in_zip_read_info->filestream, | ||
1762 | pfile_in_zip_read_info->read_buffer, | ||
1763 | uReadThis)!=uReadThis) | ||
1764 | return UNZ_ERRNO; | ||
1765 | |||
1766 | |||
1767 | # ifndef NOUNCRYPT | ||
1768 | if(s->encrypted) | ||
1769 | { | ||
1770 | uInt i; | ||
1771 | for(i=0;i<uReadThis;i++) | ||
1772 | pfile_in_zip_read_info->read_buffer[i] = | ||
1773 | zdecode(s->keys,s->pcrc_32_tab, | ||
1774 | pfile_in_zip_read_info->read_buffer[i]); | ||
1775 | } | ||
1776 | # endif | ||
1777 | |||
1778 | |||
1779 | pfile_in_zip_read_info->pos_in_zipfile += uReadThis; | ||
1780 | |||
1781 | pfile_in_zip_read_info->rest_read_compressed-=uReadThis; | ||
1782 | |||
1783 | pfile_in_zip_read_info->stream.next_in = | ||
1784 | (Bytef*)pfile_in_zip_read_info->read_buffer; | ||
1785 | pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; | ||
1786 | } | ||
1787 | |||
1788 | if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) | ||
1789 | { | ||
1790 | uInt uDoCopy,i ; | ||
1791 | |||
1792 | if ((pfile_in_zip_read_info->stream.avail_in == 0) && | ||
1793 | (pfile_in_zip_read_info->rest_read_compressed == 0)) | ||
1794 | return (iRead==0) ? UNZ_EOF : iRead; | ||
1795 | |||
1796 | if (pfile_in_zip_read_info->stream.avail_out < | ||
1797 | pfile_in_zip_read_info->stream.avail_in) | ||
1798 | uDoCopy = pfile_in_zip_read_info->stream.avail_out ; | ||
1799 | else | ||
1800 | uDoCopy = pfile_in_zip_read_info->stream.avail_in ; | ||
1801 | |||
1802 | for (i=0;i<uDoCopy;i++) | ||
1803 | *(pfile_in_zip_read_info->stream.next_out+i) = | ||
1804 | *(pfile_in_zip_read_info->stream.next_in+i); | ||
1805 | |||
1806 | pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; | ||
1807 | |||
1808 | pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, | ||
1809 | pfile_in_zip_read_info->stream.next_out, | ||
1810 | uDoCopy); | ||
1811 | pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; | ||
1812 | pfile_in_zip_read_info->stream.avail_in -= uDoCopy; | ||
1813 | pfile_in_zip_read_info->stream.avail_out -= uDoCopy; | ||
1814 | pfile_in_zip_read_info->stream.next_out += uDoCopy; | ||
1815 | pfile_in_zip_read_info->stream.next_in += uDoCopy; | ||
1816 | pfile_in_zip_read_info->stream.total_out += uDoCopy; | ||
1817 | iRead += uDoCopy; | ||
1818 | } | ||
1819 | else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) | ||
1820 | { | ||
1821 | #ifdef HAVE_BZIP2 | ||
1822 | uLong uTotalOutBefore,uTotalOutAfter; | ||
1823 | const Bytef *bufBefore; | ||
1824 | uLong uOutThis; | ||
1825 | |||
1826 | pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; | ||
1827 | pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; | ||
1828 | pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; | ||
1829 | pfile_in_zip_read_info->bstream.total_in_hi32 = 0; | ||
1830 | pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; | ||
1831 | pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; | ||
1832 | pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; | ||
1833 | pfile_in_zip_read_info->bstream.total_out_hi32 = 0; | ||
1834 | |||
1835 | uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; | ||
1836 | bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; | ||
1837 | |||
1838 | err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); | ||
1839 | |||
1840 | uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; | ||
1841 | uOutThis = uTotalOutAfter-uTotalOutBefore; | ||
1842 | |||
1843 | pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; | ||
1844 | |||
1845 | pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); | ||
1846 | pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; | ||
1847 | iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); | ||
1848 | |||
1849 | pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; | ||
1850 | pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; | ||
1851 | pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; | ||
1852 | pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; | ||
1853 | pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; | ||
1854 | pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; | ||
1855 | |||
1856 | if (err==BZ_STREAM_END) | ||
1857 | return (iRead==0) ? UNZ_EOF : iRead; | ||
1858 | if (err!=BZ_OK) | ||
1859 | break; | ||
1860 | #endif | ||
1861 | } /* end Z_BZIP2ED */ | ||
1862 | else | ||
1863 | { | ||
1864 | uInt uAvailOutBefore,uAvailOutAfter; | ||
1865 | const Bytef *bufBefore; | ||
1866 | uInt uOutThis; | ||
1867 | int flush=Z_SYNC_FLUSH; | ||
1868 | |||
1869 | uAvailOutBefore = pfile_in_zip_read_info->stream.avail_out; | ||
1870 | bufBefore = pfile_in_zip_read_info->stream.next_out; | ||
1871 | |||
1872 | err=inflate(&pfile_in_zip_read_info->stream,flush); | ||
1873 | |||
1874 | if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) | ||
1875 | err = Z_DATA_ERROR; | ||
1876 | |||
1877 | uAvailOutAfter = pfile_in_zip_read_info->stream.avail_out; | ||
1878 | uOutThis = uAvailOutBefore - uAvailOutAfter; | ||
1879 | |||
1880 | pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; | ||
1881 | |||
1882 | pfile_in_zip_read_info->crc32 | ||
1883 | = crc32(pfile_in_zip_read_info->crc32,bufBefore, uOutThis); | ||
1884 | |||
1885 | pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; | ||
1886 | |||
1887 | iRead += uAvailOutBefore - uAvailOutAfter; | ||
1888 | |||
1889 | if (err==Z_STREAM_END) | ||
1890 | return (iRead==0) ? UNZ_EOF : iRead; | ||
1891 | if (err!=Z_OK) | ||
1892 | break; | ||
1893 | } | ||
1894 | } | ||
1895 | |||
1896 | if (err==Z_OK) | ||
1897 | return iRead; | ||
1898 | return err; | ||
1899 | } | ||
1900 | |||
1901 | |||
1902 | /* | ||
1903 | Give the current position in uncompressed data | ||
1904 | */ | ||
1905 | extern z_off_t ZEXPORT unztell (unzFile file) | ||
1906 | { | ||
1907 | unz64_s* s; | ||
1908 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1909 | if (file==NULL) | ||
1910 | return UNZ_PARAMERROR; | ||
1911 | s=(unz64_s*)file; | ||
1912 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
1913 | |||
1914 | if (pfile_in_zip_read_info==NULL) | ||
1915 | return UNZ_PARAMERROR; | ||
1916 | |||
1917 | return (z_off_t)pfile_in_zip_read_info->stream.total_out; | ||
1918 | } | ||
1919 | |||
1920 | extern ZPOS64_T ZEXPORT unztell64 (unzFile file) | ||
1921 | { | ||
1922 | |||
1923 | unz64_s* s; | ||
1924 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1925 | if (file==NULL) | ||
1926 | return (ZPOS64_T)-1; | ||
1927 | s=(unz64_s*)file; | ||
1928 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
1929 | |||
1930 | if (pfile_in_zip_read_info==NULL) | ||
1931 | return (ZPOS64_T)-1; | ||
1932 | |||
1933 | return pfile_in_zip_read_info->total_out_64; | ||
1934 | } | ||
1935 | |||
1936 | |||
1937 | /* | ||
1938 | return 1 if the end of file was reached, 0 elsewhere | ||
1939 | */ | ||
1940 | extern int ZEXPORT unzeof (unzFile file) | ||
1941 | { | ||
1942 | unz64_s* s; | ||
1943 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1944 | if (file==NULL) | ||
1945 | return UNZ_PARAMERROR; | ||
1946 | s=(unz64_s*)file; | ||
1947 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
1948 | |||
1949 | if (pfile_in_zip_read_info==NULL) | ||
1950 | return UNZ_PARAMERROR; | ||
1951 | |||
1952 | if (pfile_in_zip_read_info->rest_read_uncompressed == 0) | ||
1953 | return 1; | ||
1954 | else | ||
1955 | return 0; | ||
1956 | } | ||
1957 | |||
1958 | |||
1959 | |||
1960 | /* | ||
1961 | Read extra field from the current file (opened by unzOpenCurrentFile) | ||
1962 | This is the local-header version of the extra field (sometimes, there is | ||
1963 | more info in the local-header version than in the central-header) | ||
1964 | |||
1965 | if buf==NULL, it return the size of the local extra field that can be read | ||
1966 | |||
1967 | if buf!=NULL, len is the size of the buffer, the extra header is copied in | ||
1968 | buf. | ||
1969 | the return value is the number of bytes copied in buf, or (if <0) | ||
1970 | the error code | ||
1971 | */ | ||
1972 | extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) | ||
1973 | { | ||
1974 | unz64_s* s; | ||
1975 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
1976 | uInt read_now; | ||
1977 | ZPOS64_T size_to_read; | ||
1978 | |||
1979 | if (file==NULL) | ||
1980 | return UNZ_PARAMERROR; | ||
1981 | s=(unz64_s*)file; | ||
1982 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
1983 | |||
1984 | if (pfile_in_zip_read_info==NULL) | ||
1985 | return UNZ_PARAMERROR; | ||
1986 | |||
1987 | size_to_read = (pfile_in_zip_read_info->size_local_extrafield - | ||
1988 | pfile_in_zip_read_info->pos_local_extrafield); | ||
1989 | |||
1990 | if (buf==NULL) | ||
1991 | return (int)size_to_read; | ||
1992 | |||
1993 | if (len>size_to_read) | ||
1994 | read_now = (uInt)size_to_read; | ||
1995 | else | ||
1996 | read_now = (uInt)len ; | ||
1997 | |||
1998 | if (read_now==0) | ||
1999 | return 0; | ||
2000 | |||
2001 | if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, | ||
2002 | pfile_in_zip_read_info->filestream, | ||
2003 | pfile_in_zip_read_info->offset_local_extrafield + | ||
2004 | pfile_in_zip_read_info->pos_local_extrafield, | ||
2005 | ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
2006 | return UNZ_ERRNO; | ||
2007 | |||
2008 | if (ZREAD64(pfile_in_zip_read_info->z_filefunc, | ||
2009 | pfile_in_zip_read_info->filestream, | ||
2010 | buf,read_now)!=read_now) | ||
2011 | return UNZ_ERRNO; | ||
2012 | |||
2013 | return (int)read_now; | ||
2014 | } | ||
2015 | |||
2016 | /* | ||
2017 | Close the file in zip opened with unzipOpenCurrentFile | ||
2018 | Return UNZ_CRCERROR if all the file was read but the CRC is not good | ||
2019 | */ | ||
2020 | extern int ZEXPORT unzCloseCurrentFile (unzFile file) | ||
2021 | { | ||
2022 | int err=UNZ_OK; | ||
2023 | |||
2024 | unz64_s* s; | ||
2025 | file_in_zip64_read_info_s* pfile_in_zip_read_info; | ||
2026 | if (file==NULL) | ||
2027 | return UNZ_PARAMERROR; | ||
2028 | s=(unz64_s*)file; | ||
2029 | pfile_in_zip_read_info=s->pfile_in_zip_read; | ||
2030 | |||
2031 | if (pfile_in_zip_read_info==NULL) | ||
2032 | return UNZ_PARAMERROR; | ||
2033 | |||
2034 | |||
2035 | if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && | ||
2036 | (!pfile_in_zip_read_info->raw)) | ||
2037 | { | ||
2038 | if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) | ||
2039 | err=UNZ_CRCERROR; | ||
2040 | } | ||
2041 | |||
2042 | |||
2043 | TRYFREE(pfile_in_zip_read_info->read_buffer); | ||
2044 | pfile_in_zip_read_info->read_buffer = NULL; | ||
2045 | if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) | ||
2046 | inflateEnd(&pfile_in_zip_read_info->stream); | ||
2047 | #ifdef HAVE_BZIP2 | ||
2048 | else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) | ||
2049 | BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); | ||
2050 | #endif | ||
2051 | |||
2052 | |||
2053 | pfile_in_zip_read_info->stream_initialised = 0; | ||
2054 | TRYFREE(pfile_in_zip_read_info); | ||
2055 | |||
2056 | s->pfile_in_zip_read=NULL; | ||
2057 | |||
2058 | return err; | ||
2059 | } | ||
2060 | |||
2061 | |||
2062 | /* | ||
2063 | Get the global comment string of the ZipFile, in the szComment buffer. | ||
2064 | uSizeBuf is the size of the szComment buffer. | ||
2065 | return the number of byte copied or an error code <0 | ||
2066 | */ | ||
2067 | extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) | ||
2068 | { | ||
2069 | unz64_s* s; | ||
2070 | uLong uReadThis ; | ||
2071 | if (file==NULL) | ||
2072 | return (int)UNZ_PARAMERROR; | ||
2073 | s=(unz64_s*)file; | ||
2074 | |||
2075 | uReadThis = uSizeBuf; | ||
2076 | if (uReadThis>s->gi.size_comment) | ||
2077 | uReadThis = s->gi.size_comment; | ||
2078 | |||
2079 | if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
2080 | return UNZ_ERRNO; | ||
2081 | |||
2082 | if (uReadThis>0) | ||
2083 | { | ||
2084 | *szComment='\0'; | ||
2085 | if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) | ||
2086 | return UNZ_ERRNO; | ||
2087 | } | ||
2088 | |||
2089 | if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) | ||
2090 | *(szComment+s->gi.size_comment)='\0'; | ||
2091 | return (int)uReadThis; | ||
2092 | } | ||
2093 | |||
2094 | /* Additions by RX '2004 */ | ||
2095 | extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) | ||
2096 | { | ||
2097 | unz64_s* s; | ||
2098 | |||
2099 | if (file==NULL) | ||
2100 | return 0; /*UNZ_PARAMERROR; */ | ||
2101 | s=(unz64_s*)file; | ||
2102 | if (!s->current_file_ok) | ||
2103 | return 0; | ||
2104 | if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) | ||
2105 | if (s->num_file==s->gi.number_entry) | ||
2106 | return 0; | ||
2107 | return s->pos_in_central_dir; | ||
2108 | } | ||
2109 | |||
2110 | extern uLong ZEXPORT unzGetOffset (unzFile file) | ||
2111 | { | ||
2112 | ZPOS64_T offset64; | ||
2113 | |||
2114 | if (file==NULL) | ||
2115 | return 0; /*UNZ_PARAMERROR; */ | ||
2116 | offset64 = unzGetOffset64(file); | ||
2117 | return (uLong)offset64; | ||
2118 | } | ||
2119 | |||
2120 | extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) | ||
2121 | { | ||
2122 | unz64_s* s; | ||
2123 | int err; | ||
2124 | |||
2125 | if (file==NULL) | ||
2126 | return UNZ_PARAMERROR; | ||
2127 | s=(unz64_s*)file; | ||
2128 | |||
2129 | s->pos_in_central_dir = pos; | ||
2130 | s->num_file = s->gi.number_entry; /* hack */ | ||
2131 | err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, | ||
2132 | &s->cur_file_info_internal, | ||
2133 | NULL,0,NULL,0,NULL,0); | ||
2134 | s->current_file_ok = (err == UNZ_OK); | ||
2135 | return err; | ||
2136 | } | ||
2137 | |||
2138 | extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) | ||
2139 | { | ||
2140 | return unzSetOffset64(file,pos); | ||
2141 | } | ||
2142 | |||
2143 | |||
2144 | int ZEXPORT unzSetFlags(unzFile file, unsigned flags) | ||
2145 | { | ||
2146 | unz64_s* s; | ||
2147 | if (file == NULL) | ||
2148 | return UNZ_PARAMERROR; | ||
2149 | s = (unz64_s*)file; | ||
2150 | s->flags |= flags; | ||
2151 | return UNZ_OK; | ||
2152 | } | ||
2153 | |||
2154 | |||
2155 | int ZEXPORT unzClearFlags(unzFile file, unsigned flags) | ||
2156 | { | ||
2157 | unz64_s* s; | ||
2158 | if (file == NULL) | ||
2159 | return UNZ_PARAMERROR; | ||
2160 | s = (unz64_s*)file; | ||
2161 | s->flags &= ~flags; | ||
2162 | return UNZ_OK; | ||
2163 | } | ||
diff --git a/utils/rbutilqt/quazip/unzip.h b/utils/rbutilqt/quazip/unzip.h new file mode 100644 index 0000000000..fdefa2217a --- /dev/null +++ b/utils/rbutilqt/quazip/unzip.h | |||
@@ -0,0 +1,461 @@ | |||
1 | /* unzip.h -- IO for uncompress .zip files using zlib | ||
2 | Version 1.1, February 14h, 2010 | ||
3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | ||
4 | |||
5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) | ||
6 | |||
7 | Modifications of Unzip for Zip64 | ||
8 | Copyright (C) 2007-2008 Even Rouault | ||
9 | |||
10 | Modifications for Zip64 support on both zip and unzip | ||
11 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | ||
12 | |||
13 | For more info read MiniZip_info.txt | ||
14 | |||
15 | --------------------------------------------------------------------------------- | ||
16 | |||
17 | Condition of use and distribution are the same than zlib : | ||
18 | |||
19 | This software is provided 'as-is', without any express or implied | ||
20 | warranty. In no event will the authors be held liable for any damages | ||
21 | arising from the use of this software. | ||
22 | |||
23 | Permission is granted to anyone to use this software for any purpose, | ||
24 | including commercial applications, and to alter it and redistribute it | ||
25 | freely, subject to the following restrictions: | ||
26 | |||
27 | 1. The origin of this software must not be misrepresented; you must not | ||
28 | claim that you wrote the original software. If you use this software | ||
29 | in a product, an acknowledgment in the product documentation would be | ||
30 | appreciated but is not required. | ||
31 | 2. Altered source versions must be plainly marked as such, and must not be | ||
32 | misrepresented as being the original software. | ||
33 | 3. This notice may not be removed or altered from any source distribution. | ||
34 | |||
35 | --------------------------------------------------------------------------------- | ||
36 | |||
37 | Changes | ||
38 | |||
39 | See header of unzip64.c | ||
40 | |||
41 | --------------------------------------------------------------------------- | ||
42 | |||
43 | As per the requirement above, this file is plainly marked as modified | ||
44 | by Sergey A. Tachenov. Most modifications include the I/O API redesign | ||
45 | to support QIODevice interface. Some improvements and small fixes were also made. | ||
46 | */ | ||
47 | |||
48 | #ifndef _unz64_H | ||
49 | #define _unz64_H | ||
50 | |||
51 | #ifdef __cplusplus | ||
52 | extern "C" { | ||
53 | #endif | ||
54 | |||
55 | #ifndef _ZLIB_H | ||
56 | #include <zlib.h> | ||
57 | #endif | ||
58 | |||
59 | #ifndef _ZLIBIOAPI_H | ||
60 | #include "ioapi.h" | ||
61 | #endif | ||
62 | |||
63 | #ifdef HAVE_BZIP2 | ||
64 | #include "bzlib.h" | ||
65 | #endif | ||
66 | |||
67 | #define Z_BZIP2ED 12 | ||
68 | |||
69 | #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) | ||
70 | /* like the STRICT of WIN32, we define a pointer that cannot be converted | ||
71 | from (void*) without cast */ | ||
72 | typedef struct TagunzFile__ { int unused; } unzFile__; | ||
73 | typedef unzFile__ *unzFile; | ||
74 | #else | ||
75 | typedef voidp unzFile; | ||
76 | #endif | ||
77 | |||
78 | |||
79 | #define UNZ_OK (0) | ||
80 | #define UNZ_END_OF_LIST_OF_FILE (-100) | ||
81 | #define UNZ_ERRNO (Z_ERRNO) | ||
82 | #define UNZ_EOF (0) | ||
83 | #define UNZ_PARAMERROR (-102) | ||
84 | #define UNZ_BADZIPFILE (-103) | ||
85 | #define UNZ_INTERNALERROR (-104) | ||
86 | #define UNZ_CRCERROR (-105) | ||
87 | |||
88 | #define UNZ_AUTO_CLOSE 0x01u | ||
89 | #define UNZ_DEFAULT_FLAGS UNZ_AUTO_CLOSE | ||
90 | #define UNZ_ENCODING_UTF8 0x0800u | ||
91 | |||
92 | /* tm_unz contain date/time info */ | ||
93 | typedef struct tm_unz_s | ||
94 | { | ||
95 | uInt tm_sec; /* seconds after the minute - [0,59] */ | ||
96 | uInt tm_min; /* minutes after the hour - [0,59] */ | ||
97 | uInt tm_hour; /* hours since midnight - [0,23] */ | ||
98 | uInt tm_mday; /* day of the month - [1,31] */ | ||
99 | uInt tm_mon; /* months since January - [0,11] */ | ||
100 | uInt tm_year; /* years - [1980..2044] */ | ||
101 | } tm_unz; | ||
102 | |||
103 | /* unz_global_info structure contain global data about the ZIPfile | ||
104 | These data comes from the end of central dir */ | ||
105 | typedef struct unz_global_info64_s | ||
106 | { | ||
107 | ZPOS64_T number_entry; /* total number of entries in | ||
108 | the central dir on this disk */ | ||
109 | uLong size_comment; /* size of the global comment of the zipfile */ | ||
110 | } unz_global_info64; | ||
111 | |||
112 | typedef struct unz_global_info_s | ||
113 | { | ||
114 | uLong number_entry; /* total number of entries in | ||
115 | the central dir on this disk */ | ||
116 | uLong size_comment; /* size of the global comment of the zipfile */ | ||
117 | } unz_global_info; | ||
118 | |||
119 | /* unz_file_info contain information about a file in the zipfile */ | ||
120 | typedef struct unz_file_info64_s | ||
121 | { | ||
122 | uLong version; /* version made by 2 bytes */ | ||
123 | uLong version_needed; /* version needed to extract 2 bytes */ | ||
124 | uLong flag; /* general purpose bit flag 2 bytes */ | ||
125 | uLong compression_method; /* compression method 2 bytes */ | ||
126 | uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ | ||
127 | uLong crc; /* crc-32 4 bytes */ | ||
128 | ZPOS64_T compressed_size; /* compressed size 8 bytes */ | ||
129 | ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ | ||
130 | uLong size_filename; /* filename length 2 bytes */ | ||
131 | uLong size_file_extra; /* extra field length 2 bytes */ | ||
132 | uLong size_file_comment; /* file comment length 2 bytes */ | ||
133 | |||
134 | uLong disk_num_start; /* disk number start 2 bytes */ | ||
135 | uLong internal_fa; /* internal file attributes 2 bytes */ | ||
136 | uLong external_fa; /* external file attributes 4 bytes */ | ||
137 | |||
138 | tm_unz tmu_date; | ||
139 | } unz_file_info64; | ||
140 | |||
141 | typedef struct unz_file_info_s | ||
142 | { | ||
143 | uLong version; /* version made by 2 bytes */ | ||
144 | uLong version_needed; /* version needed to extract 2 bytes */ | ||
145 | uLong flag; /* general purpose bit flag 2 bytes */ | ||
146 | uLong compression_method; /* compression method 2 bytes */ | ||
147 | uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ | ||
148 | uLong crc; /* crc-32 4 bytes */ | ||
149 | uLong compressed_size; /* compressed size 4 bytes */ | ||
150 | uLong uncompressed_size; /* uncompressed size 4 bytes */ | ||
151 | uLong size_filename; /* filename length 2 bytes */ | ||
152 | uLong size_file_extra; /* extra field length 2 bytes */ | ||
153 | uLong size_file_comment; /* file comment length 2 bytes */ | ||
154 | |||
155 | uLong disk_num_start; /* disk number start 2 bytes */ | ||
156 | uLong internal_fa; /* internal file attributes 2 bytes */ | ||
157 | uLong external_fa; /* external file attributes 4 bytes */ | ||
158 | |||
159 | tm_unz tmu_date; | ||
160 | } unz_file_info; | ||
161 | |||
162 | extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, | ||
163 | const char* fileName2, | ||
164 | int iCaseSensitivity)); | ||
165 | /* | ||
166 | Compare two filename (fileName1,fileName2). | ||
167 | If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) | ||
168 | If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi | ||
169 | or strcasecmp) | ||
170 | If iCaseSenisivity = 0, case sensitivity is defaut of your operating system | ||
171 | (like 1 on Unix, 2 on Windows) | ||
172 | */ | ||
173 | |||
174 | |||
175 | extern unzFile ZEXPORT unzOpen OF((voidpf file)); | ||
176 | extern unzFile ZEXPORT unzOpen64 OF((voidpf file)); | ||
177 | /* | ||
178 | Open a Zip file. path contain the full pathname (by example, | ||
179 | on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer | ||
180 | "zlib/zlib113.zip". | ||
181 | If the zipfile cannot be opened (file don't exist or in not valid), the | ||
182 | return value is NULL. | ||
183 | Else, the return value is a unzFile Handle, usable with other function | ||
184 | of this unzip package. | ||
185 | the "64" function take a const void* pointer, because the path is just the | ||
186 | value passed to the open64_file_func callback. | ||
187 | Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path | ||
188 | is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* | ||
189 | does not describe the reality | ||
190 | */ | ||
191 | |||
192 | |||
193 | extern unzFile ZEXPORT unzOpen2 OF((voidpf file, | ||
194 | zlib_filefunc_def* pzlib_filefunc_def)); | ||
195 | /* | ||
196 | Open a Zip file, like unzOpen, but provide a set of file low level API | ||
197 | for read/write the zip file (see ioapi.h) | ||
198 | */ | ||
199 | |||
200 | extern unzFile ZEXPORT unzOpen2_64 OF((voidpf file, | ||
201 | zlib_filefunc64_def* pzlib_filefunc_def)); | ||
202 | /* | ||
203 | Open a Zip file, like unz64Open, but provide a set of file low level API | ||
204 | for read/write the zip file (see ioapi.h) | ||
205 | */ | ||
206 | |||
207 | |||
208 | /* | ||
209 | * Exported by Sergey A. Tachenov to implement some QuaZIP features. This | ||
210 | * function MAY change signature in order to implement even more features. | ||
211 | * You have been warned! | ||
212 | * */ | ||
213 | extern unzFile unzOpenInternal (voidpf file, | ||
214 | zlib_filefunc64_32_def* pzlib_filefunc64_32_def, | ||
215 | int is64bitOpenFunction, unsigned flags); | ||
216 | |||
217 | |||
218 | |||
219 | extern int ZEXPORT unzClose OF((unzFile file)); | ||
220 | /* | ||
221 | Close a ZipFile opened with unzipOpen. | ||
222 | If there is files inside the .Zip opened with unzOpenCurrentFile (see later), | ||
223 | these files MUST be closed with unzipCloseCurrentFile before call unzipClose. | ||
224 | return UNZ_OK if there is no problem. */ | ||
225 | |||
226 | extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, | ||
227 | unz_global_info *pglobal_info)); | ||
228 | |||
229 | extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, | ||
230 | unz_global_info64 *pglobal_info)); | ||
231 | |||
232 | extern int ZEXPORT unzGetFileFlags OF((unzFile file, unsigned* pflags)); | ||
233 | /* | ||
234 | Write info about the ZipFile in the *pglobal_info structure. | ||
235 | No preparation of the structure is needed | ||
236 | return UNZ_OK if there is no problem. */ | ||
237 | |||
238 | |||
239 | extern int ZEXPORT unzGetGlobalComment OF((unzFile file, | ||
240 | char *szComment, | ||
241 | uLong uSizeBuf)); | ||
242 | /* | ||
243 | Get the global comment string of the ZipFile, in the szComment buffer. | ||
244 | uSizeBuf is the size of the szComment buffer. | ||
245 | return the number of byte copied or an error code <0 | ||
246 | */ | ||
247 | |||
248 | |||
249 | /***************************************************************************/ | ||
250 | /* Unzip package allow you browse the directory of the zipfile */ | ||
251 | |||
252 | extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); | ||
253 | /* | ||
254 | Set the current file of the zipfile to the first file. | ||
255 | return UNZ_OK if there is no problem | ||
256 | */ | ||
257 | |||
258 | extern int ZEXPORT unzGoToNextFile OF((unzFile file)); | ||
259 | /* | ||
260 | Set the current file of the zipfile to the next file. | ||
261 | return UNZ_OK if there is no problem | ||
262 | return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. | ||
263 | */ | ||
264 | |||
265 | extern int ZEXPORT unzLocateFile OF((unzFile file, | ||
266 | const char *szFileName, | ||
267 | int iCaseSensitivity)); | ||
268 | /* | ||
269 | Try locate the file szFileName in the zipfile. | ||
270 | For the iCaseSensitivity signification, see unzStringFileNameCompare | ||
271 | |||
272 | return value : | ||
273 | UNZ_OK if the file is found. It becomes the current file. | ||
274 | UNZ_END_OF_LIST_OF_FILE if the file is not found | ||
275 | */ | ||
276 | |||
277 | |||
278 | /* ****************************************** */ | ||
279 | /* Ryan supplied functions */ | ||
280 | /* unz_file_info contain information about a file in the zipfile */ | ||
281 | typedef struct unz_file_pos_s | ||
282 | { | ||
283 | uLong pos_in_zip_directory; /* offset in zip file directory */ | ||
284 | uLong num_of_file; /* # of file */ | ||
285 | } unz_file_pos; | ||
286 | |||
287 | extern int ZEXPORT unzGetFilePos( | ||
288 | unzFile file, | ||
289 | unz_file_pos* file_pos); | ||
290 | |||
291 | extern int ZEXPORT unzGoToFilePos( | ||
292 | unzFile file, | ||
293 | unz_file_pos* file_pos); | ||
294 | |||
295 | typedef struct unz64_file_pos_s | ||
296 | { | ||
297 | ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ | ||
298 | ZPOS64_T num_of_file; /* # of file */ | ||
299 | } unz64_file_pos; | ||
300 | |||
301 | extern int ZEXPORT unzGetFilePos64( | ||
302 | unzFile file, | ||
303 | unz64_file_pos* file_pos); | ||
304 | |||
305 | extern int ZEXPORT unzGoToFilePos64( | ||
306 | unzFile file, | ||
307 | const unz64_file_pos* file_pos); | ||
308 | |||
309 | /* ****************************************** */ | ||
310 | |||
311 | extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, | ||
312 | unz_file_info64 *pfile_info, | ||
313 | char *szFileName, | ||
314 | uLong fileNameBufferSize, | ||
315 | void *extraField, | ||
316 | uLong extraFieldBufferSize, | ||
317 | char *szComment, | ||
318 | uLong commentBufferSize)); | ||
319 | |||
320 | extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, | ||
321 | unz_file_info *pfile_info, | ||
322 | char *szFileName, | ||
323 | uLong fileNameBufferSize, | ||
324 | void *extraField, | ||
325 | uLong extraFieldBufferSize, | ||
326 | char *szComment, | ||
327 | uLong commentBufferSize)); | ||
328 | /* | ||
329 | Get Info about the current file | ||
330 | if pfile_info!=NULL, the *pfile_info structure will contain somes info about | ||
331 | the current file | ||
332 | if szFileName!=NULL, the filemane string will be copied in szFileName | ||
333 | (fileNameBufferSize is the size of the buffer) | ||
334 | if extraField!=NULL, the extra field information will be copied in extraField | ||
335 | (extraFieldBufferSize is the size of the buffer). | ||
336 | This is the Central-header version of the extra field | ||
337 | if szComment!=NULL, the comment string of the file will be copied in szComment | ||
338 | (commentBufferSize is the size of the buffer) | ||
339 | */ | ||
340 | |||
341 | |||
342 | /** Addition for GDAL : START */ | ||
343 | |||
344 | extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); | ||
345 | |||
346 | /** Addition for GDAL : END */ | ||
347 | |||
348 | |||
349 | /***************************************************************************/ | ||
350 | /* for reading the content of the current zipfile, you can open it, read data | ||
351 | from it, and close it (you can close it before reading all the file) | ||
352 | */ | ||
353 | |||
354 | extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); | ||
355 | /* | ||
356 | Open for reading data the current file in the zipfile. | ||
357 | If there is no error, the return value is UNZ_OK. | ||
358 | */ | ||
359 | |||
360 | extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, | ||
361 | const char* password)); | ||
362 | /* | ||
363 | Open for reading data the current file in the zipfile. | ||
364 | password is a crypting password | ||
365 | If there is no error, the return value is UNZ_OK. | ||
366 | */ | ||
367 | |||
368 | extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, | ||
369 | int* method, | ||
370 | int* level, | ||
371 | int raw)); | ||
372 | /* | ||
373 | Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) | ||
374 | if raw==1 | ||
375 | *method will receive method of compression, *level will receive level of | ||
376 | compression | ||
377 | note : you can set level parameter as NULL (if you did not want known level, | ||
378 | but you CANNOT set method parameter as NULL | ||
379 | */ | ||
380 | |||
381 | extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, | ||
382 | int* method, | ||
383 | int* level, | ||
384 | int raw, | ||
385 | const char* password)); | ||
386 | /* | ||
387 | Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) | ||
388 | if raw==1 | ||
389 | *method will receive method of compression, *level will receive level of | ||
390 | compression | ||
391 | note : you can set level parameter as NULL (if you did not want known level, | ||
392 | but you CANNOT set method parameter as NULL | ||
393 | */ | ||
394 | |||
395 | |||
396 | extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); | ||
397 | /* | ||
398 | Close the file in zip opened with unzOpenCurrentFile | ||
399 | Return UNZ_CRCERROR if all the file was read but the CRC is not good | ||
400 | */ | ||
401 | |||
402 | extern int ZEXPORT unzReadCurrentFile OF((unzFile file, | ||
403 | voidp buf, | ||
404 | unsigned len)); | ||
405 | /* | ||
406 | Read bytes from the current file (opened by unzOpenCurrentFile) | ||
407 | buf contain buffer where data must be copied | ||
408 | len the size of buf. | ||
409 | |||
410 | return the number of byte copied if somes bytes are copied | ||
411 | return 0 if the end of file was reached | ||
412 | return <0 with error code if there is an error | ||
413 | (UNZ_ERRNO for IO error, or zLib error for uncompress error) | ||
414 | */ | ||
415 | |||
416 | extern z_off_t ZEXPORT unztell OF((unzFile file)); | ||
417 | |||
418 | extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); | ||
419 | /* | ||
420 | Give the current position in uncompressed data | ||
421 | */ | ||
422 | |||
423 | extern int ZEXPORT unzeof OF((unzFile file)); | ||
424 | /* | ||
425 | return 1 if the end of file was reached, 0 elsewhere | ||
426 | */ | ||
427 | |||
428 | extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, | ||
429 | voidp buf, | ||
430 | unsigned len)); | ||
431 | /* | ||
432 | Read extra field from the current file (opened by unzOpenCurrentFile) | ||
433 | This is the local-header version of the extra field (sometimes, there is | ||
434 | more info in the local-header version than in the central-header) | ||
435 | |||
436 | if buf==NULL, it return the size of the local extra field | ||
437 | |||
438 | if buf!=NULL, len is the size of the buffer, the extra header is copied in | ||
439 | buf. | ||
440 | the return value is the number of bytes copied in buf, or (if <0) | ||
441 | the error code | ||
442 | */ | ||
443 | |||
444 | /***************************************************************************/ | ||
445 | |||
446 | /* Get the current file offset */ | ||
447 | extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); | ||
448 | extern uLong ZEXPORT unzGetOffset (unzFile file); | ||
449 | |||
450 | /* Set the current file offset */ | ||
451 | extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); | ||
452 | extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); | ||
453 | |||
454 | extern int ZEXPORT unzSetFlags(unzFile file, unsigned flags); | ||
455 | extern int ZEXPORT unzClearFlags(unzFile file, unsigned flags); | ||
456 | |||
457 | #ifdef __cplusplus | ||
458 | } | ||
459 | #endif | ||
460 | |||
461 | #endif /* _unz64_H */ | ||
diff --git a/utils/rbutilqt/quazip/zip.c b/utils/rbutilqt/quazip/zip.c new file mode 100644 index 0000000000..0f3deb04c1 --- /dev/null +++ b/utils/rbutilqt/quazip/zip.c | |||
@@ -0,0 +1,2111 @@ | |||
1 | /* zip.c -- IO on .zip files using zlib | ||
2 | Version 1.1, February 14h, 2010 | ||
3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | ||
4 | |||
5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) | ||
6 | |||
7 | Modifications for Zip64 support | ||
8 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | ||
9 | |||
10 | For more info read MiniZip_info.txt | ||
11 | |||
12 | Modifications for QIODevice support and other QuaZIP fixes | ||
13 | Copyright (C) 2005-2014 Sergey A. Tachenov | ||
14 | |||
15 | Fixing static code analysis issues | ||
16 | Copyright (C) 2016 Intel Deutschland GmbH | ||
17 | |||
18 | Changes | ||
19 | Oct-2009 - Mathias Svensson - Remove old C style function prototypes | ||
20 | Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives | ||
21 | Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. | ||
22 | Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data | ||
23 | It is used when recreting zip archive with RAW when deleting items from a zip. | ||
24 | ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. | ||
25 | Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) | ||
26 | Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer | ||
27 | |||
28 | */ | ||
29 | |||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <stdlib.h> | ||
33 | #include <string.h> | ||
34 | #include <time.h> | ||
35 | |||
36 | #include <zlib.h> | ||
37 | #if (ZLIB_VERNUM < 0x1270) | ||
38 | typedef uLongf z_crc_t; | ||
39 | #endif | ||
40 | #include "zip.h" | ||
41 | |||
42 | #ifdef STDC | ||
43 | # include <stddef.h> | ||
44 | # include <string.h> | ||
45 | # include <stdlib.h> | ||
46 | #endif | ||
47 | #ifdef NO_ERRNO_H | ||
48 | extern int errno; | ||
49 | #else | ||
50 | # include <errno.h> | ||
51 | #endif | ||
52 | |||
53 | |||
54 | #ifndef local | ||
55 | # define local static | ||
56 | #endif | ||
57 | /* compile with -Dlocal if your debugger can't find static symbols */ | ||
58 | |||
59 | #ifndef VERSIONMADEBY | ||
60 | # define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */ | ||
61 | #endif | ||
62 | |||
63 | #ifndef Z_BUFSIZE | ||
64 | #define Z_BUFSIZE (64*1024) /* (16384) */ | ||
65 | #endif | ||
66 | |||
67 | #ifndef Z_MAXFILENAMEINZIP | ||
68 | #define Z_MAXFILENAMEINZIP (256) | ||
69 | #endif | ||
70 | |||
71 | #ifndef ALLOC | ||
72 | # define ALLOC(size) (malloc(size)) | ||
73 | #endif | ||
74 | #ifndef TRYFREE | ||
75 | # define TRYFREE(p) {if (p) free(p);} | ||
76 | #endif | ||
77 | |||
78 | /* | ||
79 | #define SIZECENTRALDIRITEM (0x2e) | ||
80 | #define SIZEZIPLOCALHEADER (0x1e) | ||
81 | */ | ||
82 | |||
83 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ | ||
84 | |||
85 | |||
86 | /* NOT sure that this work on ALL platform */ | ||
87 | #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) | ||
88 | |||
89 | #ifndef SEEK_CUR | ||
90 | #define SEEK_CUR 1 | ||
91 | #endif | ||
92 | |||
93 | #ifndef SEEK_END | ||
94 | #define SEEK_END 2 | ||
95 | #endif | ||
96 | |||
97 | #ifndef SEEK_SET | ||
98 | #define SEEK_SET 0 | ||
99 | #endif | ||
100 | |||
101 | #ifndef DEF_MEM_LEVEL | ||
102 | #if MAX_MEM_LEVEL >= 8 | ||
103 | # define DEF_MEM_LEVEL 8 | ||
104 | #else | ||
105 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL | ||
106 | #endif | ||
107 | #endif | ||
108 | const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; | ||
109 | |||
110 | |||
111 | #define SIZEDATA_INDATABLOCK (4096-(4*4)) | ||
112 | |||
113 | #define LOCALHEADERMAGIC (0x04034b50) | ||
114 | #define DESCRIPTORHEADERMAGIC (0x08074b50) | ||
115 | #define CENTRALHEADERMAGIC (0x02014b50) | ||
116 | #define ENDHEADERMAGIC (0x06054b50) | ||
117 | #define ZIP64ENDHEADERMAGIC (0x6064b50) | ||
118 | #define ZIP64ENDLOCHEADERMAGIC (0x7064b50) | ||
119 | |||
120 | #define FLAG_LOCALHEADER_OFFSET (0x06) | ||
121 | #define CRC_LOCALHEADER_OFFSET (0x0e) | ||
122 | |||
123 | #define SIZECENTRALHEADER (0x2e) /* 46 */ | ||
124 | |||
125 | typedef struct linkedlist_datablock_internal_s | ||
126 | { | ||
127 | struct linkedlist_datablock_internal_s* next_datablock; | ||
128 | uLong avail_in_this_block; | ||
129 | uLong filled_in_this_block; | ||
130 | uLong unused; /* for future use and alignement */ | ||
131 | unsigned char data[SIZEDATA_INDATABLOCK]; | ||
132 | } linkedlist_datablock_internal; | ||
133 | |||
134 | typedef struct linkedlist_data_s | ||
135 | { | ||
136 | linkedlist_datablock_internal* first_block; | ||
137 | linkedlist_datablock_internal* last_block; | ||
138 | } linkedlist_data; | ||
139 | |||
140 | |||
141 | typedef struct | ||
142 | { | ||
143 | z_stream stream; /* zLib stream structure for inflate */ | ||
144 | #ifdef HAVE_BZIP2 | ||
145 | bz_stream bstream; /* bzLib stream structure for bziped */ | ||
146 | #endif | ||
147 | |||
148 | int stream_initialised; /* 1 is stream is initialised */ | ||
149 | uInt pos_in_buffered_data; /* last written byte in buffered_data */ | ||
150 | |||
151 | ZPOS64_T pos_local_header; /* offset of the local header of the file | ||
152 | currenty writing */ | ||
153 | char* central_header; /* central header data for the current file */ | ||
154 | uLong size_centralExtra; | ||
155 | uLong size_centralheader; /* size of the central header for cur file */ | ||
156 | uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ | ||
157 | uLong flag; /* flag of the file currently writing */ | ||
158 | |||
159 | int method; /* compression method of file currenty wr.*/ | ||
160 | int raw; /* 1 for directly writing raw data */ | ||
161 | Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ | ||
162 | uLong dosDate; | ||
163 | uLong crc32; | ||
164 | int encrypt; | ||
165 | int zip64; /* Add ZIP64 extened information in the extra field */ | ||
166 | ZPOS64_T pos_zip64extrainfo; | ||
167 | ZPOS64_T totalCompressedData; | ||
168 | ZPOS64_T totalUncompressedData; | ||
169 | #ifndef NOCRYPT | ||
170 | unsigned long keys[3]; /* keys defining the pseudo-random sequence */ | ||
171 | const z_crc_t FAR * pcrc_32_tab; | ||
172 | int crypt_header_size; | ||
173 | #endif | ||
174 | } curfile64_info; | ||
175 | |||
176 | typedef struct | ||
177 | { | ||
178 | zlib_filefunc64_32_def z_filefunc; | ||
179 | voidpf filestream; /* io structore of the zipfile */ | ||
180 | linkedlist_data central_dir;/* datablock with central dir in construction*/ | ||
181 | int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ | ||
182 | curfile64_info ci; /* info on the file curretly writing */ | ||
183 | |||
184 | ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ | ||
185 | ZPOS64_T add_position_when_writting_offset; | ||
186 | ZPOS64_T number_entry; | ||
187 | |||
188 | #ifndef NO_ADDFILEINEXISTINGZIP | ||
189 | char *globalcomment; | ||
190 | #endif | ||
191 | |||
192 | unsigned flags; | ||
193 | |||
194 | } zip64_internal; | ||
195 | |||
196 | |||
197 | #ifndef NOCRYPT | ||
198 | #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED | ||
199 | #include "minizip_crypt.h" | ||
200 | #endif | ||
201 | |||
202 | local linkedlist_datablock_internal* allocate_new_datablock() | ||
203 | { | ||
204 | linkedlist_datablock_internal* ldi; | ||
205 | ldi = (linkedlist_datablock_internal*) | ||
206 | ALLOC(sizeof(linkedlist_datablock_internal)); | ||
207 | if (ldi!=NULL) | ||
208 | { | ||
209 | ldi->next_datablock = NULL ; | ||
210 | ldi->filled_in_this_block = 0 ; | ||
211 | ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; | ||
212 | } | ||
213 | return ldi; | ||
214 | } | ||
215 | |||
216 | local void free_datablock(linkedlist_datablock_internal* ldi) | ||
217 | { | ||
218 | while (ldi!=NULL) | ||
219 | { | ||
220 | linkedlist_datablock_internal* ldinext = ldi->next_datablock; | ||
221 | TRYFREE(ldi); | ||
222 | ldi = ldinext; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | local void init_linkedlist(linkedlist_data* ll) | ||
227 | { | ||
228 | ll->first_block = ll->last_block = NULL; | ||
229 | } | ||
230 | |||
231 | local void free_linkedlist(linkedlist_data* ll) | ||
232 | { | ||
233 | free_datablock(ll->first_block); | ||
234 | ll->first_block = ll->last_block = NULL; | ||
235 | } | ||
236 | |||
237 | |||
238 | local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) | ||
239 | { | ||
240 | linkedlist_datablock_internal* ldi; | ||
241 | const unsigned char* from_copy; | ||
242 | |||
243 | if (ll==NULL) | ||
244 | return ZIP_INTERNALERROR; | ||
245 | |||
246 | if (ll->last_block == NULL) | ||
247 | { | ||
248 | ll->first_block = ll->last_block = allocate_new_datablock(); | ||
249 | if (ll->first_block == NULL) | ||
250 | return ZIP_INTERNALERROR; | ||
251 | } | ||
252 | |||
253 | ldi = ll->last_block; | ||
254 | from_copy = (unsigned char*)buf; | ||
255 | |||
256 | while (len>0) | ||
257 | { | ||
258 | uInt copy_this; | ||
259 | uInt i; | ||
260 | unsigned char* to_copy; | ||
261 | |||
262 | if (ldi->avail_in_this_block==0) | ||
263 | { | ||
264 | ldi->next_datablock = allocate_new_datablock(); | ||
265 | if (ldi->next_datablock == NULL) | ||
266 | return ZIP_INTERNALERROR; | ||
267 | ldi = ldi->next_datablock ; | ||
268 | ll->last_block = ldi; | ||
269 | } | ||
270 | |||
271 | if (ldi->avail_in_this_block < len) | ||
272 | copy_this = (uInt)ldi->avail_in_this_block; | ||
273 | else | ||
274 | copy_this = (uInt)len; | ||
275 | |||
276 | to_copy = &(ldi->data[ldi->filled_in_this_block]); | ||
277 | |||
278 | for (i=0;i<copy_this;i++) | ||
279 | *(to_copy+i)=*(from_copy+i); | ||
280 | |||
281 | ldi->filled_in_this_block += copy_this; | ||
282 | ldi->avail_in_this_block -= copy_this; | ||
283 | from_copy += copy_this ; | ||
284 | len -= copy_this; | ||
285 | } | ||
286 | return ZIP_OK; | ||
287 | } | ||
288 | |||
289 | |||
290 | |||
291 | /****************************************************************************/ | ||
292 | |||
293 | #ifndef NO_ADDFILEINEXISTINGZIP | ||
294 | /* =========================================================================== | ||
295 | Inputs a long in LSB order to the given file | ||
296 | nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) | ||
297 | */ | ||
298 | |||
299 | local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); | ||
300 | local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) | ||
301 | { | ||
302 | unsigned char buf[8]; | ||
303 | int n; | ||
304 | for (n = 0; n < nbByte; n++) | ||
305 | { | ||
306 | buf[n] = (unsigned char)(x & 0xff); | ||
307 | x >>= 8; | ||
308 | } | ||
309 | if (x != 0) | ||
310 | { /* data overflow - hack for ZIP64 (X Roche) */ | ||
311 | for (n = 0; n < nbByte; n++) | ||
312 | { | ||
313 | buf[n] = 0xff; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) | ||
318 | return ZIP_ERRNO; | ||
319 | else | ||
320 | return ZIP_OK; | ||
321 | } | ||
322 | |||
323 | local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); | ||
324 | local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) | ||
325 | { | ||
326 | unsigned char* buf=(unsigned char*)dest; | ||
327 | int n; | ||
328 | for (n = 0; n < nbByte; n++) { | ||
329 | buf[n] = (unsigned char)(x & 0xff); | ||
330 | x >>= 8; | ||
331 | } | ||
332 | |||
333 | if (x != 0) | ||
334 | { /* data overflow - hack for ZIP64 */ | ||
335 | for (n = 0; n < nbByte; n++) | ||
336 | { | ||
337 | buf[n] = 0xff; | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | |||
342 | /****************************************************************************/ | ||
343 | |||
344 | |||
345 | local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) | ||
346 | { | ||
347 | uLong year = (uLong)ptm->tm_year; | ||
348 | if (year>=1980) | ||
349 | year-=1980; | ||
350 | else if (year>=80) | ||
351 | year-=80; | ||
352 | return | ||
353 | (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | | ||
354 | ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); | ||
355 | } | ||
356 | |||
357 | |||
358 | /****************************************************************************/ | ||
359 | |||
360 | local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); | ||
361 | |||
362 | local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) | ||
363 | { | ||
364 | unsigned char c; | ||
365 | int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); | ||
366 | if (err==1) | ||
367 | { | ||
368 | *pi = (int)c; | ||
369 | return ZIP_OK; | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | if (ZERROR64(*pzlib_filefunc_def,filestream)) | ||
374 | return ZIP_ERRNO; | ||
375 | else | ||
376 | return ZIP_EOF; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | |||
381 | /* =========================================================================== | ||
382 | Reads a long in LSB order from the given gz_stream. Sets | ||
383 | */ | ||
384 | local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); | ||
385 | |||
386 | local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) | ||
387 | { | ||
388 | uLong x ; | ||
389 | int i = 0; | ||
390 | int err; | ||
391 | |||
392 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
393 | x = (uLong)i; | ||
394 | |||
395 | if (err==ZIP_OK) | ||
396 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
397 | x += ((uLong)i)<<8; | ||
398 | |||
399 | if (err==ZIP_OK) | ||
400 | *pX = x; | ||
401 | else | ||
402 | *pX = 0; | ||
403 | return err; | ||
404 | } | ||
405 | |||
406 | local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); | ||
407 | |||
408 | local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) | ||
409 | { | ||
410 | uLong x ; | ||
411 | int i = 0; | ||
412 | int err; | ||
413 | |||
414 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
415 | x = (uLong)i; | ||
416 | |||
417 | if (err==ZIP_OK) | ||
418 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
419 | x += ((uLong)i)<<8; | ||
420 | |||
421 | if (err==ZIP_OK) | ||
422 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
423 | x += ((uLong)i)<<16; | ||
424 | |||
425 | if (err==ZIP_OK) | ||
426 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
427 | x += ((uLong)i)<<24; | ||
428 | |||
429 | if (err==ZIP_OK) | ||
430 | *pX = x; | ||
431 | else | ||
432 | *pX = 0; | ||
433 | return err; | ||
434 | } | ||
435 | |||
436 | local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); | ||
437 | |||
438 | |||
439 | local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) | ||
440 | { | ||
441 | ZPOS64_T x; | ||
442 | int i = 0; | ||
443 | int err; | ||
444 | |||
445 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
446 | x = (ZPOS64_T)i; | ||
447 | |||
448 | if (err==ZIP_OK) | ||
449 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
450 | x += ((ZPOS64_T)i)<<8; | ||
451 | |||
452 | if (err==ZIP_OK) | ||
453 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
454 | x += ((ZPOS64_T)i)<<16; | ||
455 | |||
456 | if (err==ZIP_OK) | ||
457 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
458 | x += ((ZPOS64_T)i)<<24; | ||
459 | |||
460 | if (err==ZIP_OK) | ||
461 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
462 | x += ((ZPOS64_T)i)<<32; | ||
463 | |||
464 | if (err==ZIP_OK) | ||
465 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
466 | x += ((ZPOS64_T)i)<<40; | ||
467 | |||
468 | if (err==ZIP_OK) | ||
469 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
470 | x += ((ZPOS64_T)i)<<48; | ||
471 | |||
472 | if (err==ZIP_OK) | ||
473 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); | ||
474 | x += ((ZPOS64_T)i)<<56; | ||
475 | |||
476 | if (err==ZIP_OK) | ||
477 | *pX = x; | ||
478 | else | ||
479 | *pX = 0; | ||
480 | |||
481 | return err; | ||
482 | } | ||
483 | |||
484 | #ifndef BUFREADCOMMENT | ||
485 | #define BUFREADCOMMENT (0x400) | ||
486 | #endif | ||
487 | /* | ||
488 | Locate the Central directory of a zipfile (at the end, just before | ||
489 | the global comment) | ||
490 | */ | ||
491 | local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); | ||
492 | |||
493 | local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) | ||
494 | { | ||
495 | unsigned char* buf; | ||
496 | ZPOS64_T uSizeFile; | ||
497 | ZPOS64_T uBackRead; | ||
498 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | ||
499 | ZPOS64_T uPosFound=0; | ||
500 | |||
501 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | ||
502 | return 0; | ||
503 | |||
504 | |||
505 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | ||
506 | |||
507 | if (uMaxBack>uSizeFile) | ||
508 | uMaxBack = uSizeFile; | ||
509 | |||
510 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | ||
511 | if (buf==NULL) | ||
512 | return 0; | ||
513 | |||
514 | uBackRead = 4; | ||
515 | while (uBackRead<uMaxBack) | ||
516 | { | ||
517 | uLong uReadSize; | ||
518 | ZPOS64_T uReadPos ; | ||
519 | int i; | ||
520 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | ||
521 | uBackRead = uMaxBack; | ||
522 | else | ||
523 | uBackRead+=BUFREADCOMMENT; | ||
524 | uReadPos = uSizeFile-uBackRead ; | ||
525 | |||
526 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | ||
527 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | ||
528 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
529 | break; | ||
530 | |||
531 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | ||
532 | break; | ||
533 | |||
534 | for (i=(int)uReadSize-3; (i--)>0;){ | ||
535 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && | ||
536 | ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) | ||
537 | { | ||
538 | uPosFound = uReadPos+i; | ||
539 | break; | ||
540 | } | ||
541 | } | ||
542 | |||
543 | if (uPosFound!=0) | ||
544 | break; | ||
545 | } | ||
546 | TRYFREE(buf); | ||
547 | return uPosFound; | ||
548 | } | ||
549 | |||
550 | /* | ||
551 | Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before | ||
552 | the global comment) | ||
553 | */ | ||
554 | local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); | ||
555 | |||
556 | local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) | ||
557 | { | ||
558 | unsigned char* buf; | ||
559 | ZPOS64_T uSizeFile; | ||
560 | ZPOS64_T uBackRead; | ||
561 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ | ||
562 | ZPOS64_T uPosFound=0; | ||
563 | uLong uL; | ||
564 | ZPOS64_T relativeOffset; | ||
565 | |||
566 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) | ||
567 | return 0; | ||
568 | |||
569 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); | ||
570 | |||
571 | if (uMaxBack>uSizeFile) | ||
572 | uMaxBack = uSizeFile; | ||
573 | |||
574 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); | ||
575 | if (buf==NULL) | ||
576 | return 0; | ||
577 | |||
578 | uBackRead = 4; | ||
579 | while (uBackRead<uMaxBack) | ||
580 | { | ||
581 | uLong uReadSize; | ||
582 | ZPOS64_T uReadPos; | ||
583 | int i; | ||
584 | if (uBackRead+BUFREADCOMMENT>uMaxBack) | ||
585 | uBackRead = uMaxBack; | ||
586 | else | ||
587 | uBackRead+=BUFREADCOMMENT; | ||
588 | uReadPos = uSizeFile-uBackRead ; | ||
589 | |||
590 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? | ||
591 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); | ||
592 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
593 | break; | ||
594 | |||
595 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) | ||
596 | break; | ||
597 | |||
598 | for (i=(int)uReadSize-3; (i--)>0;) | ||
599 | { | ||
600 | /* Signature "0x07064b50" Zip64 end of central directory locater */ | ||
601 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) | ||
602 | { | ||
603 | uPosFound = uReadPos+i; | ||
604 | break; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | if (uPosFound!=0) | ||
609 | break; | ||
610 | } | ||
611 | |||
612 | TRYFREE(buf); | ||
613 | if (uPosFound == 0) | ||
614 | return 0; | ||
615 | |||
616 | /* Zip64 end of central directory locator */ | ||
617 | if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
618 | return 0; | ||
619 | |||
620 | /* the signature, already checked */ | ||
621 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) | ||
622 | return 0; | ||
623 | |||
624 | /* number of the disk with the start of the zip64 end of central directory */ | ||
625 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) | ||
626 | return 0; | ||
627 | if (uL != 0) | ||
628 | return 0; | ||
629 | |||
630 | /* relative offset of the zip64 end of central directory record */ | ||
631 | if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) | ||
632 | return 0; | ||
633 | |||
634 | /* total number of disks */ | ||
635 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) | ||
636 | return 0; | ||
637 | if (uL != 1) | ||
638 | return 0; | ||
639 | |||
640 | /* Goto Zip64 end of central directory record */ | ||
641 | if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
642 | return 0; | ||
643 | |||
644 | /* the signature */ | ||
645 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) | ||
646 | return 0; | ||
647 | |||
648 | if (uL != 0x06064b50) /* signature of 'Zip64 end of central directory' */ | ||
649 | return 0; | ||
650 | |||
651 | return relativeOffset; | ||
652 | } | ||
653 | |||
654 | int LoadCentralDirectoryRecord(zip64_internal* pziinit) | ||
655 | { | ||
656 | int err=ZIP_OK; | ||
657 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ | ||
658 | |||
659 | ZPOS64_T size_central_dir; /* size of the central directory */ | ||
660 | ZPOS64_T offset_central_dir; /* offset of start of central directory */ | ||
661 | ZPOS64_T central_pos; | ||
662 | uLong uL; | ||
663 | |||
664 | uLong number_disk; /* number of the current dist, used for | ||
665 | spaning ZIP, unsupported, always 0*/ | ||
666 | uLong number_disk_with_CD; /* number the the disk with central dir, used | ||
667 | for spaning ZIP, unsupported, always 0*/ | ||
668 | ZPOS64_T number_entry; | ||
669 | ZPOS64_T number_entry_CD; /* total number of entries in | ||
670 | the central dir | ||
671 | (same than number_entry on nospan) */ | ||
672 | uLong VersionMadeBy; | ||
673 | uLong VersionNeeded; | ||
674 | uLong size_comment; | ||
675 | |||
676 | int hasZIP64Record = 0; | ||
677 | |||
678 | /* check first if we find a ZIP64 record */ | ||
679 | central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); | ||
680 | if(central_pos > 0) | ||
681 | { | ||
682 | hasZIP64Record = 1; | ||
683 | } | ||
684 | else if(central_pos == 0) | ||
685 | { | ||
686 | central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); | ||
687 | } | ||
688 | |||
689 | /* disable to allow appending to empty ZIP archive | ||
690 | if (central_pos==0) | ||
691 | err=ZIP_ERRNO; | ||
692 | */ | ||
693 | |||
694 | if(hasZIP64Record) | ||
695 | { | ||
696 | ZPOS64_T sizeEndOfCentralDirectory; | ||
697 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
698 | err=ZIP_ERRNO; | ||
699 | |||
700 | /* the signature, already checked */ | ||
701 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) | ||
702 | err=ZIP_ERRNO; | ||
703 | |||
704 | /* size of zip64 end of central directory record */ | ||
705 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) | ||
706 | err=ZIP_ERRNO; | ||
707 | |||
708 | /* version made by */ | ||
709 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) | ||
710 | err=ZIP_ERRNO; | ||
711 | |||
712 | /* version needed to extract */ | ||
713 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) | ||
714 | err=ZIP_ERRNO; | ||
715 | |||
716 | /* number of this disk */ | ||
717 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) | ||
718 | err=ZIP_ERRNO; | ||
719 | |||
720 | /* number of the disk with the start of the central directory */ | ||
721 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) | ||
722 | err=ZIP_ERRNO; | ||
723 | |||
724 | /* total number of entries in the central directory on this disk */ | ||
725 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) | ||
726 | err=ZIP_ERRNO; | ||
727 | |||
728 | /* total number of entries in the central directory */ | ||
729 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) | ||
730 | err=ZIP_ERRNO; | ||
731 | |||
732 | if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) | ||
733 | err=ZIP_BADZIPFILE; | ||
734 | |||
735 | /* size of the central directory */ | ||
736 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) | ||
737 | err=ZIP_ERRNO; | ||
738 | |||
739 | /* offset of start of central directory with respect to the | ||
740 | starting disk number */ | ||
741 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) | ||
742 | err=ZIP_ERRNO; | ||
743 | |||
744 | /* TODO.. */ | ||
745 | /* read the comment from the standard central header. */ | ||
746 | size_comment = 0; | ||
747 | } | ||
748 | else | ||
749 | { | ||
750 | /* Read End of central Directory info */ | ||
751 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
752 | err=ZIP_ERRNO; | ||
753 | |||
754 | /* the signature, already checked */ | ||
755 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) | ||
756 | err=ZIP_ERRNO; | ||
757 | |||
758 | /* number of this disk */ | ||
759 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) | ||
760 | err=ZIP_ERRNO; | ||
761 | |||
762 | /* number of the disk with the start of the central directory */ | ||
763 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) | ||
764 | err=ZIP_ERRNO; | ||
765 | |||
766 | /* total number of entries in the central dir on this disk */ | ||
767 | number_entry = 0; | ||
768 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
769 | err=ZIP_ERRNO; | ||
770 | else | ||
771 | number_entry = uL; | ||
772 | |||
773 | /* total number of entries in the central dir */ | ||
774 | number_entry_CD = 0; | ||
775 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
776 | err=ZIP_ERRNO; | ||
777 | else | ||
778 | number_entry_CD = uL; | ||
779 | |||
780 | if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) | ||
781 | err=ZIP_BADZIPFILE; | ||
782 | |||
783 | /* size of the central directory */ | ||
784 | size_central_dir = 0; | ||
785 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
786 | err=ZIP_ERRNO; | ||
787 | else | ||
788 | size_central_dir = uL; | ||
789 | |||
790 | /* offset of start of central directory with respect to the starting disk number */ | ||
791 | offset_central_dir = 0; | ||
792 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) | ||
793 | err=ZIP_ERRNO; | ||
794 | else | ||
795 | offset_central_dir = uL; | ||
796 | |||
797 | |||
798 | /* zipfile global comment length */ | ||
799 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) | ||
800 | err=ZIP_ERRNO; | ||
801 | } | ||
802 | |||
803 | if ((central_pos<offset_central_dir+size_central_dir) && | ||
804 | (err==ZIP_OK)) | ||
805 | err=ZIP_BADZIPFILE; | ||
806 | |||
807 | if (err!=ZIP_OK) | ||
808 | { | ||
809 | if ((pziinit->flags & ZIP_AUTO_CLOSE) != 0) { | ||
810 | ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); | ||
811 | } else { | ||
812 | ZFAKECLOSE64(pziinit->z_filefunc, pziinit->filestream); | ||
813 | } | ||
814 | return ZIP_ERRNO; | ||
815 | } | ||
816 | |||
817 | if (size_comment>0) | ||
818 | { | ||
819 | pziinit->globalcomment = (char*)ALLOC(size_comment+1); | ||
820 | if (pziinit->globalcomment) | ||
821 | { | ||
822 | size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); | ||
823 | pziinit->globalcomment[size_comment]=0; | ||
824 | } | ||
825 | } | ||
826 | |||
827 | byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); | ||
828 | pziinit->add_position_when_writting_offset = byte_before_the_zipfile; | ||
829 | |||
830 | { | ||
831 | ZPOS64_T size_central_dir_to_read = size_central_dir; | ||
832 | size_t buf_size = SIZEDATA_INDATABLOCK; | ||
833 | void* buf_read = (void*)ALLOC(buf_size); | ||
834 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
835 | err=ZIP_ERRNO; | ||
836 | |||
837 | while ((size_central_dir_to_read>0) && (err==ZIP_OK)) | ||
838 | { | ||
839 | ZPOS64_T read_this = SIZEDATA_INDATABLOCK; | ||
840 | if (read_this > size_central_dir_to_read) | ||
841 | read_this = size_central_dir_to_read; | ||
842 | |||
843 | if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) | ||
844 | err=ZIP_ERRNO; | ||
845 | |||
846 | if (err==ZIP_OK) | ||
847 | err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); | ||
848 | |||
849 | size_central_dir_to_read-=read_this; | ||
850 | } | ||
851 | TRYFREE(buf_read); | ||
852 | } | ||
853 | pziinit->begin_pos = byte_before_the_zipfile; | ||
854 | pziinit->number_entry = number_entry_CD; | ||
855 | |||
856 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) | ||
857 | err=ZIP_ERRNO; | ||
858 | |||
859 | return err; | ||
860 | } | ||
861 | |||
862 | |||
863 | #endif /* !NO_ADDFILEINEXISTINGZIP*/ | ||
864 | |||
865 | |||
866 | /************************************************************/ | ||
867 | extern zipFile ZEXPORT zipOpen3 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, | ||
868 | unsigned flags) | ||
869 | { | ||
870 | zip64_internal ziinit; | ||
871 | zip64_internal* zi; | ||
872 | int err=ZIP_OK; | ||
873 | |||
874 | ziinit.flags = flags; | ||
875 | ziinit.z_filefunc.zseek32_file = NULL; | ||
876 | ziinit.z_filefunc.ztell32_file = NULL; | ||
877 | if (pzlib_filefunc64_32_def==NULL) | ||
878 | fill_qiodevice64_filefunc(&ziinit.z_filefunc.zfile_func64); | ||
879 | else | ||
880 | ziinit.z_filefunc = *pzlib_filefunc64_32_def; | ||
881 | |||
882 | ziinit.filestream = ZOPEN64(ziinit.z_filefunc, | ||
883 | file, | ||
884 | (append == APPEND_STATUS_CREATE) ? | ||
885 | (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : | ||
886 | (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); | ||
887 | |||
888 | if (ziinit.filestream == NULL) | ||
889 | return NULL; | ||
890 | |||
891 | if (append == APPEND_STATUS_CREATEAFTER) | ||
892 | ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); | ||
893 | |||
894 | ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); | ||
895 | ziinit.in_opened_file_inzip = 0; | ||
896 | ziinit.ci.stream_initialised = 0; | ||
897 | ziinit.number_entry = 0; | ||
898 | ziinit.add_position_when_writting_offset = 0; | ||
899 | init_linkedlist(&(ziinit.central_dir)); | ||
900 | |||
901 | |||
902 | |||
903 | zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); | ||
904 | if (zi==NULL) | ||
905 | { | ||
906 | if ((ziinit.flags & ZIP_AUTO_CLOSE) != 0) { | ||
907 | ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); | ||
908 | } else { | ||
909 | ZFAKECLOSE64(ziinit.z_filefunc,ziinit.filestream); | ||
910 | } | ||
911 | return NULL; | ||
912 | } | ||
913 | |||
914 | /* now we add file in a zipfile */ | ||
915 | # ifndef NO_ADDFILEINEXISTINGZIP | ||
916 | ziinit.globalcomment = NULL; | ||
917 | if (append == APPEND_STATUS_ADDINZIP) | ||
918 | { | ||
919 | /* Read and Cache Central Directory Records */ | ||
920 | err = LoadCentralDirectoryRecord(&ziinit); | ||
921 | } | ||
922 | |||
923 | if (globalcomment) | ||
924 | { | ||
925 | *globalcomment = ziinit.globalcomment; | ||
926 | } | ||
927 | # endif /* !NO_ADDFILEINEXISTINGZIP*/ | ||
928 | |||
929 | if (err != ZIP_OK) | ||
930 | { | ||
931 | # ifndef NO_ADDFILEINEXISTINGZIP | ||
932 | TRYFREE(ziinit.globalcomment); | ||
933 | # endif /* !NO_ADDFILEINEXISTINGZIP*/ | ||
934 | TRYFREE(zi); | ||
935 | return NULL; | ||
936 | } | ||
937 | else | ||
938 | { | ||
939 | *zi = ziinit; | ||
940 | return (zipFile)zi; | ||
941 | } | ||
942 | } | ||
943 | |||
944 | extern zipFile ZEXPORT zipOpen2 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) | ||
945 | { | ||
946 | if (pzlib_filefunc32_def != NULL) | ||
947 | { | ||
948 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | ||
949 | fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); | ||
950 | return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS); | ||
951 | } | ||
952 | else | ||
953 | return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS); | ||
954 | } | ||
955 | |||
956 | extern zipFile ZEXPORT zipOpen2_64 (voidpf file, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) | ||
957 | { | ||
958 | if (pzlib_filefunc_def != NULL) | ||
959 | { | ||
960 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; | ||
961 | zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; | ||
962 | zlib_filefunc64_32_def_fill.ztell32_file = NULL; | ||
963 | zlib_filefunc64_32_def_fill.zseek32_file = NULL; | ||
964 | return zipOpen3(file, append, globalcomment, &zlib_filefunc64_32_def_fill, ZIP_DEFAULT_FLAGS); | ||
965 | } | ||
966 | else | ||
967 | return zipOpen3(file, append, globalcomment, NULL, ZIP_DEFAULT_FLAGS); | ||
968 | } | ||
969 | |||
970 | |||
971 | |||
972 | extern zipFile ZEXPORT zipOpen (voidpf file, int append) | ||
973 | { | ||
974 | return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS); | ||
975 | } | ||
976 | |||
977 | extern zipFile ZEXPORT zipOpen64 (voidpf file, int append) | ||
978 | { | ||
979 | return zipOpen3(file,append,NULL,NULL, ZIP_DEFAULT_FLAGS); | ||
980 | } | ||
981 | |||
982 | int Write_LocalFileHeader(zip64_internal* zi, const char* filename, | ||
983 | uInt size_extrafield_local, | ||
984 | const void* extrafield_local, | ||
985 | uLong version_to_extract) | ||
986 | { | ||
987 | /* write the local header */ | ||
988 | int err; | ||
989 | uInt size_filename = (uInt)strlen(filename); | ||
990 | uInt size_extrafield = size_extrafield_local; | ||
991 | |||
992 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); | ||
993 | |||
994 | if (err==ZIP_OK) | ||
995 | { | ||
996 | if(zi->ci.flag & ZIP_ENCODING_UTF8) | ||
997 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)63,2);/* Version 6.3 is required for Unicode support */ | ||
998 | else if(zi->ci.zip64) | ||
999 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ | ||
1000 | else | ||
1001 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)version_to_extract,2); | ||
1002 | } | ||
1003 | |||
1004 | if (err==ZIP_OK) | ||
1005 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); | ||
1006 | |||
1007 | if (err==ZIP_OK) | ||
1008 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); | ||
1009 | |||
1010 | if (err==ZIP_OK) | ||
1011 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); | ||
1012 | |||
1013 | /* CRC / Compressed size / Uncompressed size will be filled in later and rewritten later */ | ||
1014 | if (err==ZIP_OK) | ||
1015 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ | ||
1016 | if (err==ZIP_OK) | ||
1017 | { | ||
1018 | if(zi->ci.zip64) | ||
1019 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ | ||
1020 | else | ||
1021 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ | ||
1022 | } | ||
1023 | if (err==ZIP_OK) | ||
1024 | { | ||
1025 | if(zi->ci.zip64) | ||
1026 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ | ||
1027 | else | ||
1028 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ | ||
1029 | } | ||
1030 | |||
1031 | if (err==ZIP_OK) | ||
1032 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); | ||
1033 | |||
1034 | if(zi->ci.zip64) | ||
1035 | { | ||
1036 | size_extrafield += 20; | ||
1037 | } | ||
1038 | |||
1039 | if (err==ZIP_OK) | ||
1040 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); | ||
1041 | |||
1042 | if ((err==ZIP_OK) && (size_filename > 0)) | ||
1043 | { | ||
1044 | if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) | ||
1045 | err = ZIP_ERRNO; | ||
1046 | } | ||
1047 | |||
1048 | if ((err==ZIP_OK) && (size_extrafield_local > 0)) | ||
1049 | { | ||
1050 | if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) | ||
1051 | err = ZIP_ERRNO; | ||
1052 | } | ||
1053 | |||
1054 | |||
1055 | if ((err==ZIP_OK) && (zi->ci.zip64)) | ||
1056 | { | ||
1057 | /* write the Zip64 extended info */ | ||
1058 | short HeaderID = 1; | ||
1059 | short DataSize = 16; | ||
1060 | ZPOS64_T CompressedSize = 0; | ||
1061 | ZPOS64_T UncompressedSize = 0; | ||
1062 | |||
1063 | /* Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) */ | ||
1064 | zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); | ||
1065 | |||
1066 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); | ||
1067 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); | ||
1068 | |||
1069 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); | ||
1070 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); | ||
1071 | } | ||
1072 | |||
1073 | return err; | ||
1074 | } | ||
1075 | |||
1076 | /* | ||
1077 | NOTE. | ||
1078 | When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped | ||
1079 | before calling this function it can be done with zipRemoveExtraInfoBlock | ||
1080 | |||
1081 | It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize | ||
1082 | unnecessary allocations. | ||
1083 | */ | ||
1084 | extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1085 | const void* extrafield_local, uInt size_extrafield_local, | ||
1086 | const void* extrafield_global, uInt size_extrafield_global, | ||
1087 | const char* comment, int method, int level, int raw, | ||
1088 | int windowBits,int memLevel, int strategy, | ||
1089 | const char* password, uLong crcForCrypting, | ||
1090 | uLong versionMadeBy, uLong flagBase, int zip64) | ||
1091 | { | ||
1092 | zip64_internal* zi; | ||
1093 | uInt size_filename; | ||
1094 | uInt size_comment; | ||
1095 | uInt i; | ||
1096 | int err = ZIP_OK; | ||
1097 | uLong version_to_extract; | ||
1098 | |||
1099 | # ifdef NOCRYPT | ||
1100 | if (password != NULL) | ||
1101 | return ZIP_PARAMERROR; | ||
1102 | # endif | ||
1103 | |||
1104 | if (file == NULL) | ||
1105 | return ZIP_PARAMERROR; | ||
1106 | |||
1107 | #ifdef HAVE_BZIP2 | ||
1108 | if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) | ||
1109 | return ZIP_PARAMERROR; | ||
1110 | #else | ||
1111 | if ((method!=0) && (method!=Z_DEFLATED)) | ||
1112 | return ZIP_PARAMERROR; | ||
1113 | #endif | ||
1114 | |||
1115 | zi = (zip64_internal*)file; | ||
1116 | |||
1117 | if (zi->in_opened_file_inzip == 1) | ||
1118 | { | ||
1119 | err = zipCloseFileInZip (file); | ||
1120 | if (err != ZIP_OK) | ||
1121 | return err; | ||
1122 | } | ||
1123 | |||
1124 | if (method == 0 | ||
1125 | && (level == 0 || (zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0) | ||
1126 | && (zi->flags & ZIP_SEQUENTIAL) == 0) | ||
1127 | { | ||
1128 | version_to_extract = 10; | ||
1129 | } | ||
1130 | else | ||
1131 | { | ||
1132 | version_to_extract = 20; | ||
1133 | } | ||
1134 | |||
1135 | if (filename==NULL) | ||
1136 | filename="-"; | ||
1137 | |||
1138 | if (comment==NULL) | ||
1139 | size_comment = 0; | ||
1140 | else | ||
1141 | size_comment = (uInt)strlen(comment); | ||
1142 | |||
1143 | size_filename = (uInt)strlen(filename); | ||
1144 | |||
1145 | if (zipfi == NULL) | ||
1146 | zi->ci.dosDate = 0; | ||
1147 | else | ||
1148 | { | ||
1149 | if (zipfi->dosDate != 0) | ||
1150 | zi->ci.dosDate = zipfi->dosDate; | ||
1151 | else | ||
1152 | zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); | ||
1153 | } | ||
1154 | |||
1155 | zi->ci.flag = flagBase; | ||
1156 | if (zi->flags & ZIP_ENCODING_UTF8) | ||
1157 | zi->ci.flag |= ZIP_ENCODING_UTF8; | ||
1158 | if ((level==8) || (level==9)) | ||
1159 | zi->ci.flag |= 2; | ||
1160 | if (level==2) | ||
1161 | zi->ci.flag |= 4; | ||
1162 | if (level==1) | ||
1163 | zi->ci.flag |= 6; | ||
1164 | if (password != NULL) | ||
1165 | zi->ci.flag |= 1; | ||
1166 | if (version_to_extract >= 20 | ||
1167 | && ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) != 0 | ||
1168 | || (zi->flags & ZIP_SEQUENTIAL) != 0)) | ||
1169 | zi->ci.flag |= 8; | ||
1170 | |||
1171 | zi->ci.crc32 = 0; | ||
1172 | zi->ci.method = method; | ||
1173 | zi->ci.encrypt = 0; | ||
1174 | zi->ci.stream_initialised = 0; | ||
1175 | zi->ci.pos_in_buffered_data = 0; | ||
1176 | zi->ci.raw = raw; | ||
1177 | zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); | ||
1178 | |||
1179 | zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; | ||
1180 | zi->ci.size_centralExtraFree = 32; /* Extra space we have reserved in case we need to add ZIP64 extra info data */ | ||
1181 | |||
1182 | zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); | ||
1183 | if(!zi->ci.central_header) { | ||
1184 | return (Z_MEM_ERROR); | ||
1185 | } | ||
1186 | |||
1187 | zi->ci.size_centralExtra = size_extrafield_global; | ||
1188 | zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); | ||
1189 | /* version info */ | ||
1190 | zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); | ||
1191 | zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)version_to_extract,2); | ||
1192 | zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); | ||
1193 | zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); | ||
1194 | zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); | ||
1195 | zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ | ||
1196 | zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ | ||
1197 | zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ | ||
1198 | zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); | ||
1199 | zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); | ||
1200 | zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); | ||
1201 | zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ | ||
1202 | |||
1203 | if (zipfi==NULL) | ||
1204 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); | ||
1205 | else | ||
1206 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); | ||
1207 | |||
1208 | if (zipfi==NULL) | ||
1209 | zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); | ||
1210 | else | ||
1211 | zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); | ||
1212 | |||
1213 | if(zi->ci.pos_local_header >= 0xffffffff) | ||
1214 | zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); | ||
1215 | else | ||
1216 | zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); | ||
1217 | |||
1218 | for (i=0;i<size_filename;i++) | ||
1219 | *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); | ||
1220 | |||
1221 | for (i=0;i<size_extrafield_global;i++) | ||
1222 | *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) = | ||
1223 | *(((const char*)extrafield_global)+i); | ||
1224 | |||
1225 | for (i=0;i<size_comment;i++) | ||
1226 | *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+ | ||
1227 | size_extrafield_global+i) = *(comment+i); | ||
1228 | if (zi->ci.central_header == NULL) | ||
1229 | return ZIP_INTERNALERROR; | ||
1230 | |||
1231 | zi->ci.zip64 = zip64; | ||
1232 | zi->ci.totalCompressedData = 0; | ||
1233 | zi->ci.totalUncompressedData = 0; | ||
1234 | zi->ci.pos_zip64extrainfo = 0; | ||
1235 | |||
1236 | err = Write_LocalFileHeader(zi, filename, size_extrafield_local, | ||
1237 | extrafield_local, version_to_extract); | ||
1238 | |||
1239 | #ifdef HAVE_BZIP2 | ||
1240 | zi->ci.bstream.avail_in = (uInt)0; | ||
1241 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; | ||
1242 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; | ||
1243 | zi->ci.bstream.total_in_hi32 = 0; | ||
1244 | zi->ci.bstream.total_in_lo32 = 0; | ||
1245 | zi->ci.bstream.total_out_hi32 = 0; | ||
1246 | zi->ci.bstream.total_out_lo32 = 0; | ||
1247 | #endif | ||
1248 | |||
1249 | zi->ci.stream.avail_in = (uInt)0; | ||
1250 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
1251 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
1252 | zi->ci.stream.total_in = 0; | ||
1253 | zi->ci.stream.total_out = 0; | ||
1254 | zi->ci.stream.data_type = Z_BINARY; | ||
1255 | |||
1256 | #ifdef HAVE_BZIP2 | ||
1257 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1258 | #else | ||
1259 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | ||
1260 | #endif | ||
1261 | { | ||
1262 | if(zi->ci.method == Z_DEFLATED) | ||
1263 | { | ||
1264 | zi->ci.stream.zalloc = (alloc_func)0; | ||
1265 | zi->ci.stream.zfree = (free_func)0; | ||
1266 | zi->ci.stream.opaque = (voidpf)0; | ||
1267 | |||
1268 | if (windowBits>0) | ||
1269 | windowBits = -windowBits; | ||
1270 | |||
1271 | err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); | ||
1272 | |||
1273 | if (err==Z_OK) | ||
1274 | zi->ci.stream_initialised = Z_DEFLATED; | ||
1275 | } | ||
1276 | else if(zi->ci.method == Z_BZIP2ED) | ||
1277 | { | ||
1278 | #ifdef HAVE_BZIP2 | ||
1279 | /* Init BZip stuff here */ | ||
1280 | zi->ci.bstream.bzalloc = 0; | ||
1281 | zi->ci.bstream.bzfree = 0; | ||
1282 | zi->ci.bstream.opaque = (voidpf)0; | ||
1283 | |||
1284 | err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); | ||
1285 | if(err == BZ_OK) | ||
1286 | zi->ci.stream_initialised = Z_BZIP2ED; | ||
1287 | #endif | ||
1288 | } | ||
1289 | |||
1290 | } | ||
1291 | |||
1292 | # ifndef NOCRYPT | ||
1293 | zi->ci.crypt_header_size = 0; | ||
1294 | if ((err==Z_OK) && (password != NULL)) | ||
1295 | { | ||
1296 | unsigned char bufHead[RAND_HEAD_LEN]; | ||
1297 | unsigned int sizeHead; | ||
1298 | zi->ci.encrypt = 1; | ||
1299 | zi->ci.pcrc_32_tab = get_crc_table(); | ||
1300 | /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ | ||
1301 | if (crcForCrypting == 0) { | ||
1302 | crcForCrypting = (uLong)zi->ci.dosDate << 16; /* ATTANTION! Without this row, you don't unpack your password protected archive in other app. */ | ||
1303 | } | ||
1304 | sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); | ||
1305 | zi->ci.crypt_header_size = sizeHead; | ||
1306 | |||
1307 | if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) | ||
1308 | err = ZIP_ERRNO; | ||
1309 | } | ||
1310 | # endif | ||
1311 | |||
1312 | if (err==Z_OK) | ||
1313 | zi->in_opened_file_inzip = 1; | ||
1314 | return err; | ||
1315 | } | ||
1316 | |||
1317 | extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1318 | const void* extrafield_local, uInt size_extrafield_local, | ||
1319 | const void* extrafield_global, uInt size_extrafield_global, | ||
1320 | const char* comment, int method, int level, int raw, | ||
1321 | int windowBits,int memLevel, int strategy, | ||
1322 | const char* password, uLong crcForCrypting, | ||
1323 | uLong versionMadeBy, uLong flagBase) | ||
1324 | { | ||
1325 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1326 | extrafield_local, size_extrafield_local, | ||
1327 | extrafield_global, size_extrafield_global, | ||
1328 | comment, method, level, raw, | ||
1329 | windowBits, memLevel, strategy, | ||
1330 | password, crcForCrypting, versionMadeBy, flagBase, 0); | ||
1331 | } | ||
1332 | |||
1333 | extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1334 | const void* extrafield_local, uInt size_extrafield_local, | ||
1335 | const void* extrafield_global, uInt size_extrafield_global, | ||
1336 | const char* comment, int method, int level, int raw, | ||
1337 | int windowBits,int memLevel, int strategy, | ||
1338 | const char* password, uLong crcForCrypting) | ||
1339 | { | ||
1340 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1341 | extrafield_local, size_extrafield_local, | ||
1342 | extrafield_global, size_extrafield_global, | ||
1343 | comment, method, level, raw, | ||
1344 | windowBits, memLevel, strategy, | ||
1345 | password, crcForCrypting, VERSIONMADEBY, 0, 0); | ||
1346 | } | ||
1347 | |||
1348 | extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1349 | const void* extrafield_local, uInt size_extrafield_local, | ||
1350 | const void* extrafield_global, uInt size_extrafield_global, | ||
1351 | const char* comment, int method, int level, int raw, | ||
1352 | int windowBits,int memLevel, int strategy, | ||
1353 | const char* password, uLong crcForCrypting, int zip64) | ||
1354 | { | ||
1355 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1356 | extrafield_local, size_extrafield_local, | ||
1357 | extrafield_global, size_extrafield_global, | ||
1358 | comment, method, level, raw, | ||
1359 | windowBits, memLevel, strategy, | ||
1360 | password, crcForCrypting, VERSIONMADEBY, 0, zip64); | ||
1361 | } | ||
1362 | |||
1363 | extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1364 | const void* extrafield_local, uInt size_extrafield_local, | ||
1365 | const void* extrafield_global, uInt size_extrafield_global, | ||
1366 | const char* comment, int method, int level, int raw) | ||
1367 | { | ||
1368 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1369 | extrafield_local, size_extrafield_local, | ||
1370 | extrafield_global, size_extrafield_global, | ||
1371 | comment, method, level, raw, | ||
1372 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1373 | NULL, 0, VERSIONMADEBY, 0, 0); | ||
1374 | } | ||
1375 | |||
1376 | extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1377 | const void* extrafield_local, uInt size_extrafield_local, | ||
1378 | const void* extrafield_global, uInt size_extrafield_global, | ||
1379 | const char* comment, int method, int level, int raw, int zip64) | ||
1380 | { | ||
1381 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1382 | extrafield_local, size_extrafield_local, | ||
1383 | extrafield_global, size_extrafield_global, | ||
1384 | comment, method, level, raw, | ||
1385 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1386 | NULL, 0, VERSIONMADEBY, 0, zip64); | ||
1387 | } | ||
1388 | |||
1389 | extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1390 | const void* extrafield_local, uInt size_extrafield_local, | ||
1391 | const void*extrafield_global, uInt size_extrafield_global, | ||
1392 | const char* comment, int method, int level, int zip64) | ||
1393 | { | ||
1394 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1395 | extrafield_local, size_extrafield_local, | ||
1396 | extrafield_global, size_extrafield_global, | ||
1397 | comment, method, level, 0, | ||
1398 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1399 | NULL, 0, VERSIONMADEBY, 0, zip64); | ||
1400 | } | ||
1401 | |||
1402 | extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, | ||
1403 | const void* extrafield_local, uInt size_extrafield_local, | ||
1404 | const void*extrafield_global, uInt size_extrafield_global, | ||
1405 | const char* comment, int method, int level) | ||
1406 | { | ||
1407 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, | ||
1408 | extrafield_local, size_extrafield_local, | ||
1409 | extrafield_global, size_extrafield_global, | ||
1410 | comment, method, level, 0, | ||
1411 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, | ||
1412 | NULL, 0, VERSIONMADEBY, 0, 0); | ||
1413 | } | ||
1414 | |||
1415 | local int zip64FlushWriteBuffer(zip64_internal* zi) | ||
1416 | { | ||
1417 | int err=ZIP_OK; | ||
1418 | |||
1419 | if (zi->ci.encrypt != 0) | ||
1420 | { | ||
1421 | #ifndef NOCRYPT | ||
1422 | uInt i; | ||
1423 | int t; | ||
1424 | for (i=0;i<zi->ci.pos_in_buffered_data;i++) | ||
1425 | zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); | ||
1426 | #endif | ||
1427 | } | ||
1428 | |||
1429 | if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) | ||
1430 | err = ZIP_ERRNO; | ||
1431 | |||
1432 | zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; | ||
1433 | |||
1434 | #ifdef HAVE_BZIP2 | ||
1435 | if(zi->ci.method == Z_BZIP2ED) | ||
1436 | { | ||
1437 | zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; | ||
1438 | zi->ci.bstream.total_in_lo32 = 0; | ||
1439 | zi->ci.bstream.total_in_hi32 = 0; | ||
1440 | } | ||
1441 | else | ||
1442 | #endif | ||
1443 | { | ||
1444 | zi->ci.totalUncompressedData += zi->ci.stream.total_in; | ||
1445 | zi->ci.stream.total_in = 0; | ||
1446 | } | ||
1447 | |||
1448 | |||
1449 | zi->ci.pos_in_buffered_data = 0; | ||
1450 | |||
1451 | return err; | ||
1452 | } | ||
1453 | |||
1454 | extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) | ||
1455 | { | ||
1456 | zip64_internal* zi; | ||
1457 | int err=ZIP_OK; | ||
1458 | |||
1459 | if (file == NULL) | ||
1460 | return ZIP_PARAMERROR; | ||
1461 | zi = (zip64_internal*)file; | ||
1462 | |||
1463 | if (zi->in_opened_file_inzip == 0) | ||
1464 | return ZIP_PARAMERROR; | ||
1465 | |||
1466 | zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); | ||
1467 | |||
1468 | #ifdef HAVE_BZIP2 | ||
1469 | if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) | ||
1470 | { | ||
1471 | zi->ci.bstream.next_in = (void*)buf; | ||
1472 | zi->ci.bstream.avail_in = len; | ||
1473 | err = BZ_RUN_OK; | ||
1474 | |||
1475 | while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) | ||
1476 | { | ||
1477 | if (zi->ci.bstream.avail_out == 0) | ||
1478 | { | ||
1479 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) | ||
1480 | err = ZIP_ERRNO; | ||
1481 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; | ||
1482 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; | ||
1483 | } | ||
1484 | |||
1485 | |||
1486 | if(err != BZ_RUN_OK) | ||
1487 | break; | ||
1488 | |||
1489 | if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1490 | { | ||
1491 | uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; | ||
1492 | /* uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; */ | ||
1493 | err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); | ||
1494 | |||
1495 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; | ||
1496 | } | ||
1497 | } | ||
1498 | |||
1499 | if(err == BZ_RUN_OK) | ||
1500 | err = ZIP_OK; | ||
1501 | } | ||
1502 | else | ||
1503 | #endif | ||
1504 | { | ||
1505 | zi->ci.stream.next_in = (Bytef*)buf; | ||
1506 | zi->ci.stream.avail_in = len; | ||
1507 | |||
1508 | while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) | ||
1509 | { | ||
1510 | if (zi->ci.stream.avail_out == 0) | ||
1511 | { | ||
1512 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) | ||
1513 | err = ZIP_ERRNO; | ||
1514 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
1515 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
1516 | } | ||
1517 | |||
1518 | |||
1519 | if(err != ZIP_OK) | ||
1520 | break; | ||
1521 | |||
1522 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | ||
1523 | { | ||
1524 | uInt uAvailOutBefore = zi->ci.stream.avail_out; | ||
1525 | err=deflate(&zi->ci.stream, Z_NO_FLUSH); | ||
1526 | zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; | ||
1527 | } | ||
1528 | else | ||
1529 | { | ||
1530 | uInt copy_this,i; | ||
1531 | if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) | ||
1532 | copy_this = zi->ci.stream.avail_in; | ||
1533 | else | ||
1534 | copy_this = zi->ci.stream.avail_out; | ||
1535 | |||
1536 | for (i = 0; i < copy_this; i++) | ||
1537 | *(((char*)zi->ci.stream.next_out)+i) = | ||
1538 | *(((const char*)zi->ci.stream.next_in)+i); | ||
1539 | { | ||
1540 | zi->ci.stream.avail_in -= copy_this; | ||
1541 | zi->ci.stream.avail_out-= copy_this; | ||
1542 | zi->ci.stream.next_in+= copy_this; | ||
1543 | zi->ci.stream.next_out+= copy_this; | ||
1544 | zi->ci.stream.total_in+= copy_this; | ||
1545 | zi->ci.stream.total_out+= copy_this; | ||
1546 | zi->ci.pos_in_buffered_data += copy_this; | ||
1547 | } | ||
1548 | } | ||
1549 | }/* while(...) */ | ||
1550 | } | ||
1551 | |||
1552 | return err; | ||
1553 | } | ||
1554 | |||
1555 | extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) | ||
1556 | { | ||
1557 | return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); | ||
1558 | } | ||
1559 | |||
1560 | extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) | ||
1561 | { | ||
1562 | zip64_internal* zi; | ||
1563 | ZPOS64_T compressed_size; | ||
1564 | uLong invalidValue = 0xffffffff; | ||
1565 | short datasize = 0; | ||
1566 | int err=ZIP_OK; | ||
1567 | |||
1568 | if (file == NULL) | ||
1569 | return ZIP_PARAMERROR; | ||
1570 | zi = (zip64_internal*)file; | ||
1571 | |||
1572 | if (zi->in_opened_file_inzip == 0) | ||
1573 | return ZIP_PARAMERROR; | ||
1574 | zi->ci.stream.avail_in = 0; | ||
1575 | |||
1576 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | ||
1577 | { | ||
1578 | while (err==ZIP_OK) | ||
1579 | { | ||
1580 | uLong uAvailOutBefore; | ||
1581 | if (zi->ci.stream.avail_out == 0) | ||
1582 | { | ||
1583 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) | ||
1584 | err = ZIP_ERRNO; | ||
1585 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; | ||
1586 | zi->ci.stream.next_out = zi->ci.buffered_data; | ||
1587 | } | ||
1588 | uAvailOutBefore = zi->ci.stream.avail_out; | ||
1589 | err=deflate(&zi->ci.stream, Z_FINISH); | ||
1590 | zi->ci.pos_in_buffered_data += uAvailOutBefore - zi->ci.stream.avail_out; | ||
1591 | } | ||
1592 | } | ||
1593 | else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1594 | { | ||
1595 | #ifdef HAVE_BZIP2 | ||
1596 | err = BZ_FINISH_OK; | ||
1597 | while (err==BZ_FINISH_OK) | ||
1598 | { | ||
1599 | uLong uTotalOutBefore; | ||
1600 | if (zi->ci.bstream.avail_out == 0) | ||
1601 | { | ||
1602 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) | ||
1603 | err = ZIP_ERRNO; | ||
1604 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; | ||
1605 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; | ||
1606 | } | ||
1607 | uTotalOutBefore = zi->ci.bstream.total_out_lo32; | ||
1608 | err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); | ||
1609 | if(err == BZ_STREAM_END) | ||
1610 | err = Z_STREAM_END; | ||
1611 | |||
1612 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); | ||
1613 | } | ||
1614 | |||
1615 | if(err == BZ_FINISH_OK) | ||
1616 | err = ZIP_OK; | ||
1617 | #endif | ||
1618 | } | ||
1619 | |||
1620 | if (err==Z_STREAM_END) | ||
1621 | err=ZIP_OK; /* this is normal */ | ||
1622 | |||
1623 | if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) | ||
1624 | { | ||
1625 | if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) | ||
1626 | err = ZIP_ERRNO; | ||
1627 | } | ||
1628 | |||
1629 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) | ||
1630 | { | ||
1631 | int tmp_err = deflateEnd(&zi->ci.stream); | ||
1632 | if (err == ZIP_OK) | ||
1633 | err = tmp_err; | ||
1634 | zi->ci.stream_initialised = 0; | ||
1635 | } | ||
1636 | #ifdef HAVE_BZIP2 | ||
1637 | else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) | ||
1638 | { | ||
1639 | int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); | ||
1640 | if (err==ZIP_OK) | ||
1641 | err = tmperr; | ||
1642 | zi->ci.stream_initialised = 0; | ||
1643 | } | ||
1644 | #endif | ||
1645 | |||
1646 | if (!zi->ci.raw) | ||
1647 | { | ||
1648 | crc32 = (uLong)zi->ci.crc32; | ||
1649 | uncompressed_size = zi->ci.totalUncompressedData; | ||
1650 | } | ||
1651 | compressed_size = zi->ci.totalCompressedData; | ||
1652 | |||
1653 | # ifndef NOCRYPT | ||
1654 | compressed_size += zi->ci.crypt_header_size; | ||
1655 | # endif | ||
1656 | |||
1657 | /* update Current Item crc and sizes, */ | ||
1658 | if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) | ||
1659 | { | ||
1660 | /*version Made by*/ | ||
1661 | zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); | ||
1662 | /*version needed*/ | ||
1663 | zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)((zi->ci.flag & ZIP_ENCODING_UTF8) ? 63 : 45),2); | ||
1664 | } | ||
1665 | |||
1666 | zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ | ||
1667 | |||
1668 | |||
1669 | if(compressed_size >= 0xffffffff) | ||
1670 | zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ | ||
1671 | else | ||
1672 | zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ | ||
1673 | |||
1674 | /* set internal file attributes field */ | ||
1675 | if (zi->ci.stream.data_type == Z_ASCII) | ||
1676 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); | ||
1677 | |||
1678 | if(uncompressed_size >= 0xffffffff) | ||
1679 | zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ | ||
1680 | else | ||
1681 | zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ | ||
1682 | |||
1683 | /* Add ZIP64 extra info field for uncompressed size */ | ||
1684 | if(uncompressed_size >= 0xffffffff) | ||
1685 | datasize += 8; | ||
1686 | |||
1687 | /* Add ZIP64 extra info field for compressed size */ | ||
1688 | if(compressed_size >= 0xffffffff) | ||
1689 | datasize += 8; | ||
1690 | |||
1691 | /* Add ZIP64 extra info field for relative offset to local file header of current file */ | ||
1692 | if(zi->ci.pos_local_header >= 0xffffffff) | ||
1693 | datasize += 8; | ||
1694 | |||
1695 | if(datasize > 0) | ||
1696 | { | ||
1697 | char* p = NULL; | ||
1698 | |||
1699 | if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) | ||
1700 | { | ||
1701 | /* we can not write more data to the buffer that we have room for. */ | ||
1702 | return ZIP_BADZIPFILE; | ||
1703 | } | ||
1704 | |||
1705 | p = zi->ci.central_header + zi->ci.size_centralheader; | ||
1706 | |||
1707 | /* Add Extra Information Header for 'ZIP64 information' */ | ||
1708 | zip64local_putValue_inmemory(p, 0x0001, 2); /* HeaderID */ | ||
1709 | p += 2; | ||
1710 | zip64local_putValue_inmemory(p, datasize, 2); /* DataSize */ | ||
1711 | p += 2; | ||
1712 | |||
1713 | if(uncompressed_size >= 0xffffffff) | ||
1714 | { | ||
1715 | zip64local_putValue_inmemory(p, uncompressed_size, 8); | ||
1716 | p += 8; | ||
1717 | } | ||
1718 | |||
1719 | if(compressed_size >= 0xffffffff) | ||
1720 | { | ||
1721 | zip64local_putValue_inmemory(p, compressed_size, 8); | ||
1722 | p += 8; | ||
1723 | } | ||
1724 | |||
1725 | if(zi->ci.pos_local_header >= 0xffffffff) | ||
1726 | { | ||
1727 | zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); | ||
1728 | p += 8; | ||
1729 | } | ||
1730 | |||
1731 | /* Update how much extra free space we got in the memory buffer */ | ||
1732 | /* and increase the centralheader size so the new ZIP64 fields are included */ | ||
1733 | /* ( 4 below is the size of HeaderID and DataSize field ) */ | ||
1734 | zi->ci.size_centralExtraFree -= datasize + 4; | ||
1735 | zi->ci.size_centralheader += datasize + 4; | ||
1736 | |||
1737 | /* Update the extra info size field */ | ||
1738 | zi->ci.size_centralExtra += datasize + 4; | ||
1739 | zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); | ||
1740 | } | ||
1741 | |||
1742 | if (err==ZIP_OK) | ||
1743 | err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); | ||
1744 | |||
1745 | TRYFREE(zi->ci.central_header); | ||
1746 | |||
1747 | if (err==ZIP_OK) | ||
1748 | { | ||
1749 | if ((zi->flags & ZIP_SEQUENTIAL) == 0) { | ||
1750 | /* Update the LocalFileHeader with the new values. */ | ||
1751 | |||
1752 | ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); | ||
1753 | |||
1754 | if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1755 | err = ZIP_ERRNO; | ||
1756 | |||
1757 | if (err==ZIP_OK) | ||
1758 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ | ||
1759 | |||
1760 | if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff) | ||
1761 | { | ||
1762 | if(zi->ci.pos_zip64extrainfo > 0) | ||
1763 | { | ||
1764 | /* Update the size in the ZIP64 extended field. */ | ||
1765 | if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1766 | err = ZIP_ERRNO; | ||
1767 | |||
1768 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
1769 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); | ||
1770 | |||
1771 | if (err==ZIP_OK) /* uncompressed size, unknown */ | ||
1772 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); | ||
1773 | } | ||
1774 | } | ||
1775 | else | ||
1776 | { | ||
1777 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
1778 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); | ||
1779 | |||
1780 | if (err==ZIP_OK) /* uncompressed size, unknown */ | ||
1781 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); | ||
1782 | } | ||
1783 | |||
1784 | if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) | ||
1785 | err = ZIP_ERRNO; | ||
1786 | } | ||
1787 | |||
1788 | if ((zi->ci.flag & 8) != 0) { | ||
1789 | /* Write local Descriptor after file data */ | ||
1790 | if (err==ZIP_OK) | ||
1791 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4); | ||
1792 | if (err==ZIP_OK) | ||
1793 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ | ||
1794 | if (zi->ci.zip64) { | ||
1795 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
1796 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,8); | ||
1797 | |||
1798 | if (err==ZIP_OK) /* uncompressed size, unknown */ | ||
1799 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,8); | ||
1800 | } else { | ||
1801 | if (err==ZIP_OK) /* compressed size, unknown */ | ||
1802 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); | ||
1803 | if (err==ZIP_OK) /* uncompressed size, unknown */ | ||
1804 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); | ||
1805 | } | ||
1806 | } | ||
1807 | } | ||
1808 | |||
1809 | zi->number_entry ++; | ||
1810 | zi->in_opened_file_inzip = 0; | ||
1811 | |||
1812 | return err; | ||
1813 | } | ||
1814 | |||
1815 | extern int ZEXPORT zipCloseFileInZip (zipFile file) | ||
1816 | { | ||
1817 | return zipCloseFileInZipRaw (file,0,0); | ||
1818 | } | ||
1819 | |||
1820 | int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) | ||
1821 | { | ||
1822 | int err = ZIP_OK; | ||
1823 | ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; | ||
1824 | |||
1825 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); | ||
1826 | |||
1827 | /*num disks*/ | ||
1828 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1829 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | ||
1830 | |||
1831 | /*relative offset*/ | ||
1832 | if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ | ||
1833 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); | ||
1834 | |||
1835 | /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ | ||
1836 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1837 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); | ||
1838 | |||
1839 | return err; | ||
1840 | } | ||
1841 | |||
1842 | int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) | ||
1843 | { | ||
1844 | int err = ZIP_OK; | ||
1845 | |||
1846 | uLong Zip64DataSize = 44; | ||
1847 | |||
1848 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); | ||
1849 | |||
1850 | if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ | ||
1851 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); /* why ZPOS64_T of this ? */ | ||
1852 | |||
1853 | if (err==ZIP_OK) /* version made by */ | ||
1854 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); | ||
1855 | |||
1856 | if (err==ZIP_OK) /* version needed */ | ||
1857 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)((zi->ci.flag & ZIP_ENCODING_UTF8) ? 63 : 45),2); | ||
1858 | |||
1859 | if (err==ZIP_OK) /* number of this disk */ | ||
1860 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | ||
1861 | |||
1862 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1863 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | ||
1864 | |||
1865 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ | ||
1866 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); | ||
1867 | |||
1868 | if (err==ZIP_OK) /* total number of entries in the central dir */ | ||
1869 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); | ||
1870 | |||
1871 | if (err==ZIP_OK) /* size of the central directory */ | ||
1872 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); | ||
1873 | |||
1874 | if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ | ||
1875 | { | ||
1876 | ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | ||
1877 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); | ||
1878 | } | ||
1879 | return err; | ||
1880 | } | ||
1881 | int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) | ||
1882 | { | ||
1883 | int err = ZIP_OK; | ||
1884 | |||
1885 | /*signature*/ | ||
1886 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); | ||
1887 | |||
1888 | if (err==ZIP_OK) /* number of this disk */ | ||
1889 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); | ||
1890 | |||
1891 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ | ||
1892 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); | ||
1893 | |||
1894 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ | ||
1895 | { | ||
1896 | { | ||
1897 | if(zi->number_entry >= 0xFFFF) | ||
1898 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */ | ||
1899 | else | ||
1900 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); | ||
1901 | } | ||
1902 | } | ||
1903 | |||
1904 | if (err==ZIP_OK) /* total number of entries in the central dir */ | ||
1905 | { | ||
1906 | if(zi->number_entry >= 0xFFFF) | ||
1907 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); /* use value in ZIP64 record */ | ||
1908 | else | ||
1909 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); | ||
1910 | } | ||
1911 | |||
1912 | if (err==ZIP_OK) /* size of the central directory */ | ||
1913 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); | ||
1914 | |||
1915 | if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ | ||
1916 | { | ||
1917 | ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | ||
1918 | if(pos >= 0xffffffff) | ||
1919 | { | ||
1920 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); | ||
1921 | } | ||
1922 | else | ||
1923 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); | ||
1924 | } | ||
1925 | |||
1926 | return err; | ||
1927 | } | ||
1928 | |||
1929 | int Write_GlobalComment(zip64_internal* zi, const char* global_comment) | ||
1930 | { | ||
1931 | int err = ZIP_OK; | ||
1932 | uInt size_global_comment = 0; | ||
1933 | |||
1934 | if(global_comment != NULL) | ||
1935 | size_global_comment = (uInt)strlen(global_comment); | ||
1936 | |||
1937 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); | ||
1938 | |||
1939 | if (err == ZIP_OK && size_global_comment > 0) | ||
1940 | { | ||
1941 | if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) | ||
1942 | err = ZIP_ERRNO; | ||
1943 | } | ||
1944 | return err; | ||
1945 | } | ||
1946 | |||
1947 | extern int ZEXPORT zipClose (zipFile file, const char* global_comment) | ||
1948 | { | ||
1949 | zip64_internal* zi; | ||
1950 | int err = 0; | ||
1951 | uLong size_centraldir = 0; | ||
1952 | ZPOS64_T centraldir_pos_inzip; | ||
1953 | ZPOS64_T pos; | ||
1954 | |||
1955 | if (file == NULL) | ||
1956 | return ZIP_PARAMERROR; | ||
1957 | |||
1958 | zi = (zip64_internal*)file; | ||
1959 | |||
1960 | if (zi->in_opened_file_inzip == 1) | ||
1961 | { | ||
1962 | err = zipCloseFileInZip (file); | ||
1963 | } | ||
1964 | |||
1965 | #ifndef NO_ADDFILEINEXISTINGZIP | ||
1966 | if (global_comment==NULL) | ||
1967 | global_comment = zi->globalcomment; | ||
1968 | #endif | ||
1969 | |||
1970 | centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); | ||
1971 | |||
1972 | if (err==ZIP_OK) | ||
1973 | { | ||
1974 | linkedlist_datablock_internal* ldi = zi->central_dir.first_block; | ||
1975 | while (ldi!=NULL) | ||
1976 | { | ||
1977 | if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) | ||
1978 | { | ||
1979 | if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) | ||
1980 | err = ZIP_ERRNO; | ||
1981 | } | ||
1982 | |||
1983 | size_centraldir += ldi->filled_in_this_block; | ||
1984 | ldi = ldi->next_datablock; | ||
1985 | } | ||
1986 | } | ||
1987 | free_linkedlist(&(zi->central_dir)); | ||
1988 | |||
1989 | pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | ||
1990 | if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) | ||
1991 | { | ||
1992 | ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); | ||
1993 | Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); | ||
1994 | |||
1995 | Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); | ||
1996 | } | ||
1997 | |||
1998 | if (err==ZIP_OK) | ||
1999 | err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); | ||
2000 | |||
2001 | if(err == ZIP_OK) | ||
2002 | err = Write_GlobalComment(zi, global_comment); | ||
2003 | |||
2004 | if ((zi->flags & ZIP_AUTO_CLOSE) != 0) { | ||
2005 | if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) { | ||
2006 | if (err == ZIP_OK) | ||
2007 | err = ZIP_ERRNO; | ||
2008 | } | ||
2009 | } else { | ||
2010 | if (ZFAKECLOSE64(zi->z_filefunc,zi->filestream) != 0) { | ||
2011 | if (err == ZIP_OK) | ||
2012 | err = ZIP_ERRNO; | ||
2013 | } | ||
2014 | } | ||
2015 | |||
2016 | #ifndef NO_ADDFILEINEXISTINGZIP | ||
2017 | TRYFREE(zi->globalcomment); | ||
2018 | #endif | ||
2019 | TRYFREE(zi); | ||
2020 | |||
2021 | return err; | ||
2022 | } | ||
2023 | |||
2024 | extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) | ||
2025 | { | ||
2026 | char* p = pData; | ||
2027 | int size = 0; | ||
2028 | char* pNewHeader; | ||
2029 | char* pTmp; | ||
2030 | short header; | ||
2031 | short dataSize; | ||
2032 | |||
2033 | int retVal = ZIP_OK; | ||
2034 | |||
2035 | if(pData == NULL || *dataLen < 4) | ||
2036 | return ZIP_PARAMERROR; | ||
2037 | |||
2038 | pNewHeader = (char*)ALLOC(*dataLen); | ||
2039 | if(!pNewHeader) { | ||
2040 | return Z_MEM_ERROR; | ||
2041 | } | ||
2042 | pTmp = pNewHeader; | ||
2043 | |||
2044 | while(p < (pData + *dataLen)) | ||
2045 | { | ||
2046 | header = *(short*)p; | ||
2047 | dataSize = *(((short*)p)+1); | ||
2048 | |||
2049 | if( header == sHeader ) /* Header found. */ | ||
2050 | { | ||
2051 | p += dataSize + 4; /* skip it. do not copy to temp buffer */ | ||
2052 | } | ||
2053 | else | ||
2054 | { | ||
2055 | /* Extra Info block should not be removed, So copy it to the temp buffer. */ | ||
2056 | memcpy(pTmp, p, dataSize + 4); | ||
2057 | p += dataSize + 4; | ||
2058 | size += dataSize + 4; | ||
2059 | } | ||
2060 | |||
2061 | } | ||
2062 | |||
2063 | if(size < *dataLen) | ||
2064 | { | ||
2065 | /* clean old extra info block. */ | ||
2066 | memset(pData,0, *dataLen); | ||
2067 | |||
2068 | /* copy the new extra info block over the old */ | ||
2069 | if(size > 0) | ||
2070 | memcpy(pData, pNewHeader, size); | ||
2071 | |||
2072 | /* set the new extra info size */ | ||
2073 | *dataLen = size; | ||
2074 | |||
2075 | retVal = ZIP_OK; | ||
2076 | } | ||
2077 | else | ||
2078 | retVal = ZIP_ERRNO; | ||
2079 | |||
2080 | TRYFREE(pNewHeader); | ||
2081 | |||
2082 | return retVal; | ||
2083 | } | ||
2084 | |||
2085 | int ZEXPORT zipSetFlags(zipFile file, unsigned flags) | ||
2086 | { | ||
2087 | zip64_internal* zi; | ||
2088 | if (file == NULL) | ||
2089 | return ZIP_PARAMERROR; | ||
2090 | zi = (zip64_internal*)file; | ||
2091 | zi->flags |= flags; | ||
2092 | // If the output is non-seekable, the data descriptor is needed. | ||
2093 | if ((zi->flags & ZIP_SEQUENTIAL) != 0) { | ||
2094 | zi->flags |= ZIP_WRITE_DATA_DESCRIPTOR; | ||
2095 | } | ||
2096 | return ZIP_OK; | ||
2097 | } | ||
2098 | |||
2099 | int ZEXPORT zipClearFlags(zipFile file, unsigned flags) | ||
2100 | { | ||
2101 | zip64_internal* zi; | ||
2102 | if (file == NULL) | ||
2103 | return ZIP_PARAMERROR; | ||
2104 | zi = (zip64_internal*)file; | ||
2105 | zi->flags &= ~flags; | ||
2106 | // If the data descriptor is not written, we can't use a non-seekable output. | ||
2107 | if ((zi->flags & ZIP_WRITE_DATA_DESCRIPTOR) == 0) { | ||
2108 | zi->flags &= ~ZIP_SEQUENTIAL; | ||
2109 | } | ||
2110 | return ZIP_OK; | ||
2111 | } | ||
diff --git a/utils/rbutilqt/quazip/zip.h b/utils/rbutilqt/quazip/zip.h new file mode 100644 index 0000000000..114a1bf6e7 --- /dev/null +++ b/utils/rbutilqt/quazip/zip.h | |||
@@ -0,0 +1,391 @@ | |||
1 | /* zip.h -- IO on .zip files using zlib | ||
2 | Version 1.1, February 14h, 2010 | ||
3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) | ||
4 | |||
5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) | ||
6 | |||
7 | Modifications for Zip64 support | ||
8 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | ||
9 | |||
10 | For more info read MiniZip_info.txt | ||
11 | |||
12 | --------------------------------------------------------------------------- | ||
13 | |||
14 | Condition of use and distribution are the same than zlib : | ||
15 | |||
16 | This software is provided 'as-is', without any express or implied | ||
17 | warranty. In no event will the authors be held liable for any damages | ||
18 | arising from the use of this software. | ||
19 | |||
20 | Permission is granted to anyone to use this software for any purpose, | ||
21 | including commercial applications, and to alter it and redistribute it | ||
22 | freely, subject to the following restrictions: | ||
23 | |||
24 | 1. The origin of this software must not be misrepresented; you must not | ||
25 | claim that you wrote the original software. If you use this software | ||
26 | in a product, an acknowledgment in the product documentation would be | ||
27 | appreciated but is not required. | ||
28 | 2. Altered source versions must be plainly marked as such, and must not be | ||
29 | misrepresented as being the original software. | ||
30 | 3. This notice may not be removed or altered from any source distribution. | ||
31 | |||
32 | --------------------------------------------------------------------------- | ||
33 | |||
34 | Changes | ||
35 | |||
36 | See header of zip.h | ||
37 | |||
38 | --------------------------------------------------------------------------- | ||
39 | |||
40 | As per the requirement above, this file is plainly marked as modified | ||
41 | by Sergey A. Tachenov. Most modifications include the I/O API redesign | ||
42 | to support QIODevice interface. Some improvements and small fixes were also made. | ||
43 | |||
44 | */ | ||
45 | |||
46 | #ifndef _zip12_H | ||
47 | #define _zip12_H | ||
48 | |||
49 | #ifdef __cplusplus | ||
50 | extern "C" { | ||
51 | #endif | ||
52 | |||
53 | //#define HAVE_BZIP2 | ||
54 | |||
55 | #ifndef _ZLIB_H | ||
56 | #include <zlib.h> | ||
57 | #endif | ||
58 | |||
59 | #ifndef _ZLIBIOAPI_H | ||
60 | #include "ioapi.h" | ||
61 | #endif | ||
62 | |||
63 | #ifdef HAVE_BZIP2 | ||
64 | #include "bzlib.h" | ||
65 | #endif | ||
66 | |||
67 | #define Z_BZIP2ED 12 | ||
68 | |||
69 | #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) | ||
70 | /* like the STRICT of WIN32, we define a pointer that cannot be converted | ||
71 | from (void*) without cast */ | ||
72 | typedef struct TagzipFile__ { int unused; } zipFile__; | ||
73 | typedef zipFile__ *zipFile; | ||
74 | #else | ||
75 | typedef voidp zipFile; | ||
76 | #endif | ||
77 | |||
78 | #define ZIP_OK (0) | ||
79 | #define ZIP_EOF (0) | ||
80 | #define ZIP_ERRNO (Z_ERRNO) | ||
81 | #define ZIP_PARAMERROR (-102) | ||
82 | #define ZIP_BADZIPFILE (-103) | ||
83 | #define ZIP_INTERNALERROR (-104) | ||
84 | |||
85 | #define ZIP_WRITE_DATA_DESCRIPTOR 0x8u | ||
86 | #define ZIP_AUTO_CLOSE 0x1u | ||
87 | #define ZIP_SEQUENTIAL 0x2u | ||
88 | #define ZIP_ENCODING_UTF8 0x0800u | ||
89 | #define ZIP_DEFAULT_FLAGS (ZIP_AUTO_CLOSE | ZIP_WRITE_DATA_DESCRIPTOR) | ||
90 | |||
91 | #ifndef DEF_MEM_LEVEL | ||
92 | # if MAX_MEM_LEVEL >= 8 | ||
93 | # define DEF_MEM_LEVEL 8 | ||
94 | # else | ||
95 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL | ||
96 | # endif | ||
97 | #endif | ||
98 | /* default memLevel */ | ||
99 | |||
100 | /* tm_zip contain date/time info */ | ||
101 | typedef struct tm_zip_s | ||
102 | { | ||
103 | uInt tm_sec; /* seconds after the minute - [0,59] */ | ||
104 | uInt tm_min; /* minutes after the hour - [0,59] */ | ||
105 | uInt tm_hour; /* hours since midnight - [0,23] */ | ||
106 | uInt tm_mday; /* day of the month - [1,31] */ | ||
107 | uInt tm_mon; /* months since January - [0,11] */ | ||
108 | uInt tm_year; /* years - [1980..2044] */ | ||
109 | } tm_zip; | ||
110 | |||
111 | typedef struct | ||
112 | { | ||
113 | tm_zip tmz_date; /* date in understandable format */ | ||
114 | uLong dosDate; /* if dos_date == 0, tmu_date is used */ | ||
115 | /* uLong flag; */ /* general purpose bit flag 2 bytes */ | ||
116 | |||
117 | uLong internal_fa; /* internal file attributes 2 bytes */ | ||
118 | uLong external_fa; /* external file attributes 4 bytes */ | ||
119 | } zip_fileinfo; | ||
120 | |||
121 | typedef const char* zipcharpc; | ||
122 | |||
123 | |||
124 | #define APPEND_STATUS_CREATE (0) | ||
125 | #define APPEND_STATUS_CREATEAFTER (1) | ||
126 | #define APPEND_STATUS_ADDINZIP (2) | ||
127 | |||
128 | extern zipFile ZEXPORT zipOpen OF((voidpf file, int append)); | ||
129 | extern zipFile ZEXPORT zipOpen64 OF((voidpf file, int append)); | ||
130 | /* | ||
131 | Create a zipfile. | ||
132 | the file argument depends on the API used, for QuaZIP it's a QIODevice | ||
133 | pointer. | ||
134 | if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip | ||
135 | will be created at the end of the file. | ||
136 | (useful if the file contain a self extractor code) | ||
137 | if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will | ||
138 | add files in existing zip (be sure you don't add file that doesn't exist) | ||
139 | If the zipfile cannot be opened, the return value is NULL. | ||
140 | Else, the return value is a zipFile Handle, usable with other function | ||
141 | of this zip package. | ||
142 | */ | ||
143 | |||
144 | /* Note : there is no delete function into a zipfile. | ||
145 | If you want delete file into a zipfile, you must open a zipfile, and create another | ||
146 | Of couse, you can use RAW reading and writing to copy the file you did not want delte | ||
147 | */ | ||
148 | |||
149 | extern zipFile ZEXPORT zipOpen2 OF((voidpf file, | ||
150 | int append, | ||
151 | zipcharpc* globalcomment, | ||
152 | zlib_filefunc_def* pzlib_filefunc_def)); | ||
153 | |||
154 | extern zipFile ZEXPORT zipOpen2_64 OF((voidpf file, | ||
155 | int append, | ||
156 | zipcharpc* globalcomment, | ||
157 | zlib_filefunc64_def* pzlib_filefunc_def)); | ||
158 | |||
159 | /* | ||
160 | * Exported by Sergey A. Tachenov to suit the needs of QuaZIP. | ||
161 | * Note that this function MAY change signature in order to | ||
162 | * provide new QuaZIP features. You have been warned! | ||
163 | * */ | ||
164 | extern zipFile ZEXPORT zipOpen3 (voidpf file, | ||
165 | int append, | ||
166 | zipcharpc* globalcomment, | ||
167 | zlib_filefunc64_32_def* pzlib_filefunc64_32_def, | ||
168 | unsigned flags); | ||
169 | |||
170 | extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, | ||
171 | const char* filename, | ||
172 | const zip_fileinfo* zipfi, | ||
173 | const void* extrafield_local, | ||
174 | uInt size_extrafield_local, | ||
175 | const void* extrafield_global, | ||
176 | uInt size_extrafield_global, | ||
177 | const char* comment, | ||
178 | int method, | ||
179 | int level)); | ||
180 | |||
181 | extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, | ||
182 | const char* filename, | ||
183 | const zip_fileinfo* zipfi, | ||
184 | const void* extrafield_local, | ||
185 | uInt size_extrafield_local, | ||
186 | const void* extrafield_global, | ||
187 | uInt size_extrafield_global, | ||
188 | const char* comment, | ||
189 | int method, | ||
190 | int level, | ||
191 | int zip64)); | ||
192 | |||
193 | /* | ||
194 | Open a file in the ZIP for writing. | ||
195 | filename : the filename in zip (if NULL, '-' without quote will be used | ||
196 | *zipfi contain supplemental information | ||
197 | if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local | ||
198 | contains the extrafield data the the local header | ||
199 | if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global | ||
200 | contains the extrafield data the the local header | ||
201 | if comment != NULL, comment contain the comment string | ||
202 | method contain the compression method (0 for store, Z_DEFLATED for deflate) | ||
203 | level contain the level of compression (can be Z_DEFAULT_COMPRESSION) | ||
204 | zip64 is set to 1 if a zip64 extended information block should be added to the local file header. | ||
205 | this MUST be '1' if the uncompressed size is >= 0xffffffff. | ||
206 | |||
207 | */ | ||
208 | |||
209 | |||
210 | extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, | ||
211 | const char* filename, | ||
212 | const zip_fileinfo* zipfi, | ||
213 | const void* extrafield_local, | ||
214 | uInt size_extrafield_local, | ||
215 | const void* extrafield_global, | ||
216 | uInt size_extrafield_global, | ||
217 | const char* comment, | ||
218 | int method, | ||
219 | int level, | ||
220 | int raw)); | ||
221 | |||
222 | |||
223 | extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, | ||
224 | const char* filename, | ||
225 | const zip_fileinfo* zipfi, | ||
226 | const void* extrafield_local, | ||
227 | uInt size_extrafield_local, | ||
228 | const void* extrafield_global, | ||
229 | uInt size_extrafield_global, | ||
230 | const char* comment, | ||
231 | int method, | ||
232 | int level, | ||
233 | int raw, | ||
234 | int zip64)); | ||
235 | /* | ||
236 | Same than zipOpenNewFileInZip, except if raw=1, we write raw file | ||
237 | */ | ||
238 | |||
239 | extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, | ||
240 | const char* filename, | ||
241 | const zip_fileinfo* zipfi, | ||
242 | const void* extrafield_local, | ||
243 | uInt size_extrafield_local, | ||
244 | const void* extrafield_global, | ||
245 | uInt size_extrafield_global, | ||
246 | const char* comment, | ||
247 | int method, | ||
248 | int level, | ||
249 | int raw, | ||
250 | int windowBits, | ||
251 | int memLevel, | ||
252 | int strategy, | ||
253 | const char* password, | ||
254 | uLong crcForCrypting)); | ||
255 | |||
256 | extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, | ||
257 | const char* filename, | ||
258 | const zip_fileinfo* zipfi, | ||
259 | const void* extrafield_local, | ||
260 | uInt size_extrafield_local, | ||
261 | const void* extrafield_global, | ||
262 | uInt size_extrafield_global, | ||
263 | const char* comment, | ||
264 | int method, | ||
265 | int level, | ||
266 | int raw, | ||
267 | int windowBits, | ||
268 | int memLevel, | ||
269 | int strategy, | ||
270 | const char* password, | ||
271 | uLong crcForCrypting, | ||
272 | int zip64 | ||
273 | )); | ||
274 | |||
275 | /* | ||
276 | Same than zipOpenNewFileInZip2, except | ||
277 | windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 | ||
278 | password : crypting password (NULL for no crypting) | ||
279 | crcForCrypting : crc of file to compress (needed for crypting) | ||
280 | */ | ||
281 | |||
282 | extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, | ||
283 | const char* filename, | ||
284 | const zip_fileinfo* zipfi, | ||
285 | const void* extrafield_local, | ||
286 | uInt size_extrafield_local, | ||
287 | const void* extrafield_global, | ||
288 | uInt size_extrafield_global, | ||
289 | const char* comment, | ||
290 | int method, | ||
291 | int level, | ||
292 | int raw, | ||
293 | int windowBits, | ||
294 | int memLevel, | ||
295 | int strategy, | ||
296 | const char* password, | ||
297 | uLong crcForCrypting, | ||
298 | uLong versionMadeBy, | ||
299 | uLong flagBase | ||
300 | )); | ||
301 | |||
302 | |||
303 | extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, | ||
304 | const char* filename, | ||
305 | const zip_fileinfo* zipfi, | ||
306 | const void* extrafield_local, | ||
307 | uInt size_extrafield_local, | ||
308 | const void* extrafield_global, | ||
309 | uInt size_extrafield_global, | ||
310 | const char* comment, | ||
311 | int method, | ||
312 | int level, | ||
313 | int raw, | ||
314 | int windowBits, | ||
315 | int memLevel, | ||
316 | int strategy, | ||
317 | const char* password, | ||
318 | uLong crcForCrypting, | ||
319 | uLong versionMadeBy, | ||
320 | uLong flagBase, | ||
321 | int zip64 | ||
322 | )); | ||
323 | /* | ||
324 | Same than zipOpenNewFileInZip4, except | ||
325 | versionMadeBy : value for Version made by field | ||
326 | flag : value for flag field (compression level info will be added) | ||
327 | */ | ||
328 | |||
329 | |||
330 | extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, | ||
331 | const void* buf, | ||
332 | unsigned len)); | ||
333 | /* | ||
334 | Write data in the zipfile | ||
335 | */ | ||
336 | |||
337 | extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); | ||
338 | /* | ||
339 | Close the current file in the zipfile | ||
340 | */ | ||
341 | |||
342 | extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, | ||
343 | uLong uncompressed_size, | ||
344 | uLong crc32)); | ||
345 | |||
346 | extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, | ||
347 | ZPOS64_T uncompressed_size, | ||
348 | uLong crc32)); | ||
349 | |||
350 | /* | ||
351 | Close the current file in the zipfile, for file opened with | ||
352 | parameter raw=1 in zipOpenNewFileInZip2 | ||
353 | uncompressed_size and crc32 are value for the uncompressed size | ||
354 | */ | ||
355 | |||
356 | extern int ZEXPORT zipClose OF((zipFile file, | ||
357 | const char* global_comment)); | ||
358 | /* | ||
359 | Close the zipfile | ||
360 | */ | ||
361 | |||
362 | |||
363 | extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); | ||
364 | /* | ||
365 | zipRemoveExtraInfoBlock - Added by Mathias Svensson | ||
366 | |||
367 | Remove extra information block from a extra information data for the local file header or central directory header | ||
368 | |||
369 | It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. | ||
370 | |||
371 | 0x0001 is the signature header for the ZIP64 extra information blocks | ||
372 | |||
373 | usage. | ||
374 | Remove ZIP64 Extra information from a central director extra field data | ||
375 | zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); | ||
376 | |||
377 | Remove ZIP64 Extra information from a Local File Header extra field data | ||
378 | zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); | ||
379 | */ | ||
380 | |||
381 | /* | ||
382 | Added by Sergey A. Tachenov to tweak zipping behaviour. | ||
383 | */ | ||
384 | extern int ZEXPORT zipSetFlags(zipFile file, unsigned flags); | ||
385 | extern int ZEXPORT zipClearFlags(zipFile file, unsigned flags); | ||
386 | |||
387 | #ifdef __cplusplus | ||
388 | } | ||
389 | #endif | ||
390 | |||
391 | #endif /* _zip64_H */ | ||