Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Archive/Zip/Reader.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2024. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6// @todo add Stroika wrapper on this (thirdpartyproducts)
7#ifdef HAVE_BZIP2
8#include "bzlib.h"
9#endif
10
13#include "Stroika/Foundation/Streams/MemoryStream.h"
14
15#include "Reader.h"
16
17/*
18 * NOTE/CREDIT:
19 * This code originally cribbed from ZLib (http://www.zlib.net/) 1.2.8 contrib/minizip
20 *
21 Version 1.1, February 14h, 2010
22 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
23
24 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
25
26 Modifications for Zip64 support
27 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
28
29 For more info read MiniZip_info.txt
30
31 ---------------------------------------------------------------------------
32
33 Condition of use and distribution are the same than zlib :
34
35 This software is provided 'as-is', without any express or implied
36 warranty. In no event will the authors be held liable for any damages
37 arising from the use of this software.
38
39 Permission is granted to anyone to use this software for any purpose,
40 including commercial applications, and to alter it and redistribute it
41 freely, subject to the following restrictions:
42
43 1. The origin of this software must not be misrepresented; you must not
44 claim that you wrote the original software. If you use this software
45 in a product, an acknowledgment in the product documentation would be
46 appreciated but is not required.
47 2. Altered source versions must be plainly marked as such, and must not be
48 misrepresented as being the original software.
49 3. This notice may not be removed or altered from any source distribution.
50....
51 Version 1.1, February 14h, 2010
52 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
53
54 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
55
56 Modifications of Unzip for Zip64
57 Copyright (C) 2007-2008 Even Rouault
58
59 Modifications for Zip64 support on both zip and unzip
60 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
61
62 For more info read MiniZip_info.txt
63
64 ---------------------------------------------------------------------------------
65
66 Condition of use and distribution are the same than zlib :
67
68 This software is provided 'as-is', without any express or implied
69 warranty. In no event will the authors be held liable for any damages
70 arising from the use of this software.
71
72 Permission is granted to anyone to use this software for any purpose,
73 including commercial applications, and to alter it and redistribute it
74 freely, subject to the following restrictions:
75
76 1. The origin of this software must not be misrepresented; you must not
77 claim that you wrote the original software. If you use this software
78 in a product, an acknowledgment in the product documentation would be
79 appreciated but is not required.
80 2. Altered source versions must be plainly marked as such, and must not be
81 misrepresented as being the original software.
82 3. This notice may not be removed or altered from any source distribution.
83....
84 Copyright (C) 1998-2005 Gilles Vollant
85
86 This code is a modified version of crypting code in Infozip distribution
87
88 The encryption/decryption parts of this source code (as opposed to the
89 non-echoing password parts) were originally written in Europe. The
90 whole source package can be freely distributed, including from the USA.
91 (Prior to January 2000, re-export from the US was a violation of US law.)
92
93 This encryption code is a direct transcription of the algorithm from
94 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
95 file (appnote.txt) is distributed with the PKZIP program (even in the
96 version without encryption capabilities).
97
98 If you don't need crypting in your application, just define symbols
99 NOCRYPT and NOUNCRYPT.
100
101 This code support the "Traditional PKWARE Encryption".
102
103 The new AES encryption added on Zip format by Winzip (see the page
104 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
105 Encryption is not supported.
106....
107 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
108
109 Modifications of Unzip for Zip64
110 Copyright (C) 2007-2008 Even Rouault
111
112 Modifications for Zip64 support on both zip and unzip
113 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
114
115 For more info read MiniZip_info.txt
116 ------------------------------------------------------------------------------------
117 Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
118 compatibility with older software. The following is from the original crypt.c.
119 Code woven in by Terry Thorsen 1/2003.
120
121 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
122
123 See the accompanying file LICENSE, version 2000-Apr-09 or later
124 (the contents of which are also included in zip.h) for terms of use.
125 If, for some reason, all these files are missing, the Info-ZIP license
126 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
127
128 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
129
130 The encryption/decryption parts of this source code (as opposed to the
131 non-echoing password parts) were originally written in Europe. The
132 whole source package can be freely distributed, including from the USA.
133 (Prior to January 2000, re-export from the US was a violation of US law.)
134
135 This encryption code is a direct transcription of the algorithm from
136 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
137 file (appnote.txt) is distributed with the PKZIP program (even in the
138 version without encryption capabilities).
139...
140 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
141
142 Modifications for Zip64 support
143 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
144*/
145
146#if qStroika_HasComponent_zlib
147#include <zlib.h>
148
149using namespace Stroika::Foundation;
151using namespace Stroika::Foundation::DataExchange::Archive;
152
153using std::byte;
154
155namespace {
156 constexpr uint32_t MAXU32 = numeric_limits<uint32_t>::max ();
157}
158
159///// START OF CRYPT.h
160namespace {
161#define CRC32(c, b) ((*(pcrc_32_tab + (((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
162
163 // Return the next byte in the pseudo-random sequence
164 int decrypt_byte (unsigned long* pkeys, [[maybe_unused]] const z_crc_t* pcrc_32_tab)
165 {
166 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
167 * unpredictable manner on 16-bit systems; not a problem
168 * with any known compiler so far, though */
169 temp = ((unsigned)(*(pkeys + 2)) & 0xffff) | 2;
170 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
171 }
172
173 // Update the encryption keys with the next byte of plain text
174 int update_keys (unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c)
175 {
176 (*(pkeys + 0)) = CRC32 ((*(pkeys + 0)), c);
177 (*(pkeys + 1)) += (*(pkeys + 0)) & 0xff;
178 (*(pkeys + 1)) = (*(pkeys + 1)) * 134775813L + 1;
179 {
180 int keyshift = (int)((*(pkeys + 1)) >> 24);
181 (*(pkeys + 2)) = CRC32 ((*(pkeys + 2)), keyshift);
182 }
183 return c;
184 }
185
186 // Initialize the encryption keys and the random header according to the given password.
187 void init_keys (const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
188 {
189 *(pkeys + 0) = 305419896L;
190 *(pkeys + 1) = 591751049L;
191 *(pkeys + 2) = 878082192L;
192 while (*passwd != '\0') {
193 update_keys (pkeys, pcrc_32_tab, (int)*passwd);
194 passwd++;
195 }
196 }
197
198#define zdecode(pkeys, pcrc_32_tab, c) (update_keys (pkeys, pcrc_32_tab, c ^= decrypt_byte (pkeys, pcrc_32_tab)))
199
200#define zencode(pkeys, pcrc_32_tab, c, t) (t = decrypt_byte (pkeys, pcrc_32_tab), update_keys (pkeys, pcrc_32_tab, c), t ^ (c))
201
202#define RAND_HEAD_LEN 12
203
204 /* "last resort" source for second part of crypt seed pattern */
205 constexpr unsigned int ZCR_SEED2 = 3141592654UL; /* use PI as default pattern */
206
207 int crypthead (const char* passwd, /* password string */
208 unsigned char* buf, /* where to write header */
209 int bufSize, unsigned long* pkeys, const z_crc_t* pcrc_32_tab, unsigned long crcForCrypting)
210 {
211 int n; /* index in random header */
212 int t; /* temporary */
213 int c; /* random byte */
214 unsigned char header[RAND_HEAD_LEN - 2]; /* random header */
215 static unsigned calls = 0; /* ensure different random header each time */
216
217 if (bufSize < RAND_HEAD_LEN)
218 return 0;
219
220 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
221 * output of rand() to get less predictability, since rand() is
222 * often poorly implemented.
223 */
224 if (++calls == 1) {
225 srand ((unsigned)(time (NULL) ^ ZCR_SEED2));
226 }
227 init_keys (passwd, pkeys, pcrc_32_tab);
228 for (n = 0; n < RAND_HEAD_LEN - 2; n++) {
229 c = (rand () >> 7) & 0xff;
230 header[n] = (unsigned char)zencode (pkeys, pcrc_32_tab, c, t);
231 }
232 /* Encrypt random header (last two bytes is high word of crc) */
233 init_keys (passwd, pkeys, pcrc_32_tab);
234 for (n = 0; n < RAND_HEAD_LEN - 2; n++) {
235 buf[n] = (unsigned char)zencode (pkeys, pcrc_32_tab, header[n], t);
236 }
237 buf[n++] = (unsigned char)zencode (pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
238 buf[n++] = (unsigned char)zencode (pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
239 return n;
240 }
241}
242///////////// END OF CRYPT.h //////////////////
243
244///// START OF ioapi.h////////////////////
245namespace {
246
247#ifdef HAVE_MINIZIP64_CONF_H
248#include "mz64conf.h"
249#endif
250
251 typedef uint64_t ZPOS64_T;
252
253#define ZLIB_FILEFUNC_SEEK_CUR (1)
254#define ZLIB_FILEFUNC_SEEK_END (2)
255#define ZLIB_FILEFUNC_SEEK_SET (0)
256
257#define ZLIB_FILEFUNC_MODE_READ (1)
258#define ZLIB_FILEFUNC_MODE_WRITE (2)
259#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
260
261#define ZLIB_FILEFUNC_MODE_EXISTING (4)
262#define ZLIB_FILEFUNC_MODE_CREATE (8)
263
264 typedef voidpf (*open_file_func) (voidpf opaque, const char* filename, int mode);
265 typedef uLong (*read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size);
266 typedef uLong (*write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size);
267 typedef int (*close_file_func) (voidpf opaque, voidpf stream);
268 typedef int (*testerror_file_func) (voidpf opaque, voidpf stream);
269
270 typedef long (*tell_file_func) (voidpf opaque, voidpf stream);
271 typedef long (*seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin);
272
273 /* here is the "old" 32 bits structure structure */
274 struct zlib_filefunc_def {
275 open_file_func zopen_file;
276 read_file_func zread_file;
277 write_file_func zwrite_file;
278 tell_file_func ztell_file;
279 seek_file_func zseek_file;
280 close_file_func zclose_file;
281 testerror_file_func zerror_file;
282 voidpf opaque;
283 };
284
285 typedef ZPOS64_T (*tell64_file_func) (voidpf opaque, voidpf stream);
286 typedef long (*seek64_file_func) (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin);
287 typedef voidpf (*open64_file_func) (voidpf opaque, const void* filename, int mode);
288
289 struct zlib_filefunc64_def {
290 open64_file_func zopen64_file;
291 read_file_func zread_file;
292 write_file_func zwrite_file;
293 tell64_file_func ztell64_file;
294 seek64_file_func zseek64_file;
295 close_file_func zclose_file;
296 testerror_file_func zerror_file;
297 voidpf opaque;
298 };
299
300 /* now internal definition, only for zip.c and unzip.h */
301 struct zlib_filefunc64_32_def {
302 zlib_filefunc64_def zfile_func64;
303 open_file_func zopen32_file;
304 tell_file_func ztell32_file;
305 seek_file_func zseek32_file;
306 };
307
308#define ZREAD64(filefunc, filestream, buf, size) \
309 ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque, filestream, buf, size))
310#define ZWRITE64(filefunc, filestream, buf, size) \
311 ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque, filestream, buf, size))
312#define ZCLOSE64(filefunc, filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque, filestream))
313#define ZERROR64(filefunc, filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque, filestream))
314
315 voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc, const void* filename, int mode);
316 long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, ZPOS64_T offset, int origin);
317 ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream);
318
319 void fill_zlib_filefunc64_32_def_from_filefunc32 (zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32);
320
321#define ZOPEN64(filefunc, filename, mode) (call_zopen64 ((&(filefunc)), (filename), (mode)))
322#define ZTELL64(filefunc, filestream) (call_ztell64 ((&(filefunc)), (filestream)))
323#define ZSEEK64(filefunc, filestream, pos, mode) (call_zseek64 ((&(filefunc)), (filestream), (pos), (mode)))
324}
325/////////////////////// END OF IO.h.////////////////////////////////////
326
327/////////////////////////// START OF UNZIP.h ////////////////////////////////////
328namespace {
329
330#define Z_BZIP2ED 12
331
332#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
333 /* like the STRICT of WIN32, we define a pointer that cannot be converted
334 from (void*) without cast */
335 typedef struct TagunzFile__ {
336 int unused;
337 } unzFile__;
338 typedef unzFile__* unzFile;
339#else
340 typedef voidp unzFile;
341#endif
342
343#define UNZ_OK (0)
344#define UNZ_END_OF_LIST_OF_FILE (-100)
345#define UNZ_ERRNO (Z_ERRNO)
346#define UNZ_EOF (0)
347#define UNZ_PARAMERROR (-102)
348#define UNZ_BADZIPFILE (-103)
349#define UNZ_INTERNALERROR (-104)
350#define UNZ_CRCERROR (-105)
351
352 /* tm_unz contain date/time info */
353 struct tm_unz {
354 uInt tm_sec; /* seconds after the minute - [0,59] */
355 uInt tm_min; /* minutes after the hour - [0,59] */
356 uInt tm_hour; /* hours since midnight - [0,23] */
357 uInt tm_mday; /* day of the month - [1,31] */
358 uInt tm_mon; /* months since January - [0,11] */
359 uInt tm_year; /* years - [1980..2044] */
360 };
361
362 /* unz_global_info structure contain global data about the ZIPfile
363 These data comes from the end of central dir */
364 struct unz_global_info64 {
365 ZPOS64_T number_entry; /* total number of entries in
366 the central dir on this disk */
367 uLong size_comment; /* size of the global comment of the zipfile */
368 };
369
370 struct unz_global_info {
371 uLong number_entry; /* total number of entries in
372 the central dir on this disk */
373 uLong size_comment; /* size of the global comment of the zipfile */
374 };
375
376 /* unz_file_info contain information about a file in the zipfile */
377 struct unz_file_info64 {
378 uLong version; /* version made by 2 bytes */
379 uLong version_needed; /* version needed to extract 2 bytes */
380 uLong flag; /* general purpose bit flag 2 bytes */
381 uLong compression_method; /* compression method 2 bytes */
382 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
383 uLong crc; /* crc-32 4 bytes */
384 ZPOS64_T compressed_size; /* compressed size 8 bytes */
385 ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
386 uLong size_filename; /* filename length 2 bytes */
387 uLong size_file_extra; /* extra field length 2 bytes */
388 uLong size_file_comment; /* file comment length 2 bytes */
389
390 uLong disk_num_start; /* disk number start 2 bytes */
391 uLong internal_fa; /* internal file attributes 2 bytes */
392 uLong external_fa; /* external file attributes 4 bytes */
393
394 tm_unz tmu_date;
395 };
396
397 struct unz_file_info {
398 uLong version; /* version made by 2 bytes */
399 uLong version_needed; /* version needed to extract 2 bytes */
400 uLong flag; /* general purpose bit flag 2 bytes */
401 uLong compression_method; /* compression method 2 bytes */
402 uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
403 uLong crc; /* crc-32 4 bytes */
404 uLong compressed_size; /* compressed size 4 bytes */
405 uLong uncompressed_size; /* uncompressed size 4 bytes */
406 uLong size_filename; /* filename length 2 bytes */
407 uLong size_file_extra; /* extra field length 2 bytes */
408 uLong size_file_comment; /* file comment length 2 bytes */
409
410 uLong disk_num_start; /* disk number start 2 bytes */
411 uLong internal_fa; /* internal file attributes 2 bytes */
412 uLong external_fa; /* external file attributes 4 bytes */
413
414 tm_unz tmu_date;
415 };
416
417 int unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity);
418 /*
419 Compare two filename (fileName1,fileName2).
420 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
421 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
422 or strcasecmp)
423 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
424 (like 1 on Unix, 2 on Windows)
425 */
426
427 /*
428 Open a Zip file. path contain the full pathname (by example,
429 on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
430 "zlib/zlib113.zip".
431 If the zipfile cannot be opened (file don't exist or in not valid), the
432 return value is NULL.
433 Else, the return value is a unzFile Handle, usable with other function
434 of this unzip package.
435 the "64" function take a const void* pointer, because the path is just the
436 value passed to the open64_file_func callback.
437 Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
438 is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
439 does not describe the reality
440 */
441 unzFile unzOpen (const char* path);
442 unzFile unzOpen64 (const void* path);
443
444 /*
445 Open a Zip file, like unzOpen, but provide a set of file low level API
446 for read/write the zip file (see ioapi.h)
447 */
448 unzFile unzOpen2 (const char* path, zlib_filefunc_def* pzlib_filefunc_def);
449
450 /*
451 Open a Zip file, like unz64Open, but provide a set of file low level API
452 for read/write the zip file (see ioapi.h)
453 */
454 unzFile unzOpen2_64 (const void* path, zlib_filefunc64_def* pzlib_filefunc_def);
455
456 int unzClose (unzFile file);
457 /*
458 Close a ZipFile opened with unzOpen.
459 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
460 these files MUST be closed with unzCloseCurrentFile before call unzClose.
461 return UNZ_OK if there is no problem. */
462
463 int unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info);
464
465 /*
466 Write info about the ZipFile in the *pglobal_info structure.
467 No preparation of the structure is needed
468 return UNZ_OK if there is no problem. */
469 int unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info);
470
471 /*
472 Get the global comment string of the ZipFile, in the szComment buffer.
473 uSizeBuf is the size of the szComment buffer.
474 return the number of byte copied or an error code <0
475 */
476 int unzGetGlobalComment (unzFile file, char* szComment, uLong uSizeBuf);
477
478 /***************************************************************************/
479 /* Unzip package allow you browse the directory of the zipfile */
480
481 /*
482 Set the current file of the zipfile to the first file.
483 return UNZ_OK if there is no problem
484 */
485 int unzGoToFirstFile (unzFile file);
486
487 /*
488 Set the current file of the zipfile to the next file.
489 return UNZ_OK if there is no problem
490 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
491 */
492 int unzGoToNextFile_ (unzFile file);
493
494 /*
495 Try locate the file szFileName in the zipfile.
496 For the iCaseSensitivity signification, see unzStringFileNameCompare
497
498 return value :
499 UNZ_OK if the file is found. It becomes the current file.
500 UNZ_END_OF_LIST_OF_FILE if the file is not found
501 */
502 int unzLocateFile_ (unzFile file, const char* szFileName, int iCaseSensitivity);
503
504 /* ****************************************** */
505 /* Ryan supplied functions */
506 /* unz_file_info contain information about a file in the zipfile */
507 struct unz_file_pos {
508 uLong pos_in_zip_directory; /* offset in zip file directory */
509 uLong num_of_file; /* # of file */
510 };
511
512 int unzGetFilePos (unzFile file, unz_file_pos* file_pos);
513
514 int unzGoToFilePos (unzFile file, unz_file_pos* file_pos);
515
516 struct unz64_file_pos {
517 ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
518 ZPOS64_T num_of_file; /* # of file */
519 };
520
521 int unzGetFilePos64 (unzFile file, unz64_file_pos* file_pos);
522
523 int unzGoToFilePos64 (unzFile file, const unz64_file_pos* file_pos);
524
525 /* ****************************************** */
526 int unzGetCurrentFileInfo64 (unzFile file, unz_file_info64* pfile_info, char* szFileName, uLong fileNameBufferSize, void* extraField,
527 uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize);
528
529 int unzGetCurrentFileInfo (unzFile file, unz_file_info* pfile_info, char* szFileName, uLong fileNameBufferSize, void* extraField,
530 uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize);
531 /*
532 Get Info about the current file
533 if pfile_info!=NULL, the *pfile_info structure will contain somes info about
534 the current file
535 if szFileName!=NULL, the filemane string will be copied in szFileName
536 (fileNameBufferSize is the size of the buffer)
537 if extraField!=NULL, the extra field information will be copied in extraField
538 (extraFieldBufferSize is the size of the buffer).
539 This is the Central-header version of the extra field
540 if szComment!=NULL, the comment string of the file will be copied in szComment
541 (commentBufferSize is the size of the buffer)
542 */
543
544 ZPOS64_T unzGetCurrentFileZStreamPos64 (unzFile file);
545
546 /***************************************************************************/
547 /* for reading the content of the current zipfile, you can open it, read data
548 from it, and close it (you can close it before reading all the file)
549 */
550 /*
551 Open for reading data the current file in the zipfile.
552 If there is no error, the return value is UNZ_OK.
553 */
554 int unzOpenCurrentFile (unzFile file);
555
556 /*
557 Open for reading data the current file in the zipfile.
558 password is a crypting password
559 If there is no error, the return value is UNZ_OK.
560 */
561 int unzOpenCurrentFilePassword (unzFile file, const char* password);
562
563 /*
564 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
565 if raw==1
566 *method will receive method of compression, *level will receive level of
567 compression
568 note : you can set level parameter as NULL (if you did not want known level,
569 but you CANNOT set method parameter as NULL
570 */
571 int unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw);
572
573 /*
574 Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
575 if raw==1
576 *method will receive method of compression, *level will receive level of
577 compression
578 note : you can set level parameter as NULL (if you did not want known level,
579 but you CANNOT set method parameter as NULL
580 */
581 int unzOpenCurrentFile3_ (unzFile file, int* method, int* level, int raw, const char* password);
582
583 /*
584 Close the file in zip opened with unzOpenCurrentFile
585 Return UNZ_CRCERROR if all the file was read but the CRC is not good
586 */
587 int unzCloseCurrentFile_ (unzFile file);
588
589 /*
590 Read bytes from the current file (opened by unzOpenCurrentFile)
591 buf contain buffer where data must be copied
592 len the size of buf.
593
594 return the number of byte copied if somes bytes are copied
595 return 0 if the end of file was reached
596 return <0 with error code if there is an error
597 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
598 */
599 int unzReadCurrentFile_ (unzFile file, voidp buf, unsigned len);
600
601 z_off_t unztell (unzFile file);
602
603 ZPOS64_T unztell64 (unzFile file);
604 /*
605 Give the current position in uncompressed data
606 */
607
608 /*
609 return 1 if the end of file was reached, 0 elsewhere
610 */
611 int unzeof (unzFile file);
612
613 /*
614 Read extra field from the current file (opened by unzOpenCurrentFile)
615 This is the local-header version of the extra field (sometimes, there is
616 more info in the local-header version than in the central-header)
617
618 if buf==NULL, it return the size of the local extra field
619
620 if buf!=NULL, len is the size of the buffer, the extra header is copied in
621 buf.
622 the return value is the number of bytes copied in buf, or (if <0)
623 the error code
624 */
625 int unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len);
626
627 /***************************************************************************/
628
629 /* Get the current file offset */
630 ZPOS64_T unzGetOffset64 (unzFile file);
631 uLong unzGetOffset (unzFile file);
632
633 /* Set the current file offset */
634 int unzSetOffset64 (unzFile file, ZPOS64_T pos);
635 int unzSetOffset (unzFile file, uLong pos);
636}
637//// END OF unzip.h//////////////////////////////////////////////////////////////
638
639///// START OF IOAPI.c //////////////////
640/* ioapi.h -- IO base function header for compress/uncompress .zip
641 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
642
643 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
644
645 Modifications for Zip64 support
646 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
647
648 For more info read MiniZip_info.txt
649
650*/
651
652namespace {
653 voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc, const void* filename, int mode)
654 {
655 if (pfilefunc->zfile_func64.zopen64_file != NULL)
656 return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque, filename, mode);
657 else {
658 return (*(pfilefunc->zopen32_file)) (pfilefunc->zfile_func64.opaque, (const char*)filename, mode);
659 }
660 }
661 long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, ZPOS64_T offset, int origin)
662 {
663 if (pfilefunc->zfile_func64.zseek64_file != NULL)
664 return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque, filestream, offset, origin);
665 else {
666 uLong offsetTruncated = (uLong)offset;
667 if (offsetTruncated != offset)
668 return -1;
669 else
670 return (*(pfilefunc->zseek32_file)) (pfilefunc->zfile_func64.opaque, filestream, offsetTruncated, origin);
671 }
672 }
673 ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc, voidpf filestream)
674 {
675 if (pfilefunc->zfile_func64.zseek64_file != NULL)
676 return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque, filestream);
677 else {
678 uLong tell_uLong = (*(pfilefunc->ztell32_file)) (pfilefunc->zfile_func64.opaque, filestream);
679 if ((tell_uLong) == numeric_limits<uLong>::max ())
680 return (ZPOS64_T)-1;
681 else
682 return tell_uLong;
683 }
684 }
685 void fill_zlib_filefunc64_32_def_from_filefunc32 (zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32)
686 {
687 p_filefunc64_32->zfile_func64.zopen64_file = NULL;
688 p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
689 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
690 p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
691 p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
692 p_filefunc64_32->zfile_func64.ztell64_file = NULL;
693 p_filefunc64_32->zfile_func64.zseek64_file = NULL;
694 p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
695 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
696 p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
697 p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
698 p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
699 }
700}
701///////////////////////////////////////////////// end of IOAPI.c /////////////////////
702
703///////////////////////////////// START OF unzip.c ////////////////////
704namespace {
705
706#ifndef NOUNCRYPT
707#define NOUNCRYPT
708#endif
709
710#ifndef CASESENSITIVITYDEFAULT_NO
711#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
712#define CASESENSITIVITYDEFAULT_NO
713#endif
714#endif
715
716#ifndef UNZ_BUFSIZE
717#define UNZ_BUFSIZE (16384)
718#endif
719
720#ifndef UNZ_MAXFILENAMEINZIP
721#define UNZ_MAXFILENAMEINZIP (256)
722#endif
723
724#ifndef ALLOC
725#define ALLOC(size) (malloc (size))
726#endif
727#ifndef TRYFREE
728#define TRYFREE(p) \
729 { \
730 if (p) \
731 free (p); \
732 }
733#endif
734
735#define SIZECENTRALDIRITEM (0x2e)
736#define SIZEZIPLOCALHEADER (0x1e)
737
738 // const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
739
740 /* unz_file_info_interntal contain internal info about a file in zipfile*/
741 typedef struct unz_file_info64_internal_s {
742 ZPOS64_T offset_curfile; /* relative offset of local header 8 bytes */
743 } unz_file_info64_internal;
744
745 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
746 when reading and decompress it */
747 typedef struct {
748 char* read_buffer; /* internal buffer for compressed data */
749 z_stream stream; /* zLib stream structure for inflate */
750
751#ifdef HAVE_BZIP2
752 bz_stream bstream; /* bzLib stream structure for bziped */
753#endif
754
755 ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
756 uLong stream_initialised; /* flag set if stream structure is initialised*/
757
758 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
759 uInt size_local_extrafield; /* size of the local extra field */
760 ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
761 ZPOS64_T total_out_64;
762
763 uLong crc32; /* crc32 of all data uncompressed */
764 uLong crc32_wait; /* crc32 we must obtain after decompress all */
765 ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
766 ZPOS64_T rest_read_uncompressed; /*number of byte to be obtained after decomp*/
767 zlib_filefunc64_32_def z_filefunc;
768 voidpf filestream; /* io structore of the zipfile */
769 uLong compression_method; /* compression method (0==store) */
770 ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/
771 int raw;
772 } file_in_zip64_read_info_s;
773
774 /* unz64_s contain internal information about the zipfile
775 */
776 struct unz64_s {
777 zlib_filefunc64_32_def z_filefunc;
778 int is64bitOpenFunction;
779 voidpf filestream; /* io structore of the zipfile */
780 unz_global_info64 gi; /* public global information */
781 ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/
782 ZPOS64_T num_file; /* number of the current file in the zipfile*/
783 ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
784 ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
785 ZPOS64_T central_pos; /* position of the beginning of the central dir*/
786
787 ZPOS64_T size_central_dir; /* size of the central directory */
788 ZPOS64_T offset_central_dir; /* offset of start of central directory with
789 respect to the starting disk number */
790
791 unz_file_info64 cur_file_info; /* public info about the current file in zip*/
792 unz_file_info64_internal cur_file_info_internal; /* private info about it*/
793 file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
794 file if we are decompressing it */
795 int encrypted;
796
797 int isZip64;
798
799#ifndef NOUNCRYPT
800 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
801 const z_crc_t* pcrc_32_tab;
802#endif
803 };
804
805 /* ===========================================================================
806 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
807 for end of file.
808 IN assertion: the stream s has been sucessfully opened for reading.
809 */
810 int unz64local_getByte (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi)
811 {
812 unsigned char c;
813 int err = (int)ZREAD64 (*pzlib_filefunc_def, filestream, &c, 1);
814 if (err == 1) {
815 *pi = (int)c;
816 return UNZ_OK;
817 }
818 else {
819 if (ZERROR64 (*pzlib_filefunc_def, filestream))
820 return UNZ_ERRNO;
821 else
822 return UNZ_EOF;
823 }
824 }
825
826 /* ===========================================================================
827 Reads a long in LSB order from the given gz_stream. Sets
828 */
829 int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
830 {
831 uLong x;
832 int i = 0;
833 int err;
834
835 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
836 x = (uLong)i;
837
838 if (err == UNZ_OK)
839 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
840 x |= ((uLong)i) << 8;
841
842 if (err == UNZ_OK)
843 *pX = x;
844 else
845 *pX = 0;
846 return err;
847 }
848
849 int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
850 {
851 uLong x;
852 int i = 0;
853 int err;
854
855 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
856 x = (uLong)i;
857
858 if (err == UNZ_OK)
859 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
860 x |= ((uLong)i) << 8;
861
862 if (err == UNZ_OK)
863 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
864 x |= ((uLong)i) << 16;
865
866 if (err == UNZ_OK)
867 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
868 x += ((uLong)i) << 24;
869
870 if (err == UNZ_OK)
871 *pX = x;
872 else
873 *pX = 0;
874 return err;
875 }
876
877 int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T* pX)
878 {
879 ZPOS64_T x;
880 int i = 0;
881 int err;
882
883 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
884 x = (ZPOS64_T)i;
885
886 if (err == UNZ_OK)
887 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
888 x |= ((ZPOS64_T)i) << 8;
889
890 if (err == UNZ_OK)
891 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
892 x |= ((ZPOS64_T)i) << 16;
893
894 if (err == UNZ_OK)
895 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
896 x |= ((ZPOS64_T)i) << 24;
897
898 if (err == UNZ_OK)
899 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
900 x |= ((ZPOS64_T)i) << 32;
901
902 if (err == UNZ_OK)
903 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
904 x |= ((ZPOS64_T)i) << 40;
905
906 if (err == UNZ_OK)
907 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
908 x |= ((ZPOS64_T)i) << 48;
909
910 if (err == UNZ_OK)
911 err = unz64local_getByte (pzlib_filefunc_def, filestream, &i);
912 x |= ((ZPOS64_T)i) << 56;
913
914 if (err == UNZ_OK)
915 *pX = x;
916 else
917 *pX = 0;
918 return err;
919 }
920
921 /* My own strcmpi / strcasecmp */
922 int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
923 {
924 for (;;) {
925 char c1 = *(fileName1++);
926 char c2 = *(fileName2++);
927 if ((c1 >= 'a') and (c1 <= 'z'))
928 c1 -= 0x20;
929 if ((c2 >= 'a') and (c2 <= 'z'))
930 c2 -= 0x20;
931 if (c1 == '\0')
932 return ((c2 == '\0') ? 0 : -1);
933 if (c2 == '\0')
934 return 1;
935 if (c1 < c2)
936 return -1;
937 if (c1 > c2)
938 return 1;
939 }
940 }
941
942#ifdef CASESENSITIVITYDEFAULT_NO
943#define CASESENSITIVITYDEFAULTVALUE 2
944#else
945#define CASESENSITIVITYDEFAULTVALUE 1
946#endif
947
948#ifndef STRCMPCASENOSENTIVEFUNCTION
949#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
950#endif
951
952 /*
953 Compare two filename (fileName1,fileName2).
954 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
955 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
956 or strcasecmp)
957 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
958 (like 1 on Unix, 2 on Windows)
959
960 */
961 int unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity)
962
963 {
964 if (iCaseSensitivity == 0)
965 iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE;
966
967 if (iCaseSensitivity == 1)
968 return strcmp (fileName1, fileName2);
969
970 return STRCMPCASENOSENTIVEFUNCTION (fileName1, fileName2);
971 }
972
973 constexpr size_t BUFREADCOMMENT = 0x400;
974
975 /*
976 Locate the Central directory of a zipfile (at the end, just before
977 the global comment)
978 */
979 ZPOS64_T unz64local_SearchCentralDir (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
980 {
981 ZPOS64_T uPosFound = 0;
982
983 if (ZSEEK64 (*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
984 return 0;
985
986 ZPOS64_T uSizeFile = ZTELL64 (*pzlib_filefunc_def, filestream);
987
988 ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */
989 if (uMaxBack > uSizeFile)
990 uMaxBack = uSizeFile;
991
992 unsigned char* buf = (unsigned char*)ALLOC (BUFREADCOMMENT + 4);
993 if (buf == NULL)
994 return 0;
995
996 ZPOS64_T uBackRead = 4;
997 while (uBackRead < uMaxBack) {
998 uLong uReadSize;
999 ZPOS64_T uReadPos;
1000 int i;
1001 if (uBackRead + BUFREADCOMMENT > uMaxBack)
1002 uBackRead = uMaxBack;
1003 else
1004 uBackRead += BUFREADCOMMENT;
1005 uReadPos = uSizeFile - uBackRead;
1006
1007 uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos);
1008 if (ZSEEK64 (*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0)
1009 break;
1010
1011 if (ZREAD64 (*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize)
1012 break;
1013
1014 for (i = (int)uReadSize - 3; i-- > 0;)
1015 if (((*(buf + i)) == 0x50) and ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x05) and ((*(buf + i + 3)) == 0x06)) {
1016 uPosFound = uReadPos + i;
1017 break;
1018 }
1019
1020 if (uPosFound != 0)
1021 break;
1022 }
1023 TRYFREE (buf);
1024 return uPosFound;
1025 }
1026
1027 /*
1028 Locate the Central directory 64 of a zipfile (at the end, just before
1029 the global comment)
1030 */
1031 ZPOS64_T unz64local_SearchCentralDir64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
1032 {
1033 unsigned char* buf;
1034 ZPOS64_T uSizeFile;
1035 ZPOS64_T uBackRead;
1036 ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */
1037 ZPOS64_T uPosFound = 0;
1038 uLong uL;
1039 ZPOS64_T relativeOffset;
1040
1041 if (ZSEEK64 (*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0)
1042 return 0;
1043
1044 uSizeFile = ZTELL64 (*pzlib_filefunc_def, filestream);
1045
1046 if (uMaxBack > uSizeFile)
1047 uMaxBack = uSizeFile;
1048
1049 buf = (unsigned char*)ALLOC (BUFREADCOMMENT + 4);
1050 if (buf == NULL)
1051 return 0;
1052
1053 uBackRead = 4;
1054 while (uBackRead < uMaxBack) {
1055 uLong uReadSize;
1056 ZPOS64_T uReadPos;
1057 int i;
1058 if (uBackRead + BUFREADCOMMENT > uMaxBack)
1059 uBackRead = uMaxBack;
1060 else
1061 uBackRead += BUFREADCOMMENT;
1062 uReadPos = uSizeFile - uBackRead;
1063
1064 uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos);
1065 if (ZSEEK64 (*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0)
1066 break;
1067
1068 if (ZREAD64 (*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize)
1069 break;
1070
1071 for (i = (int)uReadSize - 3; i-- > 0;)
1072 if (((*(buf + i)) == 0x50) and ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x06) and ((*(buf + i + 3)) == 0x07)) {
1073 uPosFound = uReadPos + i;
1074 break;
1075 }
1076
1077 if (uPosFound != 0)
1078 break;
1079 }
1080 TRYFREE (buf);
1081 if (uPosFound == 0)
1082 return 0;
1083
1084 /* Zip64 end of central directory locator */
1085 if (ZSEEK64 (*pzlib_filefunc_def, filestream, uPosFound, ZLIB_FILEFUNC_SEEK_SET) != 0)
1086 return 0;
1087
1088 /* the signature, already checked */
1089 if (unz64local_getLong (pzlib_filefunc_def, filestream, &uL) != UNZ_OK)
1090 return 0;
1091
1092 /* number of the disk with the start of the zip64 end of central directory */
1093 if (unz64local_getLong (pzlib_filefunc_def, filestream, &uL) != UNZ_OK)
1094 return 0;
1095 if (uL != 0)
1096 return 0;
1097
1098 /* relative offset of the zip64 end of central directory record */
1099 if (unz64local_getLong64 (pzlib_filefunc_def, filestream, &relativeOffset) != UNZ_OK)
1100 return 0;
1101
1102 /* total number of disks */
1103 if (unz64local_getLong (pzlib_filefunc_def, filestream, &uL) != UNZ_OK)
1104 return 0;
1105 if (uL != 1)
1106 return 0;
1107
1108 /* Goto end of central directory record */
1109 if (ZSEEK64 (*pzlib_filefunc_def, filestream, relativeOffset, ZLIB_FILEFUNC_SEEK_SET) != 0)
1110 return 0;
1111
1112 /* the signature */
1113 if (unz64local_getLong (pzlib_filefunc_def, filestream, &uL) != UNZ_OK)
1114 return 0;
1115
1116 if (uL != 0x06064b50)
1117 return 0;
1118
1119 return relativeOffset;
1120 }
1121
1122 /*
1123 Open a Zip file. path contain the full pathname (by example,
1124 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
1125 "zlib/zlib114.zip".
1126 If the zipfile cannot be opened (file doesn't exist or in not valid), the
1127 return value is NULL.
1128 Else, the return value is a unzFile Handle, usable with other function
1129 of this unzip package.
1130 */
1131 unzFile unzOpenInternal (const void* path, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, int is64bitOpenFunction)
1132 {
1133 unz64_s us;
1134 unz64_s* s;
1135 ZPOS64_T central_pos;
1136 uLong uL;
1137
1138 uLong number_disk; /* number of the current dist, used for
1139 spaning ZIP, unsupported, always 0*/
1140 uLong number_disk_with_CD; /* number the the disk with central dir, used
1141 for spaning ZIP, unsupported, always 0*/
1142 ZPOS64_T number_entry_CD; /* total number of entries in
1143 the central dir
1144 (same than number_entry on nospan) */
1145
1146 int err = UNZ_OK;
1147
1148 us.z_filefunc.zseek32_file = NULL;
1149 us.z_filefunc.ztell32_file = NULL;
1150
1151 AssertNotNull (pzlib_filefunc64_32_def);
1152 us.z_filefunc = *pzlib_filefunc64_32_def;
1153 us.is64bitOpenFunction = is64bitOpenFunction;
1154
1155 us.filestream = ZOPEN64 (us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);
1156 if (us.filestream == NULL)
1157 return NULL;
1158
1159 central_pos = unz64local_SearchCentralDir64 (&us.z_filefunc, us.filestream);
1160 if (central_pos) {
1161 uLong uS;
1162 ZPOS64_T uL64;
1163
1164 us.isZip64 = 1;
1165
1166 if (ZSEEK64 (us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
1167 err = UNZ_ERRNO;
1168
1169 /* the signature, already checked */
1170 if (unz64local_getLong (&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
1171 err = UNZ_ERRNO;
1172
1173 /* size of zip64 end of central directory record */
1174 if (unz64local_getLong64 (&us.z_filefunc, us.filestream, &uL64) != UNZ_OK)
1175 err = UNZ_ERRNO;
1176
1177 /* version made by */
1178 if (unz64local_getShort (&us.z_filefunc, us.filestream, &uS) != UNZ_OK)
1179 err = UNZ_ERRNO;
1180
1181 /* version needed to extract */
1182 if (unz64local_getShort (&us.z_filefunc, us.filestream, &uS) != UNZ_OK)
1183 err = UNZ_ERRNO;
1184
1185 /* number of this disk */
1186 if (unz64local_getLong (&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK)
1187 err = UNZ_ERRNO;
1188
1189 /* number of the disk with the start of the central directory */
1190 if (unz64local_getLong (&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK)
1191 err = UNZ_ERRNO;
1192
1193 /* total number of entries in the central directory on this disk */
1194 if (unz64local_getLong64 (&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK)
1195 err = UNZ_ERRNO;
1196
1197 /* total number of entries in the central directory */
1198 if (unz64local_getLong64 (&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK)
1199 err = UNZ_ERRNO;
1200
1201 if ((number_entry_CD != us.gi.number_entry) or (number_disk_with_CD != 0) or (number_disk != 0))
1202 err = UNZ_BADZIPFILE;
1203
1204 /* size of the central directory */
1205 if (unz64local_getLong64 (&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK)
1206 err = UNZ_ERRNO;
1207
1208 /* offset of start of central directory with respect to the
1209 starting disk number */
1210 if (unz64local_getLong64 (&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK)
1211 err = UNZ_ERRNO;
1212
1213 us.gi.size_comment = 0;
1214 }
1215 else {
1216 central_pos = unz64local_SearchCentralDir (&us.z_filefunc, us.filestream);
1217 if (central_pos == 0)
1218 err = UNZ_ERRNO;
1219
1220 us.isZip64 = 0;
1221
1222 if (ZSEEK64 (us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
1223 err = UNZ_ERRNO;
1224
1225 /* the signature, already checked */
1226 if (unz64local_getLong (&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
1227 err = UNZ_ERRNO;
1228
1229 /* number of this disk */
1230 if (unz64local_getShort (&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK)
1231 err = UNZ_ERRNO;
1232
1233 /* number of the disk with the start of the central directory */
1234 if (unz64local_getShort (&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK)
1235 err = UNZ_ERRNO;
1236
1237 /* total number of entries in the central dir on this disk */
1238 if (unz64local_getShort (&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
1239 err = UNZ_ERRNO;
1240 us.gi.number_entry = uL;
1241
1242 /* total number of entries in the central dir */
1243 if (unz64local_getShort (&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
1244 err = UNZ_ERRNO;
1245 number_entry_CD = uL;
1246
1247 if ((number_entry_CD != us.gi.number_entry) || (number_disk_with_CD != 0) || (number_disk != 0))
1248 err = UNZ_BADZIPFILE;
1249
1250 /* size of the central directory */
1251 if (unz64local_getLong (&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
1252 err = UNZ_ERRNO;
1253 us.size_central_dir = uL;
1254
1255 /* offset of start of central directory with respect to the
1256 starting disk number */
1257 if (unz64local_getLong (&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
1258 err = UNZ_ERRNO;
1259 us.offset_central_dir = uL;
1260
1261 /* zipfile comment length */
1262 if (unz64local_getShort (&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK)
1263 err = UNZ_ERRNO;
1264 }
1265
1266 if ((central_pos < us.offset_central_dir + us.size_central_dir) && (err == UNZ_OK))
1267 err = UNZ_BADZIPFILE;
1268
1269 if (err != UNZ_OK) {
1270 ZCLOSE64 (us.z_filefunc, us.filestream);
1271 return NULL;
1272 }
1273
1274 us.byte_before_the_zipfile = central_pos - (us.offset_central_dir + us.size_central_dir);
1275 us.central_pos = central_pos;
1276 us.pfile_in_zip_read = NULL;
1277 us.encrypted = 0;
1278
1279 s = (unz64_s*)ALLOC (sizeof (unz64_s));
1280 if (s != NULL) {
1281 *s = us;
1282 unzGoToFirstFile ((unzFile)s);
1283 }
1284 return (unzFile)s;
1285 }
1286
1287 unzFile unzOpen2 (const char* path, zlib_filefunc_def* pzlib_filefunc32_def)
1288 {
1289 if (pzlib_filefunc32_def != NULL) {
1290 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
1291 fill_zlib_filefunc64_32_def_from_filefunc32 (&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);
1292 return unzOpenInternal (path, &zlib_filefunc64_32_def_fill, 0);
1293 }
1294 else
1295 return unzOpenInternal (path, NULL, 0);
1296 }
1297
1298 unzFile unzOpen2_64 (const void* path, zlib_filefunc64_def* pzlib_filefunc_def)
1299 {
1300 if (pzlib_filefunc_def != NULL) {
1301 zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
1302 zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
1303 zlib_filefunc64_32_def_fill.ztell32_file = NULL;
1304 zlib_filefunc64_32_def_fill.zseek32_file = NULL;
1305 return unzOpenInternal (path, &zlib_filefunc64_32_def_fill, 1);
1306 }
1307 else
1308 return unzOpenInternal (path, NULL, 1);
1309 }
1310
1311 unzFile unzOpen (const char* path)
1312 {
1313 return unzOpenInternal (path, NULL, 0);
1314 }
1315
1316 unzFile unzOpen64 (const void* path)
1317 {
1318 return unzOpenInternal (path, NULL, 1);
1319 }
1320
1321 /*
1322 Close a ZipFile opened with unzOpen.
1323 If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
1324 these files MUST be closed with unzCloseCurrentFile_ before call unzClose.
1325 return UNZ_OK if there is no problem. */
1326 int unzClose (unzFile file)
1327 {
1328 unz64_s* s;
1329 if (file == NULL)
1330 return UNZ_PARAMERROR;
1331 s = (unz64_s*)file;
1332
1333 if (s->pfile_in_zip_read != NULL)
1334 unzCloseCurrentFile_ (file);
1335
1336 ZCLOSE64 (s->z_filefunc, s->filestream);
1337 TRYFREE (s);
1338 return UNZ_OK;
1339 }
1340
1341 /*
1342 Write info about the ZipFile in the *pglobal_info structure.
1343 No preparation of the structure is needed
1344 return UNZ_OK if there is no problem. */
1345 int unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
1346 {
1347 unz64_s* s;
1348 if (file == NULL)
1349 return UNZ_PARAMERROR;
1350 s = (unz64_s*)file;
1351 *pglobal_info = s->gi;
1352 return UNZ_OK;
1353 }
1354
1355 int unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
1356 {
1357 unz64_s* s;
1358 if (file == NULL)
1359 return UNZ_PARAMERROR;
1360 s = (unz64_s*)file;
1361 /* to do : check if number_entry is not truncated */
1362 pglobal_info32->number_entry = (uLong)s->gi.number_entry;
1363 pglobal_info32->size_comment = s->gi.size_comment;
1364 return UNZ_OK;
1365 }
1366 /*
1367 Translate date/time from Dos format to tm_unz (readable more easilty)
1368 */
1369 void unz64local_DosDateToTmuDate_ (ZPOS64_T ulDosDate, tm_unz* ptm)
1370 {
1371 ZPOS64_T uDate;
1372 uDate = (ZPOS64_T)(ulDosDate >> 16);
1373 ptm->tm_mday = (uInt)(uDate & 0x1f);
1374 ptm->tm_mon = (uInt)((((uDate) & 0x1E0) / 0x20) - 1);
1375 ptm->tm_year = (uInt)(((uDate & 0x0FE00) / 0x0200) + 1980);
1376
1377 ptm->tm_hour = (uInt)((ulDosDate & 0xF800) / 0x800);
1378 ptm->tm_min = (uInt)((ulDosDate & 0x7E0) / 0x20);
1379 ptm->tm_sec = (uInt)(2 * (ulDosDate & 0x1f));
1380 }
1381
1382 /*
1383 Get Info about the current file in the zipfile, with internal only info
1384 */
1385 int unz64local_GetCurrentFileInfoInternal_ (unzFile file, unz_file_info64* pfile_info, unz_file_info64_internal* pfile_info_internal,
1386 char* szFileName, uLong fileNameBufferSize, void* extraField, uLong extraFieldBufferSize,
1387 char* szComment, uLong commentBufferSize)
1388 {
1389 unz64_s* s;
1390 unz_file_info64 file_info;
1391 unz_file_info64_internal file_info_internal;
1392 int err = UNZ_OK;
1393 uLong uMagic;
1394 long lSeek = 0;
1395
1396 if (file == NULL)
1397 return UNZ_PARAMERROR;
1398 s = (unz64_s*)file;
1399 if (ZSEEK64 (s->z_filefunc, s->filestream, s->pos_in_central_dir + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
1400 err = UNZ_ERRNO;
1401
1402 /* we check the magic */
1403 if (err == UNZ_OK) {
1404 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
1405 err = UNZ_ERRNO;
1406 else if (uMagic != 0x02014b50)
1407 err = UNZ_BADZIPFILE;
1408 }
1409
1410 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.version) != UNZ_OK)
1411 err = UNZ_ERRNO;
1412
1413 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK)
1414 err = UNZ_ERRNO;
1415
1416 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.flag) != UNZ_OK)
1417 err = UNZ_ERRNO;
1418
1419 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.compression_method) != UNZ_OK)
1420 err = UNZ_ERRNO;
1421
1422 if (unz64local_getLong (&s->z_filefunc, s->filestream, &file_info.dosDate) != UNZ_OK)
1423 err = UNZ_ERRNO;
1424
1425 unz64local_DosDateToTmuDate_ (file_info.dosDate, &file_info.tmu_date);
1426
1427 if (unz64local_getLong (&s->z_filefunc, s->filestream, &file_info.crc) != UNZ_OK)
1428 err = UNZ_ERRNO;
1429
1430 {
1431 uLong uL;
1432 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
1433 err = UNZ_ERRNO;
1434 file_info.compressed_size = uL;
1435 }
1436
1437 {
1438 uLong uL;
1439 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
1440 err = UNZ_ERRNO;
1441 file_info.uncompressed_size = uL;
1442 }
1443
1444 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK)
1445 err = UNZ_ERRNO;
1446
1447 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK)
1448 err = UNZ_ERRNO;
1449
1450 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK)
1451 err = UNZ_ERRNO;
1452
1453 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK)
1454 err = UNZ_ERRNO;
1455
1456 if (unz64local_getShort (&s->z_filefunc, s->filestream, &file_info.internal_fa) != UNZ_OK)
1457 err = UNZ_ERRNO;
1458
1459 if (unz64local_getLong (&s->z_filefunc, s->filestream, &file_info.external_fa) != UNZ_OK)
1460 err = UNZ_ERRNO;
1461
1462 // relative offset of local header
1463 {
1464 uLong uL;
1465 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
1466 err = UNZ_ERRNO;
1467 file_info_internal.offset_curfile = uL;
1468 }
1469
1470 lSeek += file_info.size_filename;
1471 if ((err == UNZ_OK) and (szFileName != NULL)) {
1472 uLong uSizeRead;
1473 if (file_info.size_filename < fileNameBufferSize) {
1474 *(szFileName + file_info.size_filename) = '\0';
1475 uSizeRead = file_info.size_filename;
1476 }
1477 else
1478 uSizeRead = fileNameBufferSize;
1479
1480 if ((file_info.size_filename > 0) and (fileNameBufferSize > 0))
1481 if (ZREAD64 (s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead)
1482 err = UNZ_ERRNO;
1483 lSeek -= uSizeRead;
1484 }
1485
1486 // Read extrafield
1487 if ((err == UNZ_OK) and (extraField != NULL)) {
1488 ZPOS64_T uSizeRead;
1489 if (file_info.size_file_extra < extraFieldBufferSize)
1490 uSizeRead = file_info.size_file_extra;
1491 else
1492 uSizeRead = extraFieldBufferSize;
1493
1494 if (lSeek != 0) {
1495 if (ZSEEK64 (s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)
1496 lSeek = 0;
1497 else
1498 err = UNZ_ERRNO;
1499 }
1500
1501 if ((file_info.size_file_extra > 0) and (extraFieldBufferSize > 0))
1502 if (ZREAD64 (s->z_filefunc, s->filestream, extraField, (uLong)uSizeRead) != uSizeRead)
1503 err = UNZ_ERRNO;
1504
1505 lSeek += file_info.size_file_extra - (uLong)uSizeRead;
1506 }
1507 else
1508 lSeek += file_info.size_file_extra;
1509
1510 if ((err == UNZ_OK) and (file_info.size_file_extra != 0)) {
1511 uLong acc = 0;
1512
1513 // since lSeek now points to after the extra field we need to move back
1514 lSeek -= file_info.size_file_extra;
1515
1516 if (lSeek != 0) {
1517 if (ZSEEK64 (s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)
1518 lSeek = 0;
1519 else
1520 err = UNZ_ERRNO;
1521 }
1522
1523 while (acc < file_info.size_file_extra) {
1524 uLong headerId;
1525 uLong dataSize;
1526
1527 if (unz64local_getShort (&s->z_filefunc, s->filestream, &headerId) != UNZ_OK)
1528 err = UNZ_ERRNO;
1529
1530 if (unz64local_getShort (&s->z_filefunc, s->filestream, &dataSize) != UNZ_OK)
1531 err = UNZ_ERRNO;
1532
1533 /* ZIP64 extra fields */
1534 if (headerId == 0x0001) {
1535 uLong uL;
1536
1537 if (file_info.uncompressed_size == MAXU32) {
1538 if (unz64local_getLong64 (&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK)
1539 err = UNZ_ERRNO;
1540 }
1541
1542 if (file_info.compressed_size == MAXU32) {
1543 if (unz64local_getLong64 (&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK)
1544 err = UNZ_ERRNO;
1545 }
1546
1547 if (file_info_internal.offset_curfile == MAXU32) {
1548 /* Relative Header offset */
1549 if (unz64local_getLong64 (&s->z_filefunc, s->filestream, &file_info_internal.offset_curfile) != UNZ_OK)
1550 err = UNZ_ERRNO;
1551 }
1552
1553 if (file_info.disk_num_start == MAXU32) {
1554 /* Disk Start Number */
1555 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uL) != UNZ_OK)
1556 err = UNZ_ERRNO;
1557 }
1558 }
1559 else {
1560 if (ZSEEK64 (s->z_filefunc, s->filestream, dataSize, ZLIB_FILEFUNC_SEEK_CUR) != 0)
1561 err = UNZ_ERRNO;
1562 }
1563
1564 acc += 2 + 2 + dataSize;
1565 }
1566 }
1567
1568 if ((err == UNZ_OK) and (szComment != NULL)) {
1569 uLong uSizeRead;
1570 if (file_info.size_file_comment < commentBufferSize) {
1571 *(szComment + file_info.size_file_comment) = '\0';
1572 uSizeRead = file_info.size_file_comment;
1573 }
1574 else
1575 uSizeRead = commentBufferSize;
1576
1577 if (lSeek != 0) {
1578 if (ZSEEK64 (s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)
1579 lSeek = 0;
1580 else
1581 err = UNZ_ERRNO;
1582 }
1583
1584 if ((file_info.size_file_comment > 0) and (commentBufferSize > 0))
1585 if (ZREAD64 (s->z_filefunc, s->filestream, szComment, uSizeRead) != uSizeRead)
1586 err = UNZ_ERRNO;
1587 lSeek += file_info.size_file_comment - uSizeRead;
1588 }
1589 else
1590 lSeek += file_info.size_file_comment;
1591
1592 if ((err == UNZ_OK) and (pfile_info != NULL))
1593 *pfile_info = file_info;
1594
1595 if ((err == UNZ_OK) and (pfile_info_internal != NULL))
1596 *pfile_info_internal = file_info_internal;
1597
1598 return err;
1599 }
1600
1601 /*
1602 Write info about the ZipFile in the *pglobal_info structure.
1603 No preparation of the structure is needed
1604 return UNZ_OK if there is no problem.
1605 */
1606 int unzGetCurrentFileInfo64 (unzFile file, unz_file_info64* pfile_info, char* szFileName, uLong fileNameBufferSize, void* extraField,
1607 uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize)
1608 {
1609 return unz64local_GetCurrentFileInfoInternal_ (file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField,
1610 extraFieldBufferSize, szComment, commentBufferSize);
1611 }
1612
1613 int unzGetCurrentFileInfo (unzFile file, unz_file_info* pfile_info, char* szFileName, uLong fileNameBufferSize, void* extraField,
1614 uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize)
1615 {
1616 int err;
1617 unz_file_info64 file_info64;
1618 err = unz64local_GetCurrentFileInfoInternal_ (file, &file_info64, NULL, szFileName, fileNameBufferSize, extraField,
1619 extraFieldBufferSize, szComment, commentBufferSize);
1620 if ((err == UNZ_OK) and (pfile_info != NULL)) {
1621 pfile_info->version = file_info64.version;
1622 pfile_info->version_needed = file_info64.version_needed;
1623 pfile_info->flag = file_info64.flag;
1624 pfile_info->compression_method = file_info64.compression_method;
1625 pfile_info->dosDate = file_info64.dosDate;
1626 pfile_info->crc = file_info64.crc;
1627
1628 pfile_info->size_filename = file_info64.size_filename;
1629 pfile_info->size_file_extra = file_info64.size_file_extra;
1630 pfile_info->size_file_comment = file_info64.size_file_comment;
1631
1632 pfile_info->disk_num_start = file_info64.disk_num_start;
1633 pfile_info->internal_fa = file_info64.internal_fa;
1634 pfile_info->external_fa = file_info64.external_fa;
1635
1636 pfile_info->tmu_date = file_info64.tmu_date,
1637
1638 pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1639 pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1640 }
1641 return err;
1642 }
1643
1644 /*
1645 Set the current file of the zipfile to the first file.
1646 return UNZ_OK if there is no problem
1647 */
1648 int unzGoToFirstFile (unzFile file)
1649 {
1650 int err = UNZ_OK;
1651 unz64_s* s;
1652 if (file == NULL)
1653 return UNZ_PARAMERROR;
1654 s = (unz64_s*)file;
1655 s->pos_in_central_dir = s->offset_central_dir;
1656 s->num_file = 0;
1657 err = unz64local_GetCurrentFileInfoInternal_ (file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
1658 s->current_file_ok = (err == UNZ_OK);
1659 return err;
1660 }
1661
1662 /*
1663 Set the current file of the zipfile to the next file.
1664 return UNZ_OK if there is no problem
1665 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1666 */
1667 int unzGoToNextFile_ (unzFile file)
1668 {
1669 unz64_s* s;
1670 int err;
1671
1672 if (file == NULL)
1673 return UNZ_PARAMERROR;
1674 s = (unz64_s*)file;
1675 if (!s->current_file_ok)
1676 return UNZ_END_OF_LIST_OF_FILE;
1677 if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
1678 if (s->num_file + 1 == s->gi.number_entry)
1679 return UNZ_END_OF_LIST_OF_FILE;
1680
1681 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;
1682 s->num_file++;
1683 err = unz64local_GetCurrentFileInfoInternal_ (file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
1684 s->current_file_ok = (err == UNZ_OK);
1685 return err;
1686 }
1687
1688 /*
1689 Try locate the file szFileName in the zipfile.
1690 For the iCaseSensitivity signification, see unzStringFileNameCompare
1691
1692 return value :
1693 UNZ_OK if the file is found. It becomes the current file.
1694 UNZ_END_OF_LIST_OF_FILE if the file is not found
1695 */
1696 int unzLocateFile_ (unzFile file, const char* szFileName, int iCaseSensitivity)
1697 {
1698 unz64_s* s;
1699 int err;
1700
1701 /* We remember the 'current' position in the file so that we can jump
1702 * back there if we fail.
1703 */
1704 unz_file_info64 cur_file_infoSaved;
1705 unz_file_info64_internal cur_file_info_internalSaved;
1706 ZPOS64_T num_fileSaved;
1707 ZPOS64_T pos_in_central_dirSaved;
1708
1709 if (file == NULL)
1710 return UNZ_PARAMERROR;
1711
1712 if (strlen (szFileName) >= UNZ_MAXFILENAMEINZIP)
1713 return UNZ_PARAMERROR;
1714
1715 s = (unz64_s*)file;
1716 if (!s->current_file_ok)
1717 return UNZ_END_OF_LIST_OF_FILE;
1718
1719 /* Save the current state */
1720 num_fileSaved = s->num_file;
1721 pos_in_central_dirSaved = s->pos_in_central_dir;
1722 cur_file_infoSaved = s->cur_file_info;
1723 cur_file_info_internalSaved = s->cur_file_info_internal;
1724
1725 err = unzGoToFirstFile (file);
1726
1727 while (err == UNZ_OK) {
1728 char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
1729 err = unzGetCurrentFileInfo64 (file, NULL, szCurrentFileName, sizeof (szCurrentFileName) - 1, NULL, 0, NULL, 0);
1730 if (err == UNZ_OK) {
1731 if (unzStringFileNameCompare (szCurrentFileName, szFileName, iCaseSensitivity) == 0)
1732 return UNZ_OK;
1733 err = unzGoToNextFile_ (file);
1734 }
1735 }
1736
1737 /* We failed, so restore the state of the 'current file' to where we
1738 * were.
1739 */
1740 s->num_file = num_fileSaved;
1741 s->pos_in_central_dir = pos_in_central_dirSaved;
1742 s->cur_file_info = cur_file_infoSaved;
1743 s->cur_file_info_internal = cur_file_info_internalSaved;
1744 return err;
1745 }
1746
1747 /*
1748 ///////////////////////////////////////////
1749 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1750 // I need random access
1751 //
1752 // Further optimization could be realized by adding an ability
1753 // to cache the directory in memory. The goal being a single
1754 // comprehensive file read to put the file I need in a memory.
1755 */
1756
1757 /*
1758 typedef struct unz_file_pos_s
1759 {
1760 ZPOS64_T pos_in_zip_directory; // offset in file
1761 ZPOS64_T num_of_file; // # of file
1762 } unz_file_pos;
1763 */
1764
1765 int unzGetFilePos64 (unzFile file, unz64_file_pos* file_pos)
1766 {
1767 unz64_s* s;
1768
1769 if (file == NULL or file_pos == NULL)
1770 return UNZ_PARAMERROR;
1771 s = (unz64_s*)file;
1772 if (!s->current_file_ok)
1773 return UNZ_END_OF_LIST_OF_FILE;
1774
1775 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
1776 file_pos->num_of_file = s->num_file;
1777
1778 return UNZ_OK;
1779 }
1780
1781 int unzGetFilePos (unzFile file, unz_file_pos* file_pos)
1782 {
1783 unz64_file_pos file_pos64;
1784 int err = unzGetFilePos64 (file, &file_pos64);
1785 if (err == UNZ_OK) {
1786 file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1787 file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1788 }
1789 return err;
1790 }
1791
1792 int unzGoToFilePos64 (unzFile file, const unz64_file_pos* file_pos)
1793 {
1794 unz64_s* s;
1795 int err;
1796
1797 if (file == NULL or file_pos == NULL)
1798 return UNZ_PARAMERROR;
1799 s = (unz64_s*)file;
1800
1801 /* jump to the right spot */
1802 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1803 s->num_file = file_pos->num_of_file;
1804
1805 /* set the current file */
1806 err = unz64local_GetCurrentFileInfoInternal_ (file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
1807 /* return results */
1808 s->current_file_ok = (err == UNZ_OK);
1809 return err;
1810 }
1811
1812 int unzGoToFilePos (unzFile file, unz_file_pos* file_pos)
1813 {
1814 unz64_file_pos file_pos64;
1815 if (file_pos == NULL)
1816 return UNZ_PARAMERROR;
1817
1818 file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1819 file_pos64.num_of_file = file_pos->num_of_file;
1820 return unzGoToFilePos64 (file, &file_pos64);
1821 }
1822
1823 /*
1824 // Unzip Helper Functions - should be here?
1825 ///////////////////////////////////////////
1826 */
1827
1828 /*
1829 Read the local header of the current zipfile
1830 Check the coherency of the local header and info in the end of central
1831 directory about this file
1832 store in *piSizeVar the size of extra info in local header
1833 (filename and size of extra field data)
1834 */
1835 int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, ZPOS64_T* poffset_local_extrafield, uInt* psize_local_extrafield)
1836 {
1837 uLong uMagic, uData, uFlags;
1838 uLong size_filename;
1839 uLong size_extra_field;
1840 int err = UNZ_OK;
1841
1842 *piSizeVar = 0;
1843 *poffset_local_extrafield = 0;
1844 *psize_local_extrafield = 0;
1845
1846 if (ZSEEK64 (s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
1847 return UNZ_ERRNO;
1848
1849 if (err == UNZ_OK) {
1850 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)
1851 err = UNZ_ERRNO;
1852 else if (uMagic != 0x04034b50)
1853 err = UNZ_BADZIPFILE;
1854 }
1855
1856 if (unz64local_getShort (&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
1857 err = UNZ_ERRNO;
1858 /*
1859 else if ((err==UNZ_OK) and (uData!=s->cur_file_info.wVersion))
1860 err=UNZ_BADZIPFILE;
1861 */
1862 if (unz64local_getShort (&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK)
1863 err = UNZ_ERRNO;
1864
1865 if (unz64local_getShort (&s->z_filefunc, s->filestream, &uData) != UNZ_OK)
1866 err = UNZ_ERRNO;
1867 else if ((err == UNZ_OK) and (uData != s->cur_file_info.compression_method))
1868 err = UNZ_BADZIPFILE;
1869
1870 if ((err == UNZ_OK) and (s->cur_file_info.compression_method != 0) &&
1871 /* #ifdef HAVE_BZIP2 */
1872 (s->cur_file_info.compression_method != Z_BZIP2ED) &&
1873 /* #endif */
1874 (s->cur_file_info.compression_method != Z_DEFLATED))
1875 err = UNZ_BADZIPFILE;
1876
1877 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* date/time */
1878 err = UNZ_ERRNO;
1879
1880 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* crc */
1881 err = UNZ_ERRNO;
1882 else if ((err == UNZ_OK) and (uData != s->cur_file_info.crc) and ((uFlags & 8) == 0))
1883 err = UNZ_BADZIPFILE;
1884
1885 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size compr */
1886 err = UNZ_ERRNO;
1887 else if (uData != 0xFFFFFFFF and (err == UNZ_OK) and (uData != s->cur_file_info.compressed_size) and ((uFlags & 8) == 0))
1888 err = UNZ_BADZIPFILE;
1889
1890 if (unz64local_getLong (&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size uncompr */
1891 err = UNZ_ERRNO;
1892 else if (uData != 0xFFFFFFFF and (err == UNZ_OK) and (uData != s->cur_file_info.uncompressed_size) and ((uFlags & 8) == 0))
1893 err = UNZ_BADZIPFILE;
1894
1895 if (unz64local_getShort (&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK)
1896 err = UNZ_ERRNO;
1897 else if ((err == UNZ_OK) and (size_filename != s->cur_file_info.size_filename))
1898 err = UNZ_BADZIPFILE;
1899
1900 *piSizeVar += (uInt)size_filename;
1901
1902 if (unz64local_getShort (&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK)
1903 err = UNZ_ERRNO;
1904 *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename;
1905 *psize_local_extrafield = (uInt)size_extra_field;
1906
1907 *piSizeVar += (uInt)size_extra_field;
1908
1909 return err;
1910 }
1911
1912 /*
1913 Open for reading data the current file in the zipfile.
1914 If there is no error and the file is opened, the return value is UNZ_OK.
1915 */
1916 int unzOpenCurrentFile3_ (unzFile file, int* method, int* level, int raw, const char* password)
1917 {
1918 int err = UNZ_OK;
1919 uInt iSizeVar;
1920 unz64_s* s;
1921 file_in_zip64_read_info_s* pfile_in_zip_read_info;
1922 ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
1923 uInt size_local_extrafield; /* size of the local extra field */
1924#ifndef NOUNCRYPT
1925 char source[12];
1926#else
1927 if (password != NULL)
1928 return UNZ_PARAMERROR;
1929#endif
1930
1931 if (file == NULL)
1932 return UNZ_PARAMERROR;
1933 s = (unz64_s*)file;
1934 if (!s->current_file_ok)
1935 return UNZ_PARAMERROR;
1936
1937 if (s->pfile_in_zip_read != NULL)
1938 unzCloseCurrentFile_ (file);
1939
1940 if (unz64local_CheckCurrentFileCoherencyHeader (s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)
1941 return UNZ_BADZIPFILE;
1942
1943 pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC (sizeof (file_in_zip64_read_info_s));
1944 if (pfile_in_zip_read_info == NULL)
1945 return UNZ_INTERNALERROR;
1946
1947 pfile_in_zip_read_info->read_buffer = (char*)ALLOC (UNZ_BUFSIZE);
1948 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1949 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1950 pfile_in_zip_read_info->pos_local_extrafield = 0;
1951 pfile_in_zip_read_info->raw = raw;
1952
1953 if (pfile_in_zip_read_info->read_buffer == NULL) {
1954 TRYFREE (pfile_in_zip_read_info);
1955 return UNZ_INTERNALERROR;
1956 }
1957
1958 pfile_in_zip_read_info->stream_initialised = 0;
1959
1960 if (method != NULL)
1961 *method = (int)s->cur_file_info.compression_method;
1962
1963 if (level != NULL) {
1964 *level = 6;
1965 switch (s->cur_file_info.flag & 0x06) {
1966 case 6:
1967 *level = 1;
1968 break;
1969 case 4:
1970 *level = 2;
1971 break;
1972 case 2:
1973 *level = 9;
1974 break;
1975 }
1976 }
1977
1978 if ((s->cur_file_info.compression_method != 0) &&
1979 /* #ifdef HAVE_BZIP2 */
1980 (s->cur_file_info.compression_method != Z_BZIP2ED) &&
1981 /* #endif */
1982 (s->cur_file_info.compression_method != Z_DEFLATED))
1983
1984 err = UNZ_BADZIPFILE;
1985
1986 pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc;
1987 pfile_in_zip_read_info->crc32 = 0;
1988 pfile_in_zip_read_info->total_out_64 = 0;
1989 pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1990 pfile_in_zip_read_info->filestream = s->filestream;
1991 pfile_in_zip_read_info->z_filefunc = s->z_filefunc;
1992 pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile;
1993
1994 pfile_in_zip_read_info->stream.total_out = 0;
1995
1996 if ((s->cur_file_info.compression_method == Z_BZIP2ED) and (!raw)) {
1997#ifdef HAVE_BZIP2
1998 pfile_in_zip_read_info->bstream.bzalloc = (void* (*)(void*, int, int))0;
1999 pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
2000 pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
2001 pfile_in_zip_read_info->bstream.state = (voidpf)0;
2002
2003 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
2004 pfile_in_zip_read_info->stream.zfree = (free_func)0;
2005 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
2006 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
2007 pfile_in_zip_read_info->stream.avail_in = 0;
2008
2009 err = BZ2_bzDecompressInit (&pfile_in_zip_read_info->bstream, 0, 0);
2010 if (err == Z_OK)
2011 pfile_in_zip_read_info->stream_initialised = Z_BZIP2ED;
2012 else {
2013 TRYFREE (pfile_in_zip_read_info);
2014 return err;
2015 }
2016#else
2017 pfile_in_zip_read_info->raw = 1;
2018#endif
2019 }
2020 else if ((s->cur_file_info.compression_method == Z_DEFLATED) and (!raw)) {
2021 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
2022 pfile_in_zip_read_info->stream.zfree = (free_func)0;
2023 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
2024 pfile_in_zip_read_info->stream.next_in = 0;
2025 pfile_in_zip_read_info->stream.avail_in = 0;
2026
2027 err = inflateInit2 (&pfile_in_zip_read_info->stream, -MAX_WBITS);
2028 if (err == Z_OK)
2029 pfile_in_zip_read_info->stream_initialised = Z_DEFLATED;
2030 else {
2031 TRYFREE (pfile_in_zip_read_info);
2032 return err;
2033 }
2034 /* windowBits is passed < 0 to tell that there is no zlib header.
2035 * Note that in this case inflate *requires* an extra "dummy" byte
2036 * after the compressed stream in order to complete decompression and
2037 * return Z_STREAM_END.
2038 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
2039 * size of both compressed and uncompressed data
2040 */
2041 }
2042 pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size;
2043 pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size;
2044
2045 pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar;
2046
2047 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
2048
2049 s->pfile_in_zip_read = pfile_in_zip_read_info;
2050 s->encrypted = 0;
2051
2052#ifndef NOUNCRYPT
2053 if (password != NULL) {
2054 int i;
2055 s->pcrc_32_tab = get_crc_table ();
2056 init_keys (password, s->keys, s->pcrc_32_tab);
2057 if (ZSEEK64 (s->z_filefunc, s->filestream, s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile, SEEK_SET) != 0)
2058 return UNZ_INTERNALERROR;
2059 if (ZREAD64 (s->z_filefunc, s->filestream, source, 12) < 12)
2060 return UNZ_INTERNALERROR;
2061
2062 for (i = 0; i < 12; ++i)
2063 zdecode (s->keys, s->pcrc_32_tab, source[i]);
2064
2065 s->pfile_in_zip_read->pos_in_zipfile += 12;
2066 s->encrypted = 1;
2067 }
2068#endif
2069
2070 return UNZ_OK;
2071 }
2072
2073 int unzOpenCurrentFile (unzFile file)
2074 {
2075 return unzOpenCurrentFile3_ (file, NULL, NULL, 0, NULL);
2076 }
2077
2078 int unzOpenCurrentFilePassword (unzFile file, const char* password)
2079 {
2080 return unzOpenCurrentFile3_ (file, NULL, NULL, 0, password);
2081 }
2082
2083 int unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
2084 {
2085 return unzOpenCurrentFile3_ (file, method, level, raw, NULL);
2086 }
2087
2088 /** Addition for GDAL : START */
2089
2090 ZPOS64_T unzGetCurrentFileZStreamPos64 (unzFile file)
2091 {
2092 unz64_s* s;
2093 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2094 s = (unz64_s*)file;
2095 if (file == NULL)
2096 return 0; //UNZ_PARAMERROR;
2097 pfile_in_zip_read_info = s->pfile_in_zip_read;
2098 if (pfile_in_zip_read_info == NULL)
2099 return 0; //UNZ_PARAMERROR;
2100 return pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile;
2101 }
2102
2103 /** Addition for GDAL : END */
2104
2105 /*
2106 Read bytes from the current file.
2107 buf contain buffer where data must be copied
2108 len the size of buf.
2109
2110 return the number of byte copied if somes bytes are copied
2111 return 0 if the end of file was reached
2112 return <0 with error code if there is an error
2113 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
2114 */
2115 int unzReadCurrentFile_ (unzFile file, voidp buf, unsigned len)
2116 {
2117 int err = UNZ_OK;
2118 uInt iRead = 0;
2119 unz64_s* s;
2120 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2121 if (file == NULL)
2122 return UNZ_PARAMERROR;
2123 s = (unz64_s*)file;
2124 pfile_in_zip_read_info = s->pfile_in_zip_read;
2125
2126 if (pfile_in_zip_read_info == NULL)
2127 return UNZ_PARAMERROR;
2128
2129 if (pfile_in_zip_read_info->read_buffer == NULL)
2130 return UNZ_END_OF_LIST_OF_FILE;
2131 if (len == 0)
2132 return 0;
2133
2134 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
2135
2136 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
2137
2138 if ((len > pfile_in_zip_read_info->rest_read_uncompressed) && (!(pfile_in_zip_read_info->raw)))
2139 pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
2140
2141 if ((len > pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw))
2142 pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in;
2143
2144 while (pfile_in_zip_read_info->stream.avail_out > 0) {
2145 if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed > 0)) {
2146 uInt uReadThis = UNZ_BUFSIZE;
2147 if (pfile_in_zip_read_info->rest_read_compressed < uReadThis)
2148 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
2149 if (uReadThis == 0)
2150 return UNZ_EOF;
2151 if (ZSEEK64 (pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,
2152 pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
2153 return UNZ_ERRNO;
2154 if (ZREAD64 (pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis) != uReadThis)
2155 return UNZ_ERRNO;
2156
2157#ifndef NOUNCRYPT
2158 if (s->encrypted) {
2159 uInt i;
2160 for (i = 0; i < uReadThis; i++)
2161 pfile_in_zip_read_info->read_buffer[i] = zdecode (s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]);
2162 }
2163#endif
2164
2165 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
2166
2167 pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
2168
2169 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer;
2170 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
2171 }
2172
2173 if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) {
2174 uInt uDoCopy, i;
2175
2176 if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0))
2177 return (iRead == 0) ? UNZ_EOF : iRead;
2178
2179 if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in)
2180 uDoCopy = pfile_in_zip_read_info->stream.avail_out;
2181 else
2182 uDoCopy = pfile_in_zip_read_info->stream.avail_in;
2183
2184 for (i = 0; i < uDoCopy; i++)
2185 *(pfile_in_zip_read_info->stream.next_out + i) = *(pfile_in_zip_read_info->stream.next_in + i);
2186
2187 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
2188
2189 pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy);
2190 pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
2191 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
2192 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
2193 pfile_in_zip_read_info->stream.next_out += uDoCopy;
2194 pfile_in_zip_read_info->stream.next_in += uDoCopy;
2195 pfile_in_zip_read_info->stream.total_out += uDoCopy;
2196 iRead += uDoCopy;
2197 }
2198 else if (pfile_in_zip_read_info->compression_method == Z_BZIP2ED) {
2199#ifdef HAVE_BZIP2
2200 uLong uTotalOutBefore, uTotalOutAfter;
2201 const Bytef* bufBefore;
2202 uLong uOutThis;
2203
2204 pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
2205 pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
2206 pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
2207 pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
2208 pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
2209 pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
2210 pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
2211 pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
2212
2213 uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
2214 bufBefore = (const Bytef*)pfile_in_zip_read_info->bstream.next_out;
2215
2216 err = BZ2_bzDecompress (&pfile_in_zip_read_info->bstream);
2217
2218 uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
2219 uOutThis = uTotalOutAfter - uTotalOutBefore;
2220
2221 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
2222
2223 pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32, bufBefore, (uInt)(uOutThis));
2224 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
2225 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
2226
2227 pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
2228 pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
2229 pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
2230 pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
2231 pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
2232 pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
2233
2234 if (err == BZ_STREAM_END)
2235 return (iRead == 0) ? UNZ_EOF : iRead;
2236 if (err != BZ_OK)
2237 break;
2238#endif
2239 } // end Z_BZIP2ED
2240 else {
2241 ZPOS64_T uTotalOutBefore, uTotalOutAfter;
2242 const Bytef* bufBefore;
2243 ZPOS64_T uOutThis;
2244 int flush = Z_SYNC_FLUSH;
2245
2246 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
2247 bufBefore = pfile_in_zip_read_info->stream.next_out;
2248
2249 /*
2250 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
2251 pfile_in_zip_read_info->stream.avail_out) &&
2252 (pfile_in_zip_read_info->rest_read_compressed == 0))
2253 flush = Z_FINISH;
2254 */
2255 err = inflate (&pfile_in_zip_read_info->stream, flush);
2256
2257 if ((err >= 0) and (pfile_in_zip_read_info->stream.msg != NULL))
2258 err = Z_DATA_ERROR;
2259
2260 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
2261 uOutThis = uTotalOutAfter - uTotalOutBefore;
2262
2263 pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
2264
2265 pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32, bufBefore, (uInt)(uOutThis));
2266
2267 pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
2268
2269 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
2270
2271 if (err == Z_STREAM_END)
2272 return (iRead == 0) ? UNZ_EOF : iRead;
2273 if (err != Z_OK)
2274 break;
2275 }
2276 }
2277
2278 if (err == Z_OK)
2279 return iRead;
2280 return err;
2281 }
2282
2283 /*
2284 Give the current position in uncompressed data
2285 */
2286 z_off_t unztell (unzFile file)
2287 {
2288 unz64_s* s;
2289 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2290 if (file == NULL)
2291 return UNZ_PARAMERROR;
2292 s = (unz64_s*)file;
2293 pfile_in_zip_read_info = s->pfile_in_zip_read;
2294
2295 if (pfile_in_zip_read_info == NULL)
2296 return UNZ_PARAMERROR;
2297
2298 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
2299 }
2300
2301 ZPOS64_T unztell64 (unzFile file)
2302 {
2303
2304 unz64_s* s;
2305 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2306 if (file == NULL)
2307 return (ZPOS64_T)-1;
2308 s = (unz64_s*)file;
2309 pfile_in_zip_read_info = s->pfile_in_zip_read;
2310
2311 if (pfile_in_zip_read_info == NULL)
2312 return (ZPOS64_T)-1;
2313
2314 return pfile_in_zip_read_info->total_out_64;
2315 }
2316
2317 /*
2318 return 1 if the end of file was reached, 0 elsewhere
2319 */
2320 int unzeof (unzFile file)
2321 {
2322 unz64_s* s;
2323 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2324 if (file == NULL)
2325 return UNZ_PARAMERROR;
2326 s = (unz64_s*)file;
2327 pfile_in_zip_read_info = s->pfile_in_zip_read;
2328
2329 if (pfile_in_zip_read_info == NULL)
2330 return UNZ_PARAMERROR;
2331
2332 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
2333 return 1;
2334 else
2335 return 0;
2336 }
2337
2338 /*
2339 Read extra field from the current file (opened by unzOpenCurrentFile)
2340 This is the local-header version of the extra field (sometimes, there is
2341 more info in the local-header version than in the central-header)
2342
2343 if buf==NULL, it return the size of the local extra field that can be read
2344
2345 if buf!=NULL, len is the size of the buffer, the extra header is copied in
2346 buf.
2347 the return value is the number of bytes copied in buf, or (if <0)
2348 the error code
2349 */
2350 int unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
2351 {
2352 unz64_s* s;
2353 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2354 uInt read_now;
2355 ZPOS64_T size_to_read;
2356
2357 if (file == NULL)
2358 return UNZ_PARAMERROR;
2359 s = (unz64_s*)file;
2360 pfile_in_zip_read_info = s->pfile_in_zip_read;
2361
2362 if (pfile_in_zip_read_info == NULL)
2363 return UNZ_PARAMERROR;
2364
2365 size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield);
2366
2367 if (buf == NULL)
2368 return (int)size_to_read;
2369
2370 if (len > size_to_read)
2371 read_now = (uInt)size_to_read;
2372 else
2373 read_now = (uInt)len;
2374
2375 if (read_now == 0)
2376 return 0;
2377
2378 if (ZSEEK64 (pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,
2379 pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, ZLIB_FILEFUNC_SEEK_SET) != 0)
2380 return UNZ_ERRNO;
2381
2382 if (ZREAD64 (pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf, read_now) != read_now)
2383 return UNZ_ERRNO;
2384
2385 return (int)read_now;
2386 }
2387
2388 /*
2389 Close the file in zip opened with unzOpenCurrentFile
2390 Return UNZ_CRCERROR if all the file was read but the CRC is not good
2391 */
2392 int unzCloseCurrentFile_ (unzFile file)
2393 {
2394 int err = UNZ_OK;
2395
2396 unz64_s* s;
2397 file_in_zip64_read_info_s* pfile_in_zip_read_info;
2398 if (file == NULL)
2399 return UNZ_PARAMERROR;
2400 s = (unz64_s*)file;
2401 pfile_in_zip_read_info = s->pfile_in_zip_read;
2402
2403 if (pfile_in_zip_read_info == NULL)
2404 return UNZ_PARAMERROR;
2405
2406 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) {
2407 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2408 err = UNZ_CRCERROR;
2409 }
2410
2411 TRYFREE (pfile_in_zip_read_info->read_buffer);
2412 pfile_in_zip_read_info->read_buffer = NULL;
2413 if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2414 inflateEnd (&pfile_in_zip_read_info->stream);
2415#ifdef HAVE_BZIP2
2416 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2417 BZ2_bzDecompressEnd (&pfile_in_zip_read_info->bstream);
2418#endif
2419
2420 pfile_in_zip_read_info->stream_initialised = 0;
2421 TRYFREE (pfile_in_zip_read_info);
2422
2423 s->pfile_in_zip_read = NULL;
2424
2425 return err;
2426 }
2427
2428 /*
2429 Get the global comment string of the ZipFile, in the szComment buffer.
2430 uSizeBuf is the size of the szComment buffer.
2431 return the number of byte copied or an error code <0
2432 */
2433 int unzGetGlobalComment (unzFile file, char* szComment, uLong uSizeBuf)
2434 {
2435 unz64_s* s;
2436 uLong uReadThis;
2437 if (file == NULL)
2438 return (int)UNZ_PARAMERROR;
2439 s = (unz64_s*)file;
2440
2441 uReadThis = uSizeBuf;
2442 if (uReadThis > s->gi.size_comment)
2443 uReadThis = s->gi.size_comment;
2444
2445 if (ZSEEK64 (s->z_filefunc, s->filestream, s->central_pos + 22, ZLIB_FILEFUNC_SEEK_SET) != 0)
2446 return UNZ_ERRNO;
2447
2448 if (uReadThis > 0) {
2449 *szComment = '\0';
2450 if (ZREAD64 (s->z_filefunc, s->filestream, szComment, uReadThis) != uReadThis)
2451 return UNZ_ERRNO;
2452 }
2453
2454 if ((szComment != NULL) and (uSizeBuf > s->gi.size_comment))
2455 *(szComment + s->gi.size_comment) = '\0';
2456 return (int)uReadThis;
2457 }
2458
2459 /* Additions by RX '2004 */
2460 ZPOS64_T unzGetOffset64 (unzFile file)
2461 {
2462 unz64_s* s;
2463
2464 if (file == NULL)
2465 return 0; //UNZ_PARAMERROR;
2466 s = (unz64_s*)file;
2467 if (!s->current_file_ok)
2468 return 0;
2469 if (s->gi.number_entry != 0 and s->gi.number_entry != 0xffff)
2470 if (s->num_file == s->gi.number_entry)
2471 return 0;
2472 return s->pos_in_central_dir;
2473 }
2474
2475 uLong unzGetOffset (unzFile file)
2476 {
2477 ZPOS64_T offset64;
2478
2479 if (file == NULL)
2480 return 0; //UNZ_PARAMERROR;
2481 offset64 = unzGetOffset64 (file);
2482 return (uLong)offset64;
2483 }
2484
2485 int unzSetOffset64 (unzFile file, ZPOS64_T pos)
2486 {
2487 unz64_s* s;
2488 int err;
2489
2490 if (file == NULL)
2491 return UNZ_PARAMERROR;
2492 s = (unz64_s*)file;
2493
2494 s->pos_in_central_dir = pos;
2495 s->num_file = s->gi.number_entry; /* hack */
2496 err = unz64local_GetCurrentFileInfoInternal_ (file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);
2497 s->current_file_ok = (err == UNZ_OK);
2498 return err;
2499 }
2500
2501 int unzSetOffset (unzFile file, uLong pos)
2502 {
2503 return unzSetOffset64 (file, pos);
2504 }
2505}
2506///////////////////////////////// END OF unzip.c ////////////////////
2507#endif
2508
2509#if qStroika_HasComponent_zlib
2510class Zip::Reader::Rep_ : public Reader::_IRep {
2511private:
2512 struct MyISeekInStream : zlib_filefunc64_def {
2514#if qDebug
2515 bool fOpened_{false};
2516#endif
2517 MyISeekInStream (const Streams::InputStream::Ptr<byte>& in)
2518 : fInStream_{in}
2519 {
2520 this->zopen64_file = [] (voidpf opaqueStream, const void* /*filename*/, int /*mode*/) -> voidpf {
2521 MyISeekInStream* myThis = reinterpret_cast<MyISeekInStream*> (opaqueStream);
2522#if qDebug
2523 Assert (not myThis->fOpened_);
2524 myThis->fOpened_ = true;
2525#endif
2526 return myThis;
2527 };
2528 this->zread_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream, void* buf, uLong size) -> uLong {
2529 Require (opaqueStream == stream); // our use is one stream per zlib_filefunc64_def object
2530 MyISeekInStream* myThis = reinterpret_cast<MyISeekInStream*> (opaqueStream);
2531#if qDebug
2532 Assert (myThis->fOpened_);
2533#endif
2534 size_t sz = myThis->fInStream_.ReadBlocking (span{reinterpret_cast<byte*> (buf), size}).size ();
2535 Assert (sz <= size);
2536 return static_cast<uLong> (sz);
2537 };
2538 this->zwrite_file = [] (voidpf /*opaque*/, voidpf /*stream*/, const void* /*buf*/, uLong /*size*/) -> uLong {
2539 RequireNotReached (); // read only zip
2540 return static_cast<uLong> (UNZ_PARAMERROR);
2541 };
2542 this->ztell64_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream) -> ZPOS64_T {
2543 Require (opaqueStream == stream); // our use is one stream per zlib_filefunc64_def object
2544 MyISeekInStream* myThis = reinterpret_cast<MyISeekInStream*> (opaqueStream);
2545#if qDebug
2546 Assert (myThis->fOpened_);
2547#endif
2548 return myThis->fInStream_.GetOffset ();
2549 };
2550 this->zseek64_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream, ZPOS64_T offset, int origin) -> long {
2551 Require (opaqueStream == stream); // our use is one stream per zlib_filefunc64_def object
2552 MyISeekInStream* myThis = reinterpret_cast<MyISeekInStream*> (opaqueStream);
2553#if qDebug
2554 Assert (myThis->fOpened_);
2555#endif
2556 switch (origin) {
2557 case ZLIB_FILEFUNC_SEEK_SET:
2558 myThis->fInStream_.Seek (offset);
2559 break;
2560 case ZLIB_FILEFUNC_SEEK_CUR:
2561 myThis->fInStream_.Seek (Streams::eFromCurrent, offset);
2562 break;
2563 case ZLIB_FILEFUNC_SEEK_END:
2564 myThis->fInStream_.Seek (Streams::eFromEnd, offset);
2565 break;
2566 default:
2568 return UNZ_PARAMERROR;
2569 }
2570 return UNZ_OK;
2571 };
2572 this->zclose_file = [] ([[maybe_unused]] voidpf opaqueStream, [[maybe_unused]] voidpf stream) -> int {
2573#if qDebug
2574 Require (opaqueStream == stream); // our use is one stream per zlib_filefunc64_def object
2575 MyISeekInStream* myThis = reinterpret_cast<MyISeekInStream*> (opaqueStream);
2576 Assert (myThis->fOpened_);
2577 myThis->fOpened_ = false;
2578#endif
2579 return UNZ_OK;
2580 };
2581 this->zerror_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream) -> int {
2582 Require (opaqueStream == stream); // our use is one stream per zlib_filefunc64_def object
2583 [[maybe_unused]] MyISeekInStream* myThis = reinterpret_cast<MyISeekInStream*> (opaqueStream);
2584#if qDebug
2585 Assert (myThis->fOpened_);
2586#endif
2587 return UNZ_OK; // @todo - see what this means?
2588 };
2589 this->opaque = this;
2590 }
2591 ~MyISeekInStream ()
2592 {
2593#if qDebug
2594 Assert (not fOpened_);
2595#endif
2596 }
2597 };
2598 MyISeekInStream fInSeekStream_;
2599 unzFile fZipFile_;
2600
2601public:
2602 Rep_ (const Streams::InputStream::Ptr<byte>& in)
2603 : fInSeekStream_ (in)
2604 , fZipFile_ (unzOpen2_64 ("", &fInSeekStream_))
2605 {
2606 if (fZipFile_ == nullptr) [[unlikely]] {
2607 static const Execution::RuntimeErrorException kException_{"failed to open zipfile"sv};
2608 Execution::Throw (kException_);
2609 }
2610 }
2611 ~Rep_ ()
2612 {
2613 AssertNotNull (fZipFile_);
2614 unzClose (fZipFile_);
2615 }
2616 virtual Set<String> GetContainedFiles () const override
2617 {
2618 Set<String> result;
2619 unz_global_info64 gi;
2620 int err = unzGetGlobalInfo64 (fZipFile_, &gi);
2621 if (err != UNZ_OK) [[unlikely]] {
2622 using namespace Characters;
2623 Execution::Throw (Execution::RuntimeErrorException{Format ("error {} with zipfile in unzGetGlobalInfo"_f, err)});
2624 }
2625 for (size_t i = 0; i < gi.number_entry; i++) {
2626 char filename_inzip[10 * 1024];
2627 unz_file_info64 file_info;
2628 //uLong ratio = 0;
2629 //const char* string_method;
2630 //char charCrypt = ' ';
2631 err = ::unzGetCurrentFileInfo64 (fZipFile_, &file_info, filename_inzip, sizeof (filename_inzip), NULL, 0, NULL, 0);
2632 if (err != UNZ_OK) [[unlikely]] {
2633 using namespace Characters;
2634 Execution::Throw (Execution::RuntimeErrorException{Format ("error {} with zipfile in unzGetCurrentFileInfo64"_f, err)});
2635 break;
2636 }
2637 if ((i + 1) < gi.number_entry) {
2638 err = ::unzGoToNextFile_ (fZipFile_);
2639 if (err != UNZ_OK) [[unlikely]] {
2640 using namespace Characters;
2641 Execution::Throw (Execution::RuntimeErrorException{"error {} with zipfile in unzGoToNextFile"_f(err)});
2642 break;
2643 }
2644 }
2645 //tmphac
2646 if (filename_inzip[::strlen (filename_inzip) - 1] == '/') {
2647 continue; // only list files - not directories for now
2648 }
2649 result.Add (String{filename_inzip}); // not sure about codepage for conversion - for now assume ascii?
2650 }
2651#if 0
2652 // Keep temporarily, because we will want a traversal variant that captures this extra info
2653 uLong i;
2654 unz_global_info64 gi;
2655 int err;
2656
2657 err = unzGetGlobalInfo64(uf, &gi);
2658 if (err != UNZ_OK)
2659 printf("error %d with zipfile in unzGetGlobalInfo \n", err);
2660 printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
2661 printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
2662 for (i = 0; i < gi.number_entry; ++i) {
2663 char filename_inzip[256];
2664 unz_file_info64 file_info;
2665 uLong ratio = 0;
2666 const char* string_method;
2667 char charCrypt = ' ';
2668 err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
2669 if (err != UNZ_OK) {
2670 printf("error %d with zipfile in unzGetCurrentFileInfo\n", err);
2671 break;
2672 }
2673 if (file_info.uncompressed_size > 0)
2674 ratio = (uLong)((file_info.compressed_size * 100) / file_info.uncompressed_size);
2675
2676 /* display a '*' if the file is crypted */
2677 if ((file_info.flag & 1) != 0)
2678 charCrypt = '*';
2679
2680 if (file_info.compression_method == 0)
2681 string_method = "Stored";
2682 else if (file_info.compression_method == Z_DEFLATED) {
2683 uInt iLevel = (uInt)((file_info.flag & 0x6) / 2);
2684 if (iLevel == 0)
2685 string_method = "Defl:N";
2686 else if (iLevel == 1)
2687 string_method = "Defl:X";
2688 else if ((iLevel == 2) or (iLevel == 3))
2689 string_method = "Defl:F"; /* 2:fast , 3 : extra fast*/
2690 }
2691 else if (file_info.compression_method == Z_BZIP2ED) {
2692 string_method = "BZip2 ";
2693 }
2694 else
2695 string_method = "Unkn. ";
2696
2697 Display64BitsSize(file_info.uncompressed_size, 7);
2698 printf(" %6s%c", string_method, charCrypt);
2699 Display64BitsSize(file_info.compressed_size, 7);
2700 printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
2701 ratio,
2702 (uLong)file_info.tmu_date.tm_mon + 1,
2703 (uLong)file_info.tmu_date.tm_mday,
2704 (uLong)file_info.tmu_date.tm_year % 100,
2705 (uLong)file_info.tmu_date.tm_hour, (uLong)file_info.tmu_date.tm_min,
2706 (uLong)file_info.crc, filename_inzip);
2707 if ((i + 1) < gi.number_entry) {
2708 err = unzGoToNextFile_ (uf);
2709 if (err != UNZ_OK) {
2710 printf("error %d with zipfile in unzGoToNextFile\n", err);
2711 break;
2712 }
2713 }
2714 }
2715
2716 for (unsigned int i = 0; i < fDB_.NumFiles; i++) {
2717 if (not SzArEx_IsDir (&fDB_, i)) {
2718 size_t nameLen = ::SzArEx_GetFileNameUtf16 (&fDB_, i, nullptr);
2719 if (nameLen < 1) {
2720 break;
2721 }
2722 Memory::StackBuffer<char16_t> fileName {Memory::eUninitiialized, nameLen};
2723 size_t z = ::SzArEx_GetFileNameUtf16 (&fDB_, i, reinterpret_cast<UInt16*> (&fileName[0]));
2724 result.Add (String{&fileName[0]});
2725 }
2726 }
2727#endif
2728 return result;
2729 }
2730 virtual Memory::BLOB GetData (const String& fileName) const override
2731 {
2732 if (unzLocateFile_ (fZipFile_, fileName.AsNarrowSDKString ().c_str (), 1) != UNZ_OK) [[unlikely]] {
2733 using namespace Characters;
2734 Execution::Throw (Execution::RuntimeErrorException{Format ("File '{}' not found"_f, fileName)});
2735 }
2736 const char* password = nullptr;
2737 int err = unzOpenCurrentFilePassword (fZipFile_, password);
2738 [[maybe_unused]] auto&& cleanup = Execution::Finally ([this] () noexcept { unzCloseCurrentFile_ (fZipFile_); });
2739 Streams::MemoryStream::Ptr<byte> tmpBuf = Streams::MemoryStream::New<byte> ();
2740 do {
2741 byte buf[10 * 1024];
2742 err = unzReadCurrentFile_ (fZipFile_, buf, static_cast<unsigned int> (Memory::NEltsOf (buf)));
2743 if (err < 0) [[unlikely]] {
2744 using namespace Characters;
2745 Execution::Throw (Execution::RuntimeErrorException{Format (L"File '{}' error {} extracting"_f, fileName, err)});
2746 }
2747 else if (err > 0) {
2748 Assert (static_cast<size_t> (err) <= Memory::NEltsOf (buf));
2749 tmpBuf.Write (span{buf, static_cast<size_t> (err)});
2750 }
2751 } while (err > 0);
2752 return tmpBuf.As<Memory::BLOB> ();
2753 }
2754};
2755
2756Zip::Reader::Reader (const Streams::InputStream::Ptr<byte>& in)
2757 : DataExchange::Archive::Reader{make_shared<Rep_> (in)}
2758{
2759}
2760#endif
#define AssertNotNull(p)
Definition Assertions.h:333
#define RequireNotReached()
Definition Assertions.h:385
#define AssertNotReached()
Definition Assertions.h:355
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual string AsNarrowSDKString() const
Definition String.inl:830
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition Set.h:105
nonvirtual void Add(ArgByValueType< value_type > item)
Definition Set.inl:138
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
InputStream<>::Ptr is Smart pointer (with abstract Rep) class defining the interface to reading from ...