| 1 | 
           cycrow | 
           1 | 
           #include <windows.h>
  | 
        
        
            | 
            | 
           2 | 
           #include <stdio.h>
  | 
        
        
            | 
            | 
           3 | 
           #include <tchar.h>
  | 
        
        
            | 
            | 
           4 | 
           #include "zip.h"
  | 
        
        
            | 
            | 
           5 | 
              | 
        
        
            | 
            | 
           6 | 
              | 
        
        
            | 
            | 
           7 | 
           // THIS FILE is almost entirely based upon code by info-zip.
  | 
        
        
            | 
            | 
           8 | 
           // It has been modified by Lucian Wischik. The modifications
  | 
        
        
            | 
            | 
           9 | 
           // were a complete rewrite of the bit of code that generates the
  | 
        
        
            | 
            | 
           10 | 
           // layout of the zipfile, and support for zipping to/from memory
  | 
        
        
            | 
            | 
           11 | 
           // or handles or pipes or pagefile or diskfiles, encryption, unicode.
  | 
        
        
            | 
            | 
           12 | 
           // The original code may be found at http://www.info-zip.org
  | 
        
        
            | 
            | 
           13 | 
           // The original copyright text follows.
  | 
        
        
            | 
            | 
           14 | 
           //
  | 
        
        
            | 
            | 
           15 | 
           //
  | 
        
        
            | 
            | 
           16 | 
           //
  | 
        
        
            | 
            | 
           17 | 
           // This is version 1999-Oct-05 of the Info-ZIP copyright and license.
  | 
        
        
            | 
            | 
           18 | 
           // The definitive version of this document should be available at
  | 
        
        
            | 
            | 
           19 | 
           // ftp://ftp.cdrom.com/pub/infozip/license.html indefinitely.
  | 
        
        
            | 
            | 
           20 | 
           //
  | 
        
        
            | 
            | 
           21 | 
           // Copyright (c) 1990-1999 Info-ZIP.  All rights reserved.
  | 
        
        
            | 
            | 
           22 | 
           //
  | 
        
        
            | 
            | 
           23 | 
           // For the purposes of this copyright and license, "Info-ZIP" is defined as
  | 
        
        
            | 
            | 
           24 | 
           // the following set of individuals:
  | 
        
        
            | 
            | 
           25 | 
           //
  | 
        
        
            | 
            | 
           26 | 
           //   Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
  | 
        
        
            | 
            | 
           27 | 
           //   Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase,
  | 
        
        
            | 
            | 
           28 | 
           //   Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, David Kirschbaum,
  | 
        
        
            | 
            | 
           29 | 
           //   Johnny Lee, Onno van der Linden, Igor Mandrichenko, Steve P. Miller,
  | 
        
        
            | 
            | 
           30 | 
           //   Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, Kai Uwe Rommel,
  | 
        
        
            | 
            | 
           31 | 
           //   Steve Salisbury, Dave Smith, Christian Spieler, Antoine Verheijen,
  | 
        
        
            | 
            | 
           32 | 
           //   Paul von Behren, Rich Wales, Mike White
  | 
        
        
            | 
            | 
           33 | 
           //
  | 
        
        
            | 
            | 
           34 | 
           // This software is provided "as is," without warranty of any kind, express
  | 
        
        
            | 
            | 
           35 | 
           // or implied.  In no event shall Info-ZIP or its contributors be held liable
  | 
        
        
            | 
            | 
           36 | 
           // for any direct, indirect, incidental, special or consequential damages
  | 
        
        
            | 
            | 
           37 | 
           // arising out of the use of or inability to use 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. Redistributions of source code must retain the above copyright notice,
  | 
        
        
            | 
            | 
           44 | 
           //       definition, disclaimer, and this list of conditions.
  | 
        
        
            | 
            | 
           45 | 
           //
  | 
        
        
            | 
            | 
           46 | 
           //    2. Redistributions in binary form must reproduce the above copyright
  | 
        
        
            | 
            | 
           47 | 
           //       notice, definition, disclaimer, and this list of conditions in
  | 
        
        
            | 
            | 
           48 | 
           //       documentation and/or other materials provided with the distribution.
  | 
        
        
            | 
            | 
           49 | 
           //
  | 
        
        
            | 
            | 
           50 | 
           //    3. Altered versions--including, but not limited to, ports to new operating
  | 
        
        
            | 
            | 
           51 | 
           //       systems, existing ports with new graphical interfaces, and dynamic,
  | 
        
        
            | 
            | 
           52 | 
           //       shared, or static library versions--must be plainly marked as such
  | 
        
        
            | 
            | 
           53 | 
           //       and must not be misrepresented as being the original source.  Such
  | 
        
        
            | 
            | 
           54 | 
           //       altered versions also must not be misrepresented as being Info-ZIP
  | 
        
        
            | 
            | 
           55 | 
           //       releases--including, but not limited to, labeling of the altered
  | 
        
        
            | 
            | 
           56 | 
           //       versions with the names "Info-ZIP" (or any variation thereof, including,
  | 
        
        
            | 
            | 
           57 | 
           //       but not limited to, different capitalizations), "Pocket UnZip," "WiZ"
  | 
        
        
            | 
            | 
           58 | 
           //       or "MacZip" without the explicit permission of Info-ZIP.  Such altered
  | 
        
        
            | 
            | 
           59 | 
           //       versions are further prohibited from misrepresentative use of the
  | 
        
        
            | 
            | 
           60 | 
           //       Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s).
  | 
        
        
            | 
            | 
           61 | 
           //
  | 
        
        
            | 
            | 
           62 | 
           //    4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip,"
  | 
        
        
            | 
            | 
           63 | 
           //       "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its own source and
  | 
        
        
            | 
            | 
           64 | 
           //       binary releases.
  | 
        
        
            | 
            | 
           65 | 
           //
  | 
        
        
            | 
            | 
           66 | 
              | 
        
        
            | 
            | 
           67 | 
              | 
        
        
            | 
            | 
           68 | 
           typedef unsigned char uch;      // unsigned 8-bit value
  | 
        
        
            | 
            | 
           69 | 
           typedef unsigned short ush;     // unsigned 16-bit value
  | 
        
        
            | 
            | 
           70 | 
           typedef unsigned long ulg;      // unsigned 32-bit value
  | 
        
        
            | 
            | 
           71 | 
           typedef size_t extent;          // file size
  | 
        
        
            | 
            | 
           72 | 
           typedef unsigned Pos;   // must be at least 32 bits
  | 
        
        
            | 
            | 
           73 | 
           typedef unsigned IPos; // A Pos is an index in the character window. Pos is used only for parameter passing
  | 
        
        
            | 
            | 
           74 | 
              | 
        
        
            | 
            | 
           75 | 
           #ifndef EOF
  | 
        
        
            | 
            | 
           76 | 
           #define EOF (-1)
  | 
        
        
            | 
            | 
           77 | 
           #endif
  | 
        
        
            | 
            | 
           78 | 
              | 
        
        
            | 
            | 
           79 | 
              | 
        
        
            | 
            | 
           80 | 
           // Error return values.  The values 0..4 and 12..18 follow the conventions
  | 
        
        
            | 
            | 
           81 | 
           // of PKZIP.   The values 4..10 are all assigned to "insufficient memory"
  | 
        
        
            | 
            | 
           82 | 
           // by PKZIP, so the codes 5..10 are used here for other purposes.
  | 
        
        
            | 
            | 
           83 | 
           #define ZE_MISS         -1      // used by procname(), zipbare()
  | 
        
        
            | 
            | 
           84 | 
           #define ZE_OK           0       // success
  | 
        
        
            | 
            | 
           85 | 
           #define ZE_EOF          2       // unexpected end of zip file
  | 
        
        
            | 
            | 
           86 | 
           #define ZE_FORM         3       // zip file structure error
  | 
        
        
            | 
            | 
           87 | 
           #define ZE_MEM          4       // out of memory
  | 
        
        
            | 
            | 
           88 | 
           #define ZE_LOGIC        5       // internal logic error
  | 
        
        
            | 
            | 
           89 | 
           #define ZE_BIG          6       // entry too large to split
  | 
        
        
            | 
            | 
           90 | 
           #define ZE_NOTE         7       // invalid comment format
  | 
        
        
            | 
            | 
           91 | 
           #define ZE_TEST         8       // zip test (-T) failed or out of memory
  | 
        
        
            | 
            | 
           92 | 
           #define ZE_ABORT        9       // user interrupt or termination
  | 
        
        
            | 
            | 
           93 | 
           #define ZE_TEMP         10      // error using a temp file
  | 
        
        
            | 
            | 
           94 | 
           #define ZE_READ         11      // read or seek error
  | 
        
        
            | 
            | 
           95 | 
           #define ZE_NONE         12      // nothing to do
  | 
        
        
            | 
            | 
           96 | 
           #define ZE_NAME         13      // missing or empty zip file
  | 
        
        
            | 
            | 
           97 | 
           #define ZE_WRITE        14      // error writing to a file
  | 
        
        
            | 
            | 
           98 | 
           #define ZE_CREAT        15      // couldn't open to write
  | 
        
        
            | 
            | 
           99 | 
           #define ZE_PARMS        16      // bad command line
  | 
        
        
            | 
            | 
           100 | 
           #define ZE_OPEN         18      // could not open a specified file to read
  | 
        
        
            | 
            | 
           101 | 
           #define ZE_MAXERR       18      // the highest error number
  | 
        
        
            | 
            | 
           102 | 
              | 
        
        
            | 
            | 
           103 | 
              | 
        
        
            | 
            | 
           104 | 
           // internal file attribute
  | 
        
        
            | 
            | 
           105 | 
           #define UNKNOWN (-1)
  | 
        
        
            | 
            | 
           106 | 
           #define BINARY  0
  | 
        
        
            | 
            | 
           107 | 
           #define ASCII   1
  | 
        
        
            | 
            | 
           108 | 
              | 
        
        
            | 
            | 
           109 | 
           #define BEST -1                 // Use best method (deflation or store)
  | 
        
        
            | 
            | 
           110 | 
           #define STORE 0                 // Store method
  | 
        
        
            | 
            | 
           111 | 
           #define DEFLATE 8               // Deflation method
  | 
        
        
            | 
            | 
           112 | 
              | 
        
        
            | 
            | 
           113 | 
           #define CRCVAL_INITIAL  0L
  | 
        
        
            | 
            | 
           114 | 
              | 
        
        
            | 
            | 
           115 | 
           // MSDOS file or directory attributes
  | 
        
        
            | 
            | 
           116 | 
           #define MSDOS_HIDDEN_ATTR 0x02
  | 
        
        
            | 
            | 
           117 | 
           #define MSDOS_DIR_ATTR 0x10
  | 
        
        
            | 
            | 
           118 | 
              | 
        
        
            | 
            | 
           119 | 
           // Lengths of headers after signatures in bytes
  | 
        
        
            | 
            | 
           120 | 
           #define LOCHEAD 26
  | 
        
        
            | 
            | 
           121 | 
           #define CENHEAD 42
  | 
        
        
            | 
            | 
           122 | 
           #define ENDHEAD 18
  | 
        
        
            | 
            | 
           123 | 
              | 
        
        
            | 
            | 
           124 | 
           // Definitions for extra field handling:
  | 
        
        
            | 
            | 
           125 | 
           #define EB_HEADSIZE       4     /* length of a extra field block header */
  | 
        
        
            | 
            | 
           126 | 
           #define EB_LEN            2     /* offset of data length field in header */
  | 
        
        
            | 
            | 
           127 | 
           #define EB_UT_MINLEN      1     /* minimal UT field contains Flags byte */
  | 
        
        
            | 
            | 
           128 | 
           #define EB_UT_FLAGS       0     /* byte offset of Flags field */
  | 
        
        
            | 
            | 
           129 | 
           #define EB_UT_TIME1       1     /* byte offset of 1st time value */
  | 
        
        
            | 
            | 
           130 | 
           #define EB_UT_FL_MTIME    (1 << 0)      /* mtime present */
  | 
        
        
            | 
            | 
           131 | 
           #define EB_UT_FL_ATIME    (1 << 1)      /* atime present */
  | 
        
        
            | 
            | 
           132 | 
           #define EB_UT_FL_CTIME    (1 << 2)      /* ctime present */
  | 
        
        
            | 
            | 
           133 | 
           #define EB_UT_LEN(n)      (EB_UT_MINLEN + 4 * (n))
  | 
        
        
            | 
            | 
           134 | 
           #define EB_L_UT_SIZE    (EB_HEADSIZE + EB_UT_LEN(3))
  | 
        
        
            | 
            | 
           135 | 
           #define EB_C_UT_SIZE    (EB_HEADSIZE + EB_UT_LEN(1))
  | 
        
        
            | 
            | 
           136 | 
              | 
        
        
            | 
            | 
           137 | 
              | 
        
        
            | 
            | 
           138 | 
           // Macros for writing machine integers to little-endian format
  | 
        
        
            | 
            | 
           139 | 
           #define PUTSH(a,f) {char _putsh_c=(char)((a)&0xff); wfunc(param,&_putsh_c,1); _putsh_c=(char)((a)>>8); wfunc(param,&_putsh_c,1);}
  | 
        
        
            | 
            | 
           140 | 
           #define PUTLG(a,f) {PUTSH((a) & 0xffff,(f)) PUTSH((a) >> 16,(f))}
  | 
        
        
            | 
            | 
           141 | 
              | 
        
        
            | 
            | 
           142 | 
              | 
        
        
            | 
            | 
           143 | 
           // -- Structure of a ZIP file --
  | 
        
        
            | 
            | 
           144 | 
           // Signatures for zip file information headers
  | 
        
        
            | 
            | 
           145 | 
           #define LOCSIG     0x04034b50L
  | 
        
        
            | 
            | 
           146 | 
           #define CENSIG     0x02014b50L
  | 
        
        
            | 
            | 
           147 | 
           #define ENDSIG     0x06054b50L
  | 
        
        
            | 
            | 
           148 | 
           #define EXTLOCSIG  0x08074b50L
  | 
        
        
            | 
            | 
           149 | 
              | 
        
        
            | 
            | 
           150 | 
              | 
        
        
            | 
            | 
           151 | 
           #define MIN_MATCH  3
  | 
        
        
            | 
            | 
           152 | 
           #define MAX_MATCH  258
  | 
        
        
            | 
            | 
           153 | 
           // The minimum and maximum match lengths
  | 
        
        
            | 
            | 
           154 | 
              | 
        
        
            | 
            | 
           155 | 
              | 
        
        
            | 
            | 
           156 | 
           #define WSIZE  (0x8000)
  | 
        
        
            | 
            | 
           157 | 
           // Maximum window size = 32K. If you are really short of memory, compile
  | 
        
        
            | 
            | 
           158 | 
           // with a smaller WSIZE but this reduces the compression ratio for files
  | 
        
        
            | 
            | 
           159 | 
           // of size > WSIZE. WSIZE must be a power of two in the current implementation.
  | 
        
        
            | 
            | 
           160 | 
           //
  | 
        
        
            | 
            | 
           161 | 
              | 
        
        
            | 
            | 
           162 | 
           #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
  | 
        
        
            | 
            | 
           163 | 
           // Minimum amount of lookahead, except at the end of the input file.
  | 
        
        
            | 
            | 
           164 | 
           // See deflate.c for comments about the MIN_MATCH+1.
  | 
        
        
            | 
            | 
           165 | 
           //
  | 
        
        
            | 
            | 
           166 | 
              | 
        
        
            | 
            | 
           167 | 
           #define MAX_DIST  (WSIZE-MIN_LOOKAHEAD)
  | 
        
        
            | 
            | 
           168 | 
           // In order to simplify the code, particularly on 16 bit machines, match
  | 
        
        
            | 
            | 
           169 | 
           // distances are limited to MAX_DIST instead of WSIZE.
  | 
        
        
            | 
            | 
           170 | 
           //
  | 
        
        
            | 
            | 
           171 | 
              | 
        
        
            | 
            | 
           172 | 
              | 
        
        
            | 
            | 
           173 | 
           #define ZIP_HANDLE   1
  | 
        
        
            | 
            | 
           174 | 
           #define ZIP_FILENAME 2
  | 
        
        
            | 
            | 
           175 | 
           #define ZIP_MEMORY   3
  | 
        
        
            | 
            | 
           176 | 
           #define ZIP_FOLDER   4
  | 
        
        
            | 
            | 
           177 | 
              | 
        
        
            | 
            | 
           178 | 
              | 
        
        
            | 
            | 
           179 | 
              | 
        
        
            | 
            | 
           180 | 
           // ===========================================================================
  | 
        
        
            | 
            | 
           181 | 
           // Constants
  | 
        
        
            | 
            | 
           182 | 
           //
  | 
        
        
            | 
            | 
           183 | 
              | 
        
        
            | 
            | 
           184 | 
           #define MAX_BITS 15
  | 
        
        
            | 
            | 
           185 | 
           // All codes must not exceed MAX_BITS bits
  | 
        
        
            | 
            | 
           186 | 
              | 
        
        
            | 
            | 
           187 | 
           #define MAX_BL_BITS 7
  | 
        
        
            | 
            | 
           188 | 
           // Bit length codes must not exceed MAX_BL_BITS bits
  | 
        
        
            | 
            | 
           189 | 
              | 
        
        
            | 
            | 
           190 | 
           #define LENGTH_CODES 29
  | 
        
        
            | 
            | 
           191 | 
           // number of length codes, not counting the special END_BLOCK code
  | 
        
        
            | 
            | 
           192 | 
              | 
        
        
            | 
            | 
           193 | 
           #define LITERALS  256
  | 
        
        
            | 
            | 
           194 | 
           // number of literal bytes 0..255
  | 
        
        
            | 
            | 
           195 | 
              | 
        
        
            | 
            | 
           196 | 
           #define END_BLOCK 256
  | 
        
        
            | 
            | 
           197 | 
           // end of block literal code
  | 
        
        
            | 
            | 
           198 | 
              | 
        
        
            | 
            | 
           199 | 
           #define L_CODES (LITERALS+1+LENGTH_CODES)
  | 
        
        
            | 
            | 
           200 | 
           // number of Literal or Length codes, including the END_BLOCK code
  | 
        
        
            | 
            | 
           201 | 
              | 
        
        
            | 
            | 
           202 | 
           #define D_CODES   30
  | 
        
        
            | 
            | 
           203 | 
           // number of distance codes
  | 
        
        
            | 
            | 
           204 | 
              | 
        
        
            | 
            | 
           205 | 
           #define BL_CODES  19
  | 
        
        
            | 
            | 
           206 | 
           // number of codes used to transfer the bit lengths
  | 
        
        
            | 
            | 
           207 | 
              | 
        
        
            | 
            | 
           208 | 
              | 
        
        
            | 
            | 
           209 | 
           #define STORED_BLOCK 0
  | 
        
        
            | 
            | 
           210 | 
           #define STATIC_TREES 1
  | 
        
        
            | 
            | 
           211 | 
           #define DYN_TREES    2
  | 
        
        
            | 
            | 
           212 | 
           // The three kinds of block type
  | 
        
        
            | 
            | 
           213 | 
              | 
        
        
            | 
            | 
           214 | 
           #define LIT_BUFSIZE  0x8000
  | 
        
        
            | 
            | 
           215 | 
           #define DIST_BUFSIZE  LIT_BUFSIZE
  | 
        
        
            | 
            | 
           216 | 
           // Sizes of match buffers for literals/lengths and distances.  There are
  | 
        
        
            | 
            | 
           217 | 
           // 4 reasons for limiting LIT_BUFSIZE to 64K:
  | 
        
        
            | 
            | 
           218 | 
           //   - frequencies can be kept in 16 bit counters
  | 
        
        
            | 
            | 
           219 | 
           //   - if compression is not successful for the first block, all input data is
  | 
        
        
            | 
            | 
           220 | 
           //     still in the window so we can still emit a stored block even when input
  | 
        
        
            | 
            | 
           221 | 
           //     comes from standard input.  (This can also be done for all blocks if
  | 
        
        
            | 
            | 
           222 | 
           //     LIT_BUFSIZE is not greater than 32K.)
  | 
        
        
            | 
            | 
           223 | 
           //   - if compression is not successful for a file smaller than 64K, we can
  | 
        
        
            | 
            | 
           224 | 
           //     even emit a stored file instead of a stored block (saving 5 bytes).
  | 
        
        
            | 
            | 
           225 | 
           //   - creating new Huffman trees less frequently may not provide fast
  | 
        
        
            | 
            | 
           226 | 
           //     adaptation to changes in the input data statistics. (Take for
  | 
        
        
            | 
            | 
           227 | 
           //     example a binary file with poorly compressible code followed by
  | 
        
        
            | 
            | 
           228 | 
           //     a highly compressible string table.) Smaller buffer sizes give
  | 
        
        
            | 
            | 
           229 | 
           //     fast adaptation but have of course the overhead of transmitting trees
  | 
        
        
            | 
            | 
           230 | 
           //     more frequently.
  | 
        
        
            | 
            | 
           231 | 
           //   - I can't count above 4
  | 
        
        
            | 
            | 
           232 | 
           // The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save
  | 
        
        
            | 
            | 
           233 | 
           // memory at the expense of compression). Some optimizations would be possible
  | 
        
        
            | 
            | 
           234 | 
           // if we rely on DIST_BUFSIZE == LIT_BUFSIZE.
  | 
        
        
            | 
            | 
           235 | 
           //
  | 
        
        
            | 
            | 
           236 | 
              | 
        
        
            | 
            | 
           237 | 
           #define REP_3_6      16
  | 
        
        
            | 
            | 
           238 | 
           // repeat previous bit length 3-6 times (2 bits of repeat count)
  | 
        
        
            | 
            | 
           239 | 
              | 
        
        
            | 
            | 
           240 | 
           #define REPZ_3_10    17
  | 
        
        
            | 
            | 
           241 | 
           // repeat a zero length 3-10 times  (3 bits of repeat count)
  | 
        
        
            | 
            | 
           242 | 
              | 
        
        
            | 
            | 
           243 | 
           #define REPZ_11_138  18
  | 
        
        
            | 
            | 
           244 | 
           // repeat a zero length 11-138 times  (7 bits of repeat count)
  | 
        
        
            | 
            | 
           245 | 
              | 
        
        
            | 
            | 
           246 | 
           #define HEAP_SIZE (2*L_CODES+1)
  | 
        
        
            | 
            | 
           247 | 
           // maximum heap size
  | 
        
        
            | 
            | 
           248 | 
              | 
        
        
            | 
            | 
           249 | 
              | 
        
        
            | 
            | 
           250 | 
           // ===========================================================================
  | 
        
        
            | 
            | 
           251 | 
           // Local data used by the "bit string" routines.
  | 
        
        
            | 
            | 
           252 | 
           //
  | 
        
        
            | 
            | 
           253 | 
              | 
        
        
            | 
            | 
           254 | 
           #define Buf_size (8 * 2*sizeof(char))
  | 
        
        
            | 
            | 
           255 | 
           // Number of bits used within bi_buf. (bi_buf may be implemented on
  | 
        
        
            | 
            | 
           256 | 
           // more than 16 bits on some systems.)
  | 
        
        
            | 
            | 
           257 | 
              | 
        
        
            | 
            | 
           258 | 
           // Output a 16 bit value to the bit stream, lower (oldest) byte first
  | 
        
        
            | 
            | 
           259 | 
           #define PUTSHORT(state,w) \
  | 
        
        
            | 
            | 
           260 | 
           { if (state.bs.out_offset >= state.bs.out_size-1) \
  | 
        
        
            | 
            | 
           261 | 
               state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); \
  | 
        
        
            | 
            | 
           262 | 
             state.bs.out_buf[state.bs.out_offset++] = (char) ((w) & 0xff); \
  | 
        
        
            | 
            | 
           263 | 
             state.bs.out_buf[state.bs.out_offset++] = (char) ((ush)(w) >> 8); \
  | 
        
        
            | 
            | 
           264 | 
           }
  | 
        
        
            | 
            | 
           265 | 
              | 
        
        
            | 
            | 
           266 | 
           #define PUTBYTE(state,b) \
  | 
        
        
            | 
            | 
           267 | 
           { if (state.bs.out_offset >= state.bs.out_size) \
  | 
        
        
            | 
            | 
           268 | 
               state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); \
  | 
        
        
            | 
            | 
           269 | 
             state.bs.out_buf[state.bs.out_offset++] = (char) (b); \
  | 
        
        
            | 
            | 
           270 | 
           }
  | 
        
        
            | 
            | 
           271 | 
              | 
        
        
            | 
            | 
           272 | 
           // DEFLATE.CPP HEADER
  | 
        
        
            | 
            | 
           273 | 
              | 
        
        
            | 
            | 
           274 | 
           #define HASH_BITS  15
  | 
        
        
            | 
            | 
           275 | 
           // For portability to 16 bit machines, do not use values above 15.
  | 
        
        
            | 
            | 
           276 | 
              | 
        
        
            | 
            | 
           277 | 
           #define HASH_SIZE (unsigned)(1<<HASH_BITS)
  | 
        
        
            | 
            | 
           278 | 
           #define HASH_MASK (HASH_SIZE-1)
  | 
        
        
            | 
            | 
           279 | 
           #define WMASK     (WSIZE-1)
  | 
        
        
            | 
            | 
           280 | 
           // HASH_SIZE and WSIZE must be powers of two
  | 
        
        
            | 
            | 
           281 | 
              | 
        
        
            | 
            | 
           282 | 
           #define NIL 0
  | 
        
        
            | 
            | 
           283 | 
           // Tail of hash chains
  | 
        
        
            | 
            | 
           284 | 
              | 
        
        
            | 
            | 
           285 | 
           #define FAST 4
  | 
        
        
            | 
            | 
           286 | 
           #define SLOW 2
  | 
        
        
            | 
            | 
           287 | 
           // speed options for the general purpose bit flag
  | 
        
        
            | 
            | 
           288 | 
              | 
        
        
            | 
            | 
           289 | 
           #define TOO_FAR 4096
  | 
        
        
            | 
            | 
           290 | 
           // Matches of length 3 are discarded if their distance exceeds TOO_FAR
  | 
        
        
            | 
            | 
           291 | 
              | 
        
        
            | 
            | 
           292 | 
              | 
        
        
            | 
            | 
           293 | 
              | 
        
        
            | 
            | 
           294 | 
           #define EQUAL 0
  | 
        
        
            | 
            | 
           295 | 
           // result of memcmp for equal strings
  | 
        
        
            | 
            | 
           296 | 
              | 
        
        
            | 
            | 
           297 | 
              | 
        
        
            | 
            | 
           298 | 
           // ===========================================================================
  | 
        
        
            | 
            | 
           299 | 
           // Local data used by the "longest match" routines.
  | 
        
        
            | 
            | 
           300 | 
              | 
        
        
            | 
            | 
           301 | 
           #define H_SHIFT  ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
  | 
        
        
            | 
            | 
           302 | 
           // Number of bits by which ins_h and del_h must be shifted at each
  | 
        
        
            | 
            | 
           303 | 
           // input step. It must be such that after MIN_MATCH steps, the oldest
  | 
        
        
            | 
            | 
           304 | 
           // byte no longer takes part in the hash key, that is:
  | 
        
        
            | 
            | 
           305 | 
           //   H_SHIFT * MIN_MATCH >= HASH_BITS
  | 
        
        
            | 
            | 
           306 | 
              | 
        
        
            | 
            | 
           307 | 
           #define max_insert_length  max_lazy_match
  | 
        
        
            | 
            | 
           308 | 
           // Insert new strings in the hash table only if the match length
  | 
        
        
            | 
            | 
           309 | 
           // is not greater than this length. This saves time but degrades compression.
  | 
        
        
            | 
            | 
           310 | 
           // max_insert_length is used only for compression levels <= 3.
  | 
        
        
            | 
            | 
           311 | 
              | 
        
        
            | 
            | 
           312 | 
              | 
        
        
            | 
            | 
           313 | 
              | 
        
        
            | 
            | 
           314 | 
           const int extra_lbits[LENGTH_CODES] // extra bits for each length code
  | 
        
        
            | 
            | 
           315 | 
              = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
  | 
        
        
            | 
            | 
           316 | 
              | 
        
        
            | 
            | 
           317 | 
           const int extra_dbits[D_CODES] // extra bits for each distance code
  | 
        
        
            | 
            | 
           318 | 
              = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
  | 
        
        
            | 
            | 
           319 | 
              | 
        
        
            | 
            | 
           320 | 
           const int extra_blbits[BL_CODES]// extra bits for each bit length code
  | 
        
        
            | 
            | 
           321 | 
              = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
  | 
        
        
            | 
            | 
           322 | 
              | 
        
        
            | 
            | 
           323 | 
           const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
  | 
        
        
            | 
            | 
           324 | 
           // The lengths of the bit length codes are sent in order of decreasing
  | 
        
        
            | 
            | 
           325 | 
           // probability, to avoid transmitting the lengths for unused bit length codes.
  | 
        
        
            | 
            | 
           326 | 
              | 
        
        
            | 
            | 
           327 | 
              | 
        
        
            | 
            | 
           328 | 
           typedef struct config {
  | 
        
        
            | 
            | 
           329 | 
              ush good_length; // reduce lazy search above this match length
  | 
        
        
            | 
            | 
           330 | 
              ush max_lazy;    // do not perform lazy search above this match length
  | 
        
        
            | 
            | 
           331 | 
              ush nice_length; // quit search above this match length
  | 
        
        
            | 
            | 
           332 | 
              ush max_chain;
  | 
        
        
            | 
            | 
           333 | 
           } config;
  | 
        
        
            | 
            | 
           334 | 
              | 
        
        
            | 
            | 
           335 | 
           // Values for max_lazy_match, good_match, nice_match and max_chain_length,
  | 
        
        
            | 
            | 
           336 | 
           // depending on the desired pack level (0..9). The values given below have
  | 
        
        
            | 
            | 
           337 | 
           // been tuned to exclude worst case performance for pathological files.
  | 
        
        
            | 
            | 
           338 | 
           // Better values may be found for specific files.
  | 
        
        
            | 
            | 
           339 | 
           //
  | 
        
        
            | 
            | 
           340 | 
              | 
        
        
            | 
            | 
           341 | 
           const config configuration_table[10] = {
  | 
        
        
            | 
            | 
           342 | 
           //  good lazy nice chain
  | 
        
        
            | 
            | 
           343 | 
               {0,    0,  0,    0},  // 0 store only
  | 
        
        
            | 
            | 
           344 | 
               {4,    4,  8,    4},  // 1 maximum speed, no lazy matches
  | 
        
        
            | 
            | 
           345 | 
               {4,    5, 16,    8},  // 2
  | 
        
        
            | 
            | 
           346 | 
               {4,    6, 32,   32},  // 3
  | 
        
        
            | 
            | 
           347 | 
               {4,    4, 16,   16},  // 4 lazy matches */
  | 
        
        
            | 
            | 
           348 | 
               {8,   16, 32,   32},  // 5
  | 
        
        
            | 
            | 
           349 | 
               {8,   16, 128, 128},  // 6
  | 
        
        
            | 
            | 
           350 | 
               {8,   32, 128, 256},  // 7
  | 
        
        
            | 
            | 
           351 | 
               {32, 128, 258, 1024}, // 8
  | 
        
        
            | 
            | 
           352 | 
               {32, 258, 258, 4096}};// 9 maximum compression */
  | 
        
        
            | 
            | 
           353 | 
              | 
        
        
            | 
            | 
           354 | 
           // Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
  | 
        
        
            | 
            | 
           355 | 
           // For deflate_fast() (levels <= 3) good is ignored and lazy has a different meaning.
  | 
        
        
            | 
            | 
           356 | 
              | 
        
        
            | 
            | 
           357 | 
              | 
        
        
            | 
            | 
           358 | 
              | 
        
        
            | 
            | 
           359 | 
              | 
        
        
            | 
            | 
           360 | 
              | 
        
        
            | 
            | 
           361 | 
              | 
        
        
            | 
            | 
           362 | 
              | 
        
        
            | 
            | 
           363 | 
           // Data structure describing a single value and its code string.
  | 
        
        
            | 
            | 
           364 | 
           typedef struct ct_data {
  | 
        
        
            | 
            | 
           365 | 
               union {
  | 
        
        
            | 
            | 
           366 | 
                   ush  freq;       // frequency count
  | 
        
        
            | 
            | 
           367 | 
                   ush  code;       // bit string
  | 
        
        
            | 
            | 
           368 | 
               } fc;
  | 
        
        
            | 
            | 
           369 | 
               union {
  | 
        
        
            | 
            | 
           370 | 
                   ush  dad;        // father node in Huffman tree
  | 
        
        
            | 
            | 
           371 | 
                   ush  len;        // length of bit string
  | 
        
        
            | 
            | 
           372 | 
               } dl;
  | 
        
        
            | 
            | 
           373 | 
           } ct_data;
  | 
        
        
            | 
            | 
           374 | 
              | 
        
        
            | 
            | 
           375 | 
           typedef struct tree_desc {
  | 
        
        
            | 
            | 
           376 | 
               ct_data *dyn_tree;      // the dynamic tree
  | 
        
        
            | 
            | 
           377 | 
               ct_data *static_tree;   // corresponding static tree or NULL
  | 
        
        
            | 
            | 
           378 | 
               const int *extra_bits;  // extra bits for each code or NULL
  | 
        
        
            | 
            | 
           379 | 
               int     extra_base;     // base index for extra_bits
  | 
        
        
            | 
            | 
           380 | 
               int     elems;          // max number of elements in the tree
  | 
        
        
            | 
            | 
           381 | 
               int     max_length;     // max bit length for the codes
  | 
        
        
            | 
            | 
           382 | 
               int     max_code;       // largest code with non zero frequency
  | 
        
        
            | 
            | 
           383 | 
           } tree_desc;
  | 
        
        
            | 
            | 
           384 | 
              | 
        
        
            | 
            | 
           385 | 
              | 
        
        
            | 
            | 
           386 | 
              | 
        
        
            | 
            | 
           387 | 
              | 
        
        
            | 
            | 
           388 | 
           class TTreeState
  | 
        
        
            | 
            | 
           389 | 
           { public:
  | 
        
        
            | 
            | 
           390 | 
             TTreeState();
  | 
        
        
            | 
            | 
           391 | 
              | 
        
        
            | 
            | 
           392 | 
             ct_data dyn_ltree[HEAP_SIZE];    // literal and length tree
  | 
        
        
            | 
            | 
           393 | 
             ct_data dyn_dtree[2*D_CODES+1];  // distance tree
  | 
        
        
            | 
            | 
           394 | 
             ct_data static_ltree[L_CODES+2]; // the static literal tree...
  | 
        
        
            | 
            | 
           395 | 
             // ... Since the bit lengths are imposed, there is no need for the L_CODES
  | 
        
        
            | 
            | 
           396 | 
             // extra codes used during heap construction. However the codes 286 and 287
  | 
        
        
            | 
            | 
           397 | 
             // are needed to build a canonical tree (see ct_init below).
  | 
        
        
            | 
            | 
           398 | 
             ct_data static_dtree[D_CODES]; // the static distance tree...
  | 
        
        
            | 
            | 
           399 | 
             // ... (Actually a trivial tree since all codes use 5 bits.)
  | 
        
        
            | 
            | 
           400 | 
             ct_data bl_tree[2*BL_CODES+1];  // Huffman tree for the bit lengths
  | 
        
        
            | 
            | 
           401 | 
              | 
        
        
            | 
            | 
           402 | 
             tree_desc l_desc;
  | 
        
        
            | 
            | 
           403 | 
             tree_desc d_desc;
  | 
        
        
            | 
            | 
           404 | 
             tree_desc bl_desc;
  | 
        
        
            | 
            | 
           405 | 
              | 
        
        
            | 
            | 
           406 | 
             ush bl_count[MAX_BITS+1];  // number of codes at each bit length for an optimal tree
  | 
        
        
            | 
            | 
           407 | 
              | 
        
        
            | 
            | 
           408 | 
             int heap[2*L_CODES+1]; // heap used to build the Huffman trees
  | 
        
        
            | 
            | 
           409 | 
             int heap_len;               // number of elements in the heap
  | 
        
        
            | 
            | 
           410 | 
             int heap_max;               // element of largest frequency
  | 
        
        
            | 
            | 
           411 | 
             // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
  | 
        
        
            | 
            | 
           412 | 
             // The same heap array is used to build all trees.
  | 
        
        
            | 
            | 
           413 | 
              | 
        
        
            | 
            | 
           414 | 
             uch depth[2*L_CODES+1];
  | 
        
        
            | 
            | 
           415 | 
             // Depth of each subtree used as tie breaker for trees of equal frequency
  | 
        
        
            | 
            | 
           416 | 
              | 
        
        
            | 
            | 
           417 | 
             uch length_code[MAX_MATCH-MIN_MATCH+1];
  | 
        
        
            | 
            | 
           418 | 
             // length code for each normalized match length (0 == MIN_MATCH)
  | 
        
        
            | 
            | 
           419 | 
              | 
        
        
            | 
            | 
           420 | 
             uch dist_code[512];
  | 
        
        
            | 
            | 
           421 | 
             // distance codes. The first 256 values correspond to the distances
  | 
        
        
            | 
            | 
           422 | 
             // 3 .. 258, the last 256 values correspond to the top 8 bits of
  | 
        
        
            | 
            | 
           423 | 
             // the 15 bit distances.
  | 
        
        
            | 
            | 
           424 | 
              | 
        
        
            | 
            | 
           425 | 
             int base_length[LENGTH_CODES];
  | 
        
        
            | 
            | 
           426 | 
             // First normalized length for each code (0 = MIN_MATCH)
  | 
        
        
            | 
            | 
           427 | 
              | 
        
        
            | 
            | 
           428 | 
             int base_dist[D_CODES];
  | 
        
        
            | 
            | 
           429 | 
             // First normalized distance for each code (0 = distance of 1)
  | 
        
        
            | 
            | 
           430 | 
              | 
        
        
            | 
            | 
           431 | 
             uch far l_buf[LIT_BUFSIZE];  // buffer for literals/lengths
  | 
        
        
            | 
            | 
           432 | 
             ush far d_buf[DIST_BUFSIZE]; // buffer for distances
  | 
        
        
            | 
            | 
           433 | 
              | 
        
        
            | 
            | 
           434 | 
             uch flag_buf[(LIT_BUFSIZE/8)];
  | 
        
        
            | 
            | 
           435 | 
             // flag_buf is a bit array distinguishing literals from lengths in
  | 
        
        
            | 
            | 
           436 | 
             // l_buf, and thus indicating the presence or absence of a distance.
  | 
        
        
            | 
            | 
           437 | 
              | 
        
        
            | 
            | 
           438 | 
             unsigned last_lit;    // running index in l_buf
  | 
        
        
            | 
            | 
           439 | 
             unsigned last_dist;   // running index in d_buf
  | 
        
        
            | 
            | 
           440 | 
             unsigned last_flags;  // running index in flag_buf
  | 
        
        
            | 
            | 
           441 | 
             uch flags;            // current flags not yet saved in flag_buf
  | 
        
        
            | 
            | 
           442 | 
             uch flag_bit;         // current bit used in flags
  | 
        
        
            | 
            | 
           443 | 
             // bits are filled in flags starting at bit 0 (least significant).
  | 
        
        
            | 
            | 
           444 | 
             // Note: these flags are overkill in the current code since we don't
  | 
        
        
            | 
            | 
           445 | 
             // take advantage of DIST_BUFSIZE == LIT_BUFSIZE.
  | 
        
        
            | 
            | 
           446 | 
              | 
        
        
            | 
            | 
           447 | 
             ulg opt_len;          // bit length of current block with optimal trees
  | 
        
        
            | 
            | 
           448 | 
             ulg static_len;       // bit length of current block with static trees
  | 
        
        
            | 
            | 
           449 | 
              | 
        
        
            | 
            | 
           450 | 
             ulg cmpr_bytelen;     // total byte length of compressed file
  | 
        
        
            | 
            | 
           451 | 
             ulg cmpr_len_bits;    // number of bits past 'cmpr_bytelen'
  | 
        
        
            | 
            | 
           452 | 
              | 
        
        
            | 
            | 
           453 | 
             ulg input_len;        // total byte length of input file
  | 
        
        
            | 
            | 
           454 | 
             // input_len is for debugging only since we can get it by other means.
  | 
        
        
            | 
            | 
           455 | 
              | 
        
        
            | 
            | 
           456 | 
             ush *file_type;       // pointer to UNKNOWN, BINARY or ASCII
  | 
        
        
            | 
            | 
           457 | 
           //  int *file_method;     // pointer to DEFLATE or STORE
  | 
        
        
            | 
            | 
           458 | 
           };
  | 
        
        
            | 
            | 
           459 | 
              | 
        
        
            | 
            | 
           460 | 
           TTreeState::TTreeState()
  | 
        
        
            | 
            | 
           461 | 
           { tree_desc a = {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0};  l_desc = a;
  | 
        
        
            | 
            | 
           462 | 
             tree_desc b = {dyn_dtree, static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS, 0};  d_desc = b;
  | 
        
        
            | 
            | 
           463 | 
             tree_desc c = {bl_tree, NULL,       extra_blbits, 0,         BL_CODES, MAX_BL_BITS, 0};  bl_desc = c;
  | 
        
        
            | 
            | 
           464 | 
             last_lit=0;
  | 
        
        
            | 
            | 
           465 | 
             last_dist=0;
  | 
        
        
            | 
            | 
           466 | 
             last_flags=0;
  | 
        
        
            | 
            | 
           467 | 
           }
  | 
        
        
            | 
            | 
           468 | 
              | 
        
        
            | 
            | 
           469 | 
              | 
        
        
            | 
            | 
           470 | 
              | 
        
        
            | 
            | 
           471 | 
           class TBitState
  | 
        
        
            | 
            | 
           472 | 
           { public:
  | 
        
        
            | 
            | 
           473 | 
              | 
        
        
            | 
            | 
           474 | 
             int flush_flg;
  | 
        
        
            | 
            | 
           475 | 
             //
  | 
        
        
            | 
            | 
           476 | 
             unsigned bi_buf;
  | 
        
        
            | 
            | 
           477 | 
             // Output buffer. bits are inserted starting at the bottom (least significant
  | 
        
        
            | 
            | 
           478 | 
             // bits). The width of bi_buf must be at least 16 bits.
  | 
        
        
            | 
            | 
           479 | 
             int bi_valid;
  | 
        
        
            | 
            | 
           480 | 
             // Number of valid bits in bi_buf.  All bits above the last valid bit
  | 
        
        
            | 
            | 
           481 | 
             // are always zero.
  | 
        
        
            | 
            | 
           482 | 
             char *out_buf;
  | 
        
        
            | 
            | 
           483 | 
             // Current output buffer.
  | 
        
        
            | 
            | 
           484 | 
             unsigned out_offset;
  | 
        
        
            | 
            | 
           485 | 
             // Current offset in output buffer.
  | 
        
        
            | 
            | 
           486 | 
             // On 16 bit machines, the buffer is limited to 64K.
  | 
        
        
            | 
            | 
           487 | 
             unsigned out_size;
  | 
        
        
            | 
            | 
           488 | 
             // Size of current output buffer
  | 
        
        
            | 
            | 
           489 | 
             ulg bits_sent;   // bit length of the compressed data  only needed for debugging???
  | 
        
        
            | 
            | 
           490 | 
           };
  | 
        
        
            | 
            | 
           491 | 
              | 
        
        
            | 
            | 
           492 | 
              | 
        
        
            | 
            | 
           493 | 
              | 
        
        
            | 
            | 
           494 | 
              | 
        
        
            | 
            | 
           495 | 
              | 
        
        
            | 
            | 
           496 | 
              | 
        
        
            | 
            | 
           497 | 
              | 
        
        
            | 
            | 
           498 | 
           class TDeflateState
  | 
        
        
            | 
            | 
           499 | 
           { public:
  | 
        
        
            | 
            | 
           500 | 
             TDeflateState() {window_size=0;}
  | 
        
        
            | 
            | 
           501 | 
              | 
        
        
            | 
            | 
           502 | 
             uch    window[2L*WSIZE];
  | 
        
        
            | 
            | 
           503 | 
             // Sliding window. Input bytes are read into the second half of the window,
  | 
        
        
            | 
            | 
           504 | 
             // and move to the first half later to keep a dictionary of at least WSIZE
  | 
        
        
            | 
            | 
           505 | 
             // bytes. With this organization, matches are limited to a distance of
  | 
        
        
            | 
            | 
           506 | 
             // WSIZE-MAX_MATCH bytes, but this ensures that IO is always
  | 
        
        
            | 
            | 
           507 | 
             // performed with a length multiple of the block size. Also, it limits
  | 
        
        
            | 
            | 
           508 | 
             // the window size to 64K, which is quite useful on MSDOS.
  | 
        
        
            | 
            | 
           509 | 
             // To do: limit the window size to WSIZE+CBSZ if SMALL_MEM (the code would
  | 
        
        
            | 
            | 
           510 | 
             // be less efficient since the data would have to be copied WSIZE/CBSZ times)
  | 
        
        
            | 
            | 
           511 | 
             Pos    prev[WSIZE];
  | 
        
        
            | 
            | 
           512 | 
             // Link to older string with same hash index. To limit the size of this
  | 
        
        
            | 
            | 
           513 | 
             // array to 64K, this link is maintained only for the last 32K strings.
  | 
        
        
            | 
            | 
           514 | 
             // An index in this array is thus a window index modulo 32K.
  | 
        
        
            | 
            | 
           515 | 
             Pos    head[HASH_SIZE];
  | 
        
        
            | 
            | 
           516 | 
             // Heads of the hash chains or NIL. If your compiler thinks that
  | 
        
        
            | 
            | 
           517 | 
             // HASH_SIZE is a dynamic value, recompile with -DDYN_ALLOC.
  | 
        
        
            | 
            | 
           518 | 
              | 
        
        
            | 
            | 
           519 | 
             ulg window_size;
  | 
        
        
            | 
            | 
           520 | 
             // window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
  | 
        
        
            | 
            | 
           521 | 
             // input file length plus MIN_LOOKAHEAD.
  | 
        
        
            | 
            | 
           522 | 
              | 
        
        
            | 
            | 
           523 | 
             long block_start;
  | 
        
        
            | 
            | 
           524 | 
             // window position at the beginning of the current output block. Gets
  | 
        
        
            | 
            | 
           525 | 
             // negative when the window is moved backwards.
  | 
        
        
            | 
            | 
           526 | 
              | 
        
        
            | 
            | 
           527 | 
             int sliding;
  | 
        
        
            | 
            | 
           528 | 
             // Set to false when the input file is already in memory
  | 
        
        
            | 
            | 
           529 | 
              | 
        
        
            | 
            | 
           530 | 
             unsigned ins_h;  // hash index of string to be inserted
  | 
        
        
            | 
            | 
           531 | 
              | 
        
        
            | 
            | 
           532 | 
             unsigned int prev_length;
  | 
        
        
            | 
            | 
           533 | 
             // Length of the best match at previous step. Matches not greater than this
  | 
        
        
            | 
            | 
           534 | 
             // are discarded. This is used in the lazy match evaluation.
  | 
        
        
            | 
            | 
           535 | 
              | 
        
        
            | 
            | 
           536 | 
             unsigned strstart;         // start of string to insert
  | 
        
        
            | 
            | 
           537 | 
             unsigned match_start; // start of matching string
  | 
        
        
            | 
            | 
           538 | 
             int      eofile;           // flag set at end of input file
  | 
        
        
            | 
            | 
           539 | 
             unsigned lookahead;        // number of valid bytes ahead in window
  | 
        
        
            | 
            | 
           540 | 
              | 
        
        
            | 
            | 
           541 | 
             unsigned max_chain_length;
  | 
        
        
            | 
            | 
           542 | 
             // To speed up deflation, hash chains are never searched beyond this length.
  | 
        
        
            | 
            | 
           543 | 
             // A higher limit improves compression ratio but degrades the speed.
  | 
        
        
            | 
            | 
           544 | 
              | 
        
        
            | 
            | 
           545 | 
             unsigned int max_lazy_match;
  | 
        
        
            | 
            | 
           546 | 
             // Attempt to find a better match only when the current match is strictly
  | 
        
        
            | 
            | 
           547 | 
             // smaller than this value. This mechanism is used only for compression
  | 
        
        
            | 
            | 
           548 | 
             // levels >= 4.
  | 
        
        
            | 
            | 
           549 | 
              | 
        
        
            | 
            | 
           550 | 
             unsigned good_match;
  | 
        
        
            | 
            | 
           551 | 
             // Use a faster search when the previous match is longer than this
  | 
        
        
            | 
            | 
           552 | 
              | 
        
        
            | 
            | 
           553 | 
             int nice_match; // Stop searching when current match exceeds this
  | 
        
        
            | 
            | 
           554 | 
           };
  | 
        
        
            | 
            | 
           555 | 
              | 
        
        
            | 
            | 
           556 | 
           typedef __int64 lutime_t;       // define it ourselves since we don't include time.h
  | 
        
        
            | 
            | 
           557 | 
              | 
        
        
            | 
            | 
           558 | 
           typedef struct iztimes {
  | 
        
        
            | 
            | 
           559 | 
             lutime_t atime,mtime,ctime;
  | 
        
        
            | 
            | 
           560 | 
           } iztimes; // access, modify, create times
  | 
        
        
            | 
            | 
           561 | 
              | 
        
        
            | 
            | 
           562 | 
           typedef struct zlist {
  | 
        
        
            | 
            | 
           563 | 
             ush vem, ver, flg, how;       // See central header in zipfile.c for what vem..off are
  | 
        
        
            | 
            | 
           564 | 
             ulg tim, crc, siz, len;
  | 
        
        
            | 
            | 
           565 | 
             extent nam, ext, cext, com;   // offset of ext must be >= LOCHEAD
  | 
        
        
            | 
            | 
           566 | 
             ush dsk, att, lflg;           // offset of lflg must be >= LOCHEAD
  | 
        
        
            | 
            | 
           567 | 
             ulg atx, off;
  | 
        
        
            | 
            | 
           568 | 
             char name[MAX_PATH];          // File name in zip file
  | 
        
        
            | 
            | 
           569 | 
             char *extra;                  // Extra field (set only if ext != 0)
  | 
        
        
            | 
            | 
           570 | 
             char *cextra;                 // Extra in central (set only if cext != 0)
  | 
        
        
            | 
            | 
           571 | 
             char *comment;                // Comment (set only if com != 0)
  | 
        
        
            | 
            | 
           572 | 
             char iname[MAX_PATH];         // Internal file name after cleanup
  | 
        
        
            | 
            | 
           573 | 
             char zname[MAX_PATH];         // External version of internal name
  | 
        
        
            | 
            | 
           574 | 
             int mark;                     // Marker for files to operate on
  | 
        
        
            | 
            | 
           575 | 
             int trash;                    // Marker for files to delete
  | 
        
        
            | 
            | 
           576 | 
             int dosflag;                  // Set to force MSDOS file attributes
  | 
        
        
            | 
            | 
           577 | 
             struct zlist far *nxt;        // Pointer to next header in list
  | 
        
        
            | 
            | 
           578 | 
           } TZipFileInfo;
  | 
        
        
            | 
            | 
           579 | 
              | 
        
        
            | 
            | 
           580 | 
              | 
        
        
            | 
            | 
           581 | 
           struct TState;
  | 
        
        
            | 
            | 
           582 | 
           typedef unsigned (*READFUNC)(TState &state, char *buf,unsigned size);
  | 
        
        
            | 
            | 
           583 | 
           typedef unsigned (*FLUSHFUNC)(void *param, const char *buf, unsigned *size);
  | 
        
        
            | 
            | 
           584 | 
           typedef unsigned (*WRITEFUNC)(void *param, const char *buf, unsigned size);
  | 
        
        
            | 
            | 
           585 | 
           struct TState
  | 
        
        
            | 
            | 
           586 | 
           { void *param;
  | 
        
        
            | 
            | 
           587 | 
             int level; bool seekable;
  | 
        
        
            | 
            | 
           588 | 
             READFUNC readfunc; FLUSHFUNC flush_outbuf;
  | 
        
        
            | 
            | 
           589 | 
             TTreeState ts; TBitState bs; TDeflateState ds;
  | 
        
        
            | 
            | 
           590 | 
             const char *err;
  | 
        
        
            | 
            | 
           591 | 
           };
  | 
        
        
            | 
            | 
           592 | 
              | 
        
        
            | 
            | 
           593 | 
              | 
        
        
            | 
            | 
           594 | 
              | 
        
        
            | 
            | 
           595 | 
              | 
        
        
            | 
            | 
           596 | 
              | 
        
        
            | 
            | 
           597 | 
              | 
        
        
            | 
            | 
           598 | 
              | 
        
        
            | 
            | 
           599 | 
              | 
        
        
            | 
            | 
           600 | 
              | 
        
        
            | 
            | 
           601 | 
           void Assert(TState &state,bool cond, const char *msg)
  | 
        
        
            | 
            | 
           602 | 
           { if (cond) return;
  | 
        
        
            | 
            | 
           603 | 
             state.err=msg;
  | 
        
        
            | 
            | 
           604 | 
           }
  | 
        
        
            | 
            | 
           605 | 
           void __cdecl Trace(const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);}
  | 
        
        
            | 
            | 
           606 | 
           void __cdecl Tracec(bool ,const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);}
  | 
        
        
            | 
            | 
           607 | 
              | 
        
        
            | 
            | 
           608 | 
              | 
        
        
            | 
            | 
           609 | 
              | 
        
        
            | 
            | 
           610 | 
           // ===========================================================================
  | 
        
        
            | 
            | 
           611 | 
           // Local (static) routines in this file.
  | 
        
        
            | 
            | 
           612 | 
           //
  | 
        
        
            | 
            | 
           613 | 
              | 
        
        
            | 
            | 
           614 | 
           void init_block     (TState &);
  | 
        
        
            | 
            | 
           615 | 
           void pqdownheap     (TState &,ct_data *tree, int k);
  | 
        
        
            | 
            | 
           616 | 
           void gen_bitlen     (TState &,tree_desc *desc);
  | 
        
        
            | 
            | 
           617 | 
           void gen_codes      (TState &state,ct_data *tree, int max_code);
  | 
        
        
            | 
            | 
           618 | 
           void build_tree     (TState &,tree_desc *desc);
  | 
        
        
            | 
            | 
           619 | 
           void scan_tree      (TState &,ct_data *tree, int max_code);
  | 
        
        
            | 
            | 
           620 | 
           void send_tree      (TState &state,ct_data *tree, int max_code);
  | 
        
        
            | 
            | 
           621 | 
           int  build_bl_tree  (TState &);
  | 
        
        
            | 
            | 
           622 | 
           void send_all_trees (TState &state,int lcodes, int dcodes, int blcodes);
  | 
        
        
            | 
            | 
           623 | 
           void compress_block (TState &state,ct_data *ltree, ct_data *dtree);
  | 
        
        
            | 
            | 
           624 | 
           void set_file_type  (TState &);
  | 
        
        
            | 
            | 
           625 | 
           void send_bits      (TState &state, int value, int length);
  | 
        
        
            | 
            | 
           626 | 
           unsigned bi_reverse (unsigned code, int len);
  | 
        
        
            | 
            | 
           627 | 
           void bi_windup      (TState &state);
  | 
        
        
            | 
            | 
           628 | 
           void copy_block     (TState &state,char *buf, unsigned len, int header);
  | 
        
        
            | 
            | 
           629 | 
              | 
        
        
            | 
            | 
           630 | 
              | 
        
        
            | 
            | 
           631 | 
           #define send_code(state, c, tree) send_bits(state, tree[c].fc.code, tree[c].dl.len)
  | 
        
        
            | 
            | 
           632 | 
           // Send a code of the given tree. c and tree must not have side effects
  | 
        
        
            | 
            | 
           633 | 
              | 
        
        
            | 
            | 
           634 | 
           // alternatively...
  | 
        
        
            | 
            | 
           635 | 
           //#define send_code(state, c, tree)
  | 
        
        
            | 
            | 
           636 | 
           //     { if (state.verbose>1) fprintf(stderr,"\ncd %3d ",(c));
  | 
        
        
            | 
            | 
           637 | 
           //       send_bits(state, tree[c].fc.code, tree[c].dl.len); }
  | 
        
        
            | 
            | 
           638 | 
              | 
        
        
            | 
            | 
           639 | 
           #define d_code(dist) ((dist) < 256 ? state.ts.dist_code[dist] : state.ts.dist_code[256+((dist)>>7)])
  | 
        
        
            | 
            | 
           640 | 
           // Mapping from a distance to a distance code. dist is the distance - 1 and
  | 
        
        
            | 
            | 
           641 | 
           // must not have side effects. dist_code[256] and dist_code[257] are never used.
  | 
        
        
            | 
            | 
           642 | 
              | 
        
        
            | 
            | 
           643 | 
           #define Max(a,b) (a >= b ? a : b)
  | 
        
        
            | 
            | 
           644 | 
           /* the arguments must not have side effects */
  | 
        
        
            | 
            | 
           645 | 
              | 
        
        
            | 
            | 
           646 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           647 | 
            * Allocate the match buffer, initialize the various tables and save the
  | 
        
        
            | 
            | 
           648 | 
            * location of the internal file attribute (ascii/binary) and method
  | 
        
        
            | 
            | 
           649 | 
            * (DEFLATE/STORE).
  | 
        
        
            | 
            | 
           650 | 
            */
  | 
        
        
            | 
            | 
           651 | 
           void ct_init(TState &state, ush *attr)
  | 
        
        
            | 
            | 
           652 | 
           {
  | 
        
        
            | 
            | 
           653 | 
               int n;        /* iterates over tree elements */
  | 
        
        
            | 
            | 
           654 | 
               int bits;     /* bit counter */
  | 
        
        
            | 
            | 
           655 | 
               int length;   /* length value */
  | 
        
        
            | 
            | 
           656 | 
               int code;     /* code value */
  | 
        
        
            | 
            | 
           657 | 
               int dist;     /* distance index */
  | 
        
        
            | 
            | 
           658 | 
              | 
        
        
            | 
            | 
           659 | 
               state.ts.file_type = attr;
  | 
        
        
            | 
            | 
           660 | 
               //state.ts.file_method = method;
  | 
        
        
            | 
            | 
           661 | 
               state.ts.cmpr_bytelen = state.ts.cmpr_len_bits = 0L;
  | 
        
        
            | 
            | 
           662 | 
               state.ts.input_len = 0L;
  | 
        
        
            | 
            | 
           663 | 
              | 
        
        
            | 
            | 
           664 | 
               if (state.ts.static_dtree[0].dl.len != 0) return; /* ct_init already called */
  | 
        
        
            | 
            | 
           665 | 
              | 
        
        
            | 
            | 
           666 | 
               /* Initialize the mapping length (0..255) -> length code (0..28) */
  | 
        
        
            | 
            | 
           667 | 
               length = 0;
  | 
        
        
            | 
            | 
           668 | 
               for (code = 0; code < LENGTH_CODES-1; code++) {
  | 
        
        
            | 
            | 
           669 | 
                   state.ts.base_length[code] = length;
  | 
        
        
            | 
            | 
           670 | 
                   for (n = 0; n < (1<<extra_lbits[code]); n++) {
  | 
        
        
            | 
            | 
           671 | 
                       state.ts.length_code[length++] = (uch)code;
  | 
        
        
            | 
            | 
           672 | 
                   }
  | 
        
        
            | 
            | 
           673 | 
               }
  | 
        
        
            | 
            | 
           674 | 
               Assert(state,length == 256, "ct_init: length != 256");
  | 
        
        
            | 
            | 
           675 | 
               /* Note that the length 255 (match length 258) can be represented
  | 
        
        
            | 
            | 
           676 | 
                * in two different ways: code 284 + 5 bits or code 285, so we
  | 
        
        
            | 
            | 
           677 | 
                * overwrite length_code[255] to use the best encoding:
  | 
        
        
            | 
            | 
           678 | 
                */
  | 
        
        
            | 
            | 
           679 | 
               state.ts.length_code[length-1] = (uch)code;
  | 
        
        
            | 
            | 
           680 | 
              | 
        
        
            | 
            | 
           681 | 
               /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
  | 
        
        
            | 
            | 
           682 | 
               dist = 0;
  | 
        
        
            | 
            | 
           683 | 
               for (code = 0 ; code < 16; code++) {
  | 
        
        
            | 
            | 
           684 | 
                   state.ts.base_dist[code] = dist;
  | 
        
        
            | 
            | 
           685 | 
                   for (n = 0; n < (1<<extra_dbits[code]); n++) {
  | 
        
        
            | 
            | 
           686 | 
                       state.ts.dist_code[dist++] = (uch)code;
  | 
        
        
            | 
            | 
           687 | 
                   }
  | 
        
        
            | 
            | 
           688 | 
               }
  | 
        
        
            | 
            | 
           689 | 
               Assert(state,dist == 256, "ct_init: dist != 256");
  | 
        
        
            | 
            | 
           690 | 
               dist >>= 7; /* from now on, all distances are divided by 128 */
  | 
        
        
            | 
            | 
           691 | 
               for ( ; code < D_CODES; code++) {
  | 
        
        
            | 
            | 
           692 | 
                   state.ts.base_dist[code] = dist << 7;
  | 
        
        
            | 
            | 
           693 | 
                   for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
  | 
        
        
            | 
            | 
           694 | 
                       state.ts.dist_code[256 + dist++] = (uch)code;
  | 
        
        
            | 
            | 
           695 | 
                   }
  | 
        
        
            | 
            | 
           696 | 
               }
  | 
        
        
            | 
            | 
           697 | 
               Assert(state,dist == 256, "ct_init: 256+dist != 512");
  | 
        
        
            | 
            | 
           698 | 
              | 
        
        
            | 
            | 
           699 | 
               /* Construct the codes of the static literal tree */
  | 
        
        
            | 
            | 
           700 | 
               for (bits = 0; bits <= MAX_BITS; bits++) state.ts.bl_count[bits] = 0;
  | 
        
        
            | 
            | 
           701 | 
               n = 0;
  | 
        
        
            | 
            | 
           702 | 
               while (n <= 143) state.ts.static_ltree[n++].dl.len = 8, state.ts.bl_count[8]++;
  | 
        
        
            | 
            | 
           703 | 
               while (n <= 255) state.ts.static_ltree[n++].dl.len = 9, state.ts.bl_count[9]++;
  | 
        
        
            | 
            | 
           704 | 
               while (n <= 279) state.ts.static_ltree[n++].dl.len = 7, state.ts.bl_count[7]++;
  | 
        
        
            | 
            | 
           705 | 
               while (n <= 287) state.ts.static_ltree[n++].dl.len = 8, state.ts.bl_count[8]++;
  | 
        
        
            | 
            | 
           706 | 
               /* fc.codes 286 and 287 do not exist, but we must include them in the
  | 
        
        
            | 
            | 
           707 | 
                * tree construction to get a canonical Huffman tree (longest code
  | 
        
        
            | 
            | 
           708 | 
                * all ones)
  | 
        
        
            | 
            | 
           709 | 
                */
  | 
        
        
            | 
            | 
           710 | 
               gen_codes(state,(ct_data *)state.ts.static_ltree, L_CODES+1);
  | 
        
        
            | 
            | 
           711 | 
              | 
        
        
            | 
            | 
           712 | 
               /* The static distance tree is trivial: */
  | 
        
        
            | 
            | 
           713 | 
               for (n = 0; n < D_CODES; n++) {
  | 
        
        
            | 
            | 
           714 | 
                   state.ts.static_dtree[n].dl.len = 5;
  | 
        
        
            | 
            | 
           715 | 
                   state.ts.static_dtree[n].fc.code = (ush)bi_reverse(n, 5);
  | 
        
        
            | 
            | 
           716 | 
               }
  | 
        
        
            | 
            | 
           717 | 
              | 
        
        
            | 
            | 
           718 | 
               /* Initialize the first block of the first file: */
  | 
        
        
            | 
            | 
           719 | 
               init_block(state);
  | 
        
        
            | 
            | 
           720 | 
           }
  | 
        
        
            | 
            | 
           721 | 
              | 
        
        
            | 
            | 
           722 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           723 | 
            * Initialize a new block.
  | 
        
        
            | 
            | 
           724 | 
            */
  | 
        
        
            | 
            | 
           725 | 
           void init_block(TState &state)
  | 
        
        
            | 
            | 
           726 | 
           {
  | 
        
        
            | 
            | 
           727 | 
               int n; /* iterates over tree elements */
  | 
        
        
            | 
            | 
           728 | 
              | 
        
        
            | 
            | 
           729 | 
               /* Initialize the trees. */
  | 
        
        
            | 
            | 
           730 | 
               for (n = 0; n < L_CODES;  n++) state.ts.dyn_ltree[n].fc.freq = 0;
  | 
        
        
            | 
            | 
           731 | 
               for (n = 0; n < D_CODES;  n++) state.ts.dyn_dtree[n].fc.freq = 0;
  | 
        
        
            | 
            | 
           732 | 
               for (n = 0; n < BL_CODES; n++) state.ts.bl_tree[n].fc.freq = 0;
  | 
        
        
            | 
            | 
           733 | 
              | 
        
        
            | 
            | 
           734 | 
               state.ts.dyn_ltree[END_BLOCK].fc.freq = 1;
  | 
        
        
            | 
            | 
           735 | 
               state.ts.opt_len = state.ts.static_len = 0L;
  | 
        
        
            | 
            | 
           736 | 
               state.ts.last_lit = state.ts.last_dist = state.ts.last_flags = 0;
  | 
        
        
            | 
            | 
           737 | 
               state.ts.flags = 0; state.ts.flag_bit = 1;
  | 
        
        
            | 
            | 
           738 | 
           }
  | 
        
        
            | 
            | 
           739 | 
              | 
        
        
            | 
            | 
           740 | 
           #define SMALLEST 1
  | 
        
        
            | 
            | 
           741 | 
           /* Index within the heap array of least frequent node in the Huffman tree */
  | 
        
        
            | 
            | 
           742 | 
              | 
        
        
            | 
            | 
           743 | 
              | 
        
        
            | 
            | 
           744 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           745 | 
            * Remove the smallest element from the heap and recreate the heap with
  | 
        
        
            | 
            | 
           746 | 
            * one less element. Updates heap and heap_len.
  | 
        
        
            | 
            | 
           747 | 
            */
  | 
        
        
            | 
            | 
           748 | 
           #define pqremove(tree, top) \
  | 
        
        
            | 
            | 
           749 | 
           {\
  | 
        
        
            | 
            | 
           750 | 
               top = state.ts.heap[SMALLEST]; \
  | 
        
        
            | 
            | 
           751 | 
               state.ts.heap[SMALLEST] = state.ts.heap[state.ts.heap_len--]; \
  | 
        
        
            | 
            | 
           752 | 
               pqdownheap(state,tree, SMALLEST); \
  | 
        
        
            | 
            | 
           753 | 
           }
  | 
        
        
            | 
            | 
           754 | 
              | 
        
        
            | 
            | 
           755 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           756 | 
            * Compares to subtrees, using the tree depth as tie breaker when
  | 
        
        
            | 
            | 
           757 | 
            * the subtrees have equal frequency. This minimizes the worst case length.
  | 
        
        
            | 
            | 
           758 | 
            */
  | 
        
        
            | 
            | 
           759 | 
           #define smaller(tree, n, m) \
  | 
        
        
            | 
            | 
           760 | 
              (tree[n].fc.freq < tree[m].fc.freq || \
  | 
        
        
            | 
            | 
           761 | 
              (tree[n].fc.freq == tree[m].fc.freq && state.ts.depth[n] <= state.ts.depth[m]))
  | 
        
        
            | 
            | 
           762 | 
              | 
        
        
            | 
            | 
           763 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           764 | 
            * Restore the heap property by moving down the tree starting at node k,
  | 
        
        
            | 
            | 
           765 | 
            * exchanging a node with the smallest of its two sons if necessary, stopping
  | 
        
        
            | 
            | 
           766 | 
            * when the heap property is re-established (each father smaller than its
  | 
        
        
            | 
            | 
           767 | 
            * two sons).
  | 
        
        
            | 
            | 
           768 | 
            */
  | 
        
        
            | 
            | 
           769 | 
           void pqdownheap(TState &state,ct_data *tree, int k)
  | 
        
        
            | 
            | 
           770 | 
           {
  | 
        
        
            | 
            | 
           771 | 
               int v = state.ts.heap[k];
  | 
        
        
            | 
            | 
           772 | 
               int j = k << 1;  /* left son of k */
  | 
        
        
            | 
            | 
           773 | 
               int htemp;       /* required because of bug in SASC compiler */
  | 
        
        
            | 
            | 
           774 | 
              | 
        
        
            | 
            | 
           775 | 
               while (j <= state.ts.heap_len) {
  | 
        
        
            | 
            | 
           776 | 
                   /* Set j to the smallest of the two sons: */
  | 
        
        
            | 
            | 
           777 | 
                   if (j < state.ts.heap_len && smaller(tree, state.ts.heap[j+1], state.ts.heap[j])) j++;
  | 
        
        
            | 
            | 
           778 | 
              | 
        
        
            | 
            | 
           779 | 
                   /* Exit if v is smaller than both sons */
  | 
        
        
            | 
            | 
           780 | 
                   htemp = state.ts.heap[j];
  | 
        
        
            | 
            | 
           781 | 
                   if (smaller(tree, v, htemp)) break;
  | 
        
        
            | 
            | 
           782 | 
              | 
        
        
            | 
            | 
           783 | 
                   /* Exchange v with the smallest son */
  | 
        
        
            | 
            | 
           784 | 
                   state.ts.heap[k] = htemp;
  | 
        
        
            | 
            | 
           785 | 
                   k = j;
  | 
        
        
            | 
            | 
           786 | 
              | 
        
        
            | 
            | 
           787 | 
                   /* And continue down the tree, setting j to the left son of k */
  | 
        
        
            | 
            | 
           788 | 
                   j <<= 1;
  | 
        
        
            | 
            | 
           789 | 
               }
  | 
        
        
            | 
            | 
           790 | 
               state.ts.heap[k] = v;
  | 
        
        
            | 
            | 
           791 | 
           }
  | 
        
        
            | 
            | 
           792 | 
              | 
        
        
            | 
            | 
           793 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           794 | 
            * Compute the optimal bit lengths for a tree and update the total bit length
  | 
        
        
            | 
            | 
           795 | 
            * for the current block.
  | 
        
        
            | 
            | 
           796 | 
            * IN assertion: the fields freq and dad are set, heap[heap_max] and
  | 
        
        
            | 
            | 
           797 | 
            *    above are the tree nodes sorted by increasing frequency.
  | 
        
        
            | 
            | 
           798 | 
            * OUT assertions: the field len is set to the optimal bit length, the
  | 
        
        
            | 
            | 
           799 | 
            *     array bl_count contains the frequencies for each bit length.
  | 
        
        
            | 
            | 
           800 | 
            *     The length opt_len is updated; static_len is also updated if stree is
  | 
        
        
            | 
            | 
           801 | 
            *     not null.
  | 
        
        
            | 
            | 
           802 | 
            */
  | 
        
        
            | 
            | 
           803 | 
           void gen_bitlen(TState &state,tree_desc *desc)
  | 
        
        
            | 
            | 
           804 | 
           {
  | 
        
        
            | 
            | 
           805 | 
               ct_data *tree  = desc->dyn_tree;
  | 
        
        
            | 
            | 
           806 | 
               const int *extra     = desc->extra_bits;
  | 
        
        
            | 
            | 
           807 | 
               int base            = desc->extra_base;
  | 
        
        
            | 
            | 
           808 | 
               int max_code        = desc->max_code;
  | 
        
        
            | 
            | 
           809 | 
               int max_length      = desc->max_length;
  | 
        
        
            | 
            | 
           810 | 
               ct_data *stree = desc->static_tree;
  | 
        
        
            | 
            | 
           811 | 
               int h;              /* heap index */
  | 
        
        
            | 
            | 
           812 | 
               int n, m;           /* iterate over the tree elements */
  | 
        
        
            | 
            | 
           813 | 
               int bits;           /* bit length */
  | 
        
        
            | 
            | 
           814 | 
               int xbits;          /* extra bits */
  | 
        
        
            | 
            | 
           815 | 
               ush f;              /* frequency */
  | 
        
        
            | 
            | 
           816 | 
               int overflow = 0;   /* number of elements with bit length too large */
  | 
        
        
            | 
            | 
           817 | 
              | 
        
        
            | 
            | 
           818 | 
               for (bits = 0; bits <= MAX_BITS; bits++) state.ts.bl_count[bits] = 0;
  | 
        
        
            | 
            | 
           819 | 
              | 
        
        
            | 
            | 
           820 | 
               /* In a first pass, compute the optimal bit lengths (which may
  | 
        
        
            | 
            | 
           821 | 
                * overflow in the case of the bit length tree).
  | 
        
        
            | 
            | 
           822 | 
                */
  | 
        
        
            | 
            | 
           823 | 
               tree[state.ts.heap[state.ts.heap_max]].dl.len = 0; /* root of the heap */
  | 
        
        
            | 
            | 
           824 | 
              | 
        
        
            | 
            | 
           825 | 
               for (h = state.ts.heap_max+1; h < HEAP_SIZE; h++) {
  | 
        
        
            | 
            | 
           826 | 
                   n = state.ts.heap[h];
  | 
        
        
            | 
            | 
           827 | 
                   bits = tree[tree[n].dl.dad].dl.len + 1;
  | 
        
        
            | 
            | 
           828 | 
                   if (bits > max_length) bits = max_length, overflow++;
  | 
        
        
            | 
            | 
           829 | 
                   tree[n].dl.len = (ush)bits;
  | 
        
        
            | 
            | 
           830 | 
                   /* We overwrite tree[n].dl.dad which is no longer needed */
  | 
        
        
            | 
            | 
           831 | 
              | 
        
        
            | 
            | 
           832 | 
                   if (n > max_code) continue; /* not a leaf node */
  | 
        
        
            | 
            | 
           833 | 
              | 
        
        
            | 
            | 
           834 | 
                   state.ts.bl_count[bits]++;
  | 
        
        
            | 
            | 
           835 | 
                   xbits = 0;
  | 
        
        
            | 
            | 
           836 | 
                   if (n >= base) xbits = extra[n-base];
  | 
        
        
            | 
            | 
           837 | 
                   f = tree[n].fc.freq;
  | 
        
        
            | 
            | 
           838 | 
                   state.ts.opt_len += (ulg)f * (bits + xbits);
  | 
        
        
            | 
            | 
           839 | 
                   if (stree) state.ts.static_len += (ulg)f * (stree[n].dl.len + xbits);
  | 
        
        
            | 
            | 
           840 | 
               }
  | 
        
        
            | 
            | 
           841 | 
               if (overflow == 0) return;
  | 
        
        
            | 
            | 
           842 | 
              | 
        
        
            | 
            | 
           843 | 
               Trace("\nbit length overflow\n");
  | 
        
        
            | 
            | 
           844 | 
               /* This happens for example on obj2 and pic of the Calgary corpus */
  | 
        
        
            | 
            | 
           845 | 
              | 
        
        
            | 
            | 
           846 | 
               /* Find the first bit length which could increase: */
  | 
        
        
            | 
            | 
           847 | 
               do {
  | 
        
        
            | 
            | 
           848 | 
                   bits = max_length-1;
  | 
        
        
            | 
            | 
           849 | 
                   while (state.ts.bl_count[bits] == 0) bits--;
  | 
        
        
            | 
            | 
           850 | 
                   state.ts.bl_count[bits]--;           /* move one leaf down the tree */
  | 
        
        
            | 
            | 
           851 | 
                   state.ts.bl_count[bits+1] += (ush)2; /* move one overflow item as its brother */
  | 
        
        
            | 
            | 
           852 | 
                   state.ts.bl_count[max_length]--;
  | 
        
        
            | 
            | 
           853 | 
                   /* The brother of the overflow item also moves one step up,
  | 
        
        
            | 
            | 
           854 | 
                    * but this does not affect bl_count[max_length]
  | 
        
        
            | 
            | 
           855 | 
                    */
  | 
        
        
            | 
            | 
           856 | 
                   overflow -= 2;
  | 
        
        
            | 
            | 
           857 | 
               } while (overflow > 0);
  | 
        
        
            | 
            | 
           858 | 
              | 
        
        
            | 
            | 
           859 | 
               /* Now recompute all bit lengths, scanning in increasing frequency.
  | 
        
        
            | 
            | 
           860 | 
                * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
  | 
        
        
            | 
            | 
           861 | 
                * lengths instead of fixing only the wrong ones. This idea is taken
  | 
        
        
            | 
            | 
           862 | 
                * from 'ar' written by Haruhiko Okumura.)
  | 
        
        
            | 
            | 
           863 | 
                */
  | 
        
        
            | 
            | 
           864 | 
               for (bits = max_length; bits != 0; bits--) {
  | 
        
        
            | 
            | 
           865 | 
                   n = state.ts.bl_count[bits];
  | 
        
        
            | 
            | 
           866 | 
                   while (n != 0) {
  | 
        
        
            | 
            | 
           867 | 
                       m = state.ts.heap[--h];
  | 
        
        
            | 
            | 
           868 | 
                       if (m > max_code) continue;
  | 
        
        
            | 
            | 
           869 | 
                       if (tree[m].dl.len != (ush)bits) {
  | 
        
        
            | 
            | 
           870 | 
                           Trace("code %d bits %d->%d\n", m, tree[m].dl.len, bits);
  | 
        
        
            | 
            | 
           871 | 
                           state.ts.opt_len += ((long)bits-(long)tree[m].dl.len)*(long)tree[m].fc.freq;
  | 
        
        
            | 
            | 
           872 | 
                           tree[m].dl.len = (ush)bits;
  | 
        
        
            | 
            | 
           873 | 
                       }
  | 
        
        
            | 
            | 
           874 | 
                       n--;
  | 
        
        
            | 
            | 
           875 | 
                   }
  | 
        
        
            | 
            | 
           876 | 
               }
  | 
        
        
            | 
            | 
           877 | 
           }
  | 
        
        
            | 
            | 
           878 | 
              | 
        
        
            | 
            | 
           879 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           880 | 
            * Generate the codes for a given tree and bit counts (which need not be
  | 
        
        
            | 
            | 
           881 | 
            * optimal).
  | 
        
        
            | 
            | 
           882 | 
            * IN assertion: the array bl_count contains the bit length statistics for
  | 
        
        
            | 
            | 
           883 | 
            * the given tree and the field len is set for all tree elements.
  | 
        
        
            | 
            | 
           884 | 
            * OUT assertion: the field code is set for all tree elements of non
  | 
        
        
            | 
            | 
           885 | 
            *     zero code length.
  | 
        
        
            | 
            | 
           886 | 
            */
  | 
        
        
            | 
            | 
           887 | 
           void gen_codes (TState &state, ct_data *tree, int max_code)
  | 
        
        
            | 
            | 
           888 | 
           {
  | 
        
        
            | 
            | 
           889 | 
               ush next_code[MAX_BITS+1]; /* next code value for each bit length */
  | 
        
        
            | 
            | 
           890 | 
               ush code = 0;              /* running code value */
  | 
        
        
            | 
            | 
           891 | 
               int bits;                  /* bit index */
  | 
        
        
            | 
            | 
           892 | 
               int n;                     /* code index */
  | 
        
        
            | 
            | 
           893 | 
              | 
        
        
            | 
            | 
           894 | 
               /* The distribution counts are first used to generate the code values
  | 
        
        
            | 
            | 
           895 | 
                * without bit reversal.
  | 
        
        
            | 
            | 
           896 | 
                */
  | 
        
        
            | 
            | 
           897 | 
               for (bits = 1; bits <= MAX_BITS; bits++) {
  | 
        
        
            | 
            | 
           898 | 
                   next_code[bits] = code = (ush)((code + state.ts.bl_count[bits-1]) << 1);
  | 
        
        
            | 
            | 
           899 | 
               }
  | 
        
        
            | 
            | 
           900 | 
               /* Check that the bit counts in bl_count are consistent. The last code
  | 
        
        
            | 
            | 
           901 | 
                * must be all ones.
  | 
        
        
            | 
            | 
           902 | 
                */
  | 
        
        
            | 
            | 
           903 | 
               Assert(state,code + state.ts.bl_count[MAX_BITS]-1 == (1<< ((ush) MAX_BITS)) - 1,
  | 
        
        
            | 
            | 
           904 | 
                       "inconsistent bit counts");
  | 
        
        
            | 
            | 
           905 | 
               Trace("\ngen_codes: max_code %d ", max_code);
  | 
        
        
            | 
            | 
           906 | 
              | 
        
        
            | 
            | 
           907 | 
               for (n = 0;  n <= max_code; n++) {
  | 
        
        
            | 
            | 
           908 | 
                   int len = tree[n].dl.len;
  | 
        
        
            | 
            | 
           909 | 
                   if (len == 0) continue;
  | 
        
        
            | 
            | 
           910 | 
                   /* Now reverse the bits */
  | 
        
        
            | 
            | 
           911 | 
                   tree[n].fc.code = (ush)bi_reverse(next_code[len]++, len);
  | 
        
        
            | 
            | 
           912 | 
              | 
        
        
            | 
            | 
           913 | 
                   //Tracec(tree != state.ts.static_ltree, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].fc.code, next_code[len]-1);
  | 
        
        
            | 
            | 
           914 | 
               }
  | 
        
        
            | 
            | 
           915 | 
           }
  | 
        
        
            | 
            | 
           916 | 
              | 
        
        
            | 
            | 
           917 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           918 | 
            * Construct one Huffman tree and assigns the code bit strings and lengths.
  | 
        
        
            | 
            | 
           919 | 
            * Update the total bit length for the current block.
  | 
        
        
            | 
            | 
           920 | 
            * IN assertion: the field freq is set for all tree elements.
  | 
        
        
            | 
            | 
           921 | 
            * OUT assertions: the fields len and code are set to the optimal bit length
  | 
        
        
            | 
            | 
           922 | 
            *     and corresponding code. The length opt_len is updated; static_len is
  | 
        
        
            | 
            | 
           923 | 
            *     also updated if stree is not null. The field max_code is set.
  | 
        
        
            | 
            | 
           924 | 
            */
  | 
        
        
            | 
            | 
           925 | 
           void build_tree(TState &state,tree_desc *desc)
  | 
        
        
            | 
            | 
           926 | 
           {
  | 
        
        
            | 
            | 
           927 | 
               ct_data *tree   = desc->dyn_tree;
  | 
        
        
            | 
            | 
           928 | 
               ct_data *stree  = desc->static_tree;
  | 
        
        
            | 
            | 
           929 | 
               int elems            = desc->elems;
  | 
        
        
            | 
            | 
           930 | 
               int n, m;          /* iterate over heap elements */
  | 
        
        
            | 
            | 
           931 | 
               int max_code = -1; /* largest code with non zero frequency */
  | 
        
        
            | 
            | 
           932 | 
               int node = elems;  /* next internal node of the tree */
  | 
        
        
            | 
            | 
           933 | 
              | 
        
        
            | 
            | 
           934 | 
               /* Construct the initial heap, with least frequent element in
  | 
        
        
            | 
            | 
           935 | 
                * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
  | 
        
        
            | 
            | 
           936 | 
                * heap[0] is not used.
  | 
        
        
            | 
            | 
           937 | 
                */
  | 
        
        
            | 
            | 
           938 | 
               state.ts.heap_len = 0, state.ts.heap_max = HEAP_SIZE;
  | 
        
        
            | 
            | 
           939 | 
              | 
        
        
            | 
            | 
           940 | 
               for (n = 0; n < elems; n++) {
  | 
        
        
            | 
            | 
           941 | 
                   if (tree[n].fc.freq != 0) {
  | 
        
        
            | 
            | 
           942 | 
                       state.ts.heap[++state.ts.heap_len] = max_code = n;
  | 
        
        
            | 
            | 
           943 | 
                       state.ts.depth[n] = 0;
  | 
        
        
            | 
            | 
           944 | 
                   } else {
  | 
        
        
            | 
            | 
           945 | 
                       tree[n].dl.len = 0;
  | 
        
        
            | 
            | 
           946 | 
                   }
  | 
        
        
            | 
            | 
           947 | 
               }
  | 
        
        
            | 
            | 
           948 | 
              | 
        
        
            | 
            | 
           949 | 
               /* The pkzip format requires that at least one distance code exists,
  | 
        
        
            | 
            | 
           950 | 
                * and that at least one bit should be sent even if there is only one
  | 
        
        
            | 
            | 
           951 | 
                * possible code. So to avoid special checks later on we force at least
  | 
        
        
            | 
            | 
           952 | 
                * two codes of non zero frequency.
  | 
        
        
            | 
            | 
           953 | 
                */
  | 
        
        
            | 
            | 
           954 | 
               while (state.ts.heap_len < 2) {
  | 
        
        
            | 
            | 
           955 | 
                   int newcp = state.ts.heap[++state.ts.heap_len] = (max_code < 2 ? ++max_code : 0);
  | 
        
        
            | 
            | 
           956 | 
                   tree[newcp].fc.freq = 1;
  | 
        
        
            | 
            | 
           957 | 
                   state.ts.depth[newcp] = 0;
  | 
        
        
            | 
            | 
           958 | 
                   state.ts.opt_len--; if (stree) state.ts.static_len -= stree[newcp].dl.len;
  | 
        
        
            | 
            | 
           959 | 
                   /* new is 0 or 1 so it does not have extra bits */
  | 
        
        
            | 
            | 
           960 | 
               }
  | 
        
        
            | 
            | 
           961 | 
               desc->max_code = max_code;
  | 
        
        
            | 
            | 
           962 | 
              | 
        
        
            | 
            | 
           963 | 
               /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
  | 
        
        
            | 
            | 
           964 | 
                * establish sub-heaps of increasing lengths:
  | 
        
        
            | 
            | 
           965 | 
                */
  | 
        
        
            | 
            | 
           966 | 
               for (n = state.ts.heap_len/2; n >= 1; n--) pqdownheap(state,tree, n);
  | 
        
        
            | 
            | 
           967 | 
              | 
        
        
            | 
            | 
           968 | 
               /* Construct the Huffman tree by repeatedly combining the least two
  | 
        
        
            | 
            | 
           969 | 
                * frequent nodes.
  | 
        
        
            | 
            | 
           970 | 
                */
  | 
        
        
            | 
            | 
           971 | 
               do {
  | 
        
        
            | 
            | 
           972 | 
                   pqremove(tree, n);   /* n = node of least frequency */
  | 
        
        
            | 
            | 
           973 | 
                   m = state.ts.heap[SMALLEST];  /* m = node of next least frequency */
  | 
        
        
            | 
            | 
           974 | 
              | 
        
        
            | 
            | 
           975 | 
                   state.ts.heap[--state.ts.heap_max] = n; /* keep the nodes sorted by frequency */
  | 
        
        
            | 
            | 
           976 | 
                   state.ts.heap[--state.ts.heap_max] = m;
  | 
        
        
            | 
            | 
           977 | 
              | 
        
        
            | 
            | 
           978 | 
                   /* Create a new node father of n and m */
  | 
        
        
            | 
            | 
           979 | 
                   tree[node].fc.freq = (ush)(tree[n].fc.freq + tree[m].fc.freq);
  | 
        
        
            | 
            | 
           980 | 
                   state.ts.depth[node] = (uch) (Max(state.ts.depth[n], state.ts.depth[m]) + 1);
  | 
        
        
            | 
            | 
           981 | 
                   tree[n].dl.dad = tree[m].dl.dad = (ush)node;
  | 
        
        
            | 
            | 
           982 | 
                   /* and insert the new node in the heap */
  | 
        
        
            | 
            | 
           983 | 
                   state.ts.heap[SMALLEST] = node++;
  | 
        
        
            | 
            | 
           984 | 
                   pqdownheap(state,tree, SMALLEST);
  | 
        
        
            | 
            | 
           985 | 
              | 
        
        
            | 
            | 
           986 | 
               } while (state.ts.heap_len >= 2);
  | 
        
        
            | 
            | 
           987 | 
              | 
        
        
            | 
            | 
           988 | 
               state.ts.heap[--state.ts.heap_max] = state.ts.heap[SMALLEST];
  | 
        
        
            | 
            | 
           989 | 
              | 
        
        
            | 
            | 
           990 | 
               /* At this point, the fields freq and dad are set. We can now
  | 
        
        
            | 
            | 
           991 | 
                * generate the bit lengths.
  | 
        
        
            | 
            | 
           992 | 
                */
  | 
        
        
            | 
            | 
           993 | 
               gen_bitlen(state,(tree_desc *)desc);
  | 
        
        
            | 
            | 
           994 | 
              | 
        
        
            | 
            | 
           995 | 
               /* The field len is now set, we can generate the bit codes */
  | 
        
        
            | 
            | 
           996 | 
               gen_codes (state,(ct_data *)tree, max_code);
  | 
        
        
            | 
            | 
           997 | 
           }
  | 
        
        
            | 
            | 
           998 | 
              | 
        
        
            | 
            | 
           999 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1000 | 
            * Scan a literal or distance tree to determine the frequencies of the codes
  | 
        
        
            | 
            | 
           1001 | 
            * in the bit length tree. Updates opt_len to take into account the repeat
  | 
        
        
            | 
            | 
           1002 | 
            * counts. (The contribution of the bit length codes will be added later
  | 
        
        
            | 
            | 
           1003 | 
            * during the construction of bl_tree.)
  | 
        
        
            | 
            | 
           1004 | 
            */
  | 
        
        
            | 
            | 
           1005 | 
           void scan_tree (TState &state,ct_data *tree, int max_code)
  | 
        
        
            | 
            | 
           1006 | 
           {
  | 
        
        
            | 
            | 
           1007 | 
               int n;                     /* iterates over all tree elements */
  | 
        
        
            | 
            | 
           1008 | 
               int prevlen = -1;          /* last emitted length */
  | 
        
        
            | 
            | 
           1009 | 
               int curlen;                /* length of current code */
  | 
        
        
            | 
            | 
           1010 | 
               int nextlen = tree[0].dl.len; /* length of next code */
  | 
        
        
            | 
            | 
           1011 | 
               int count = 0;             /* repeat count of the current code */
  | 
        
        
            | 
            | 
           1012 | 
               int max_count = 7;         /* max repeat count */
  | 
        
        
            | 
            | 
           1013 | 
               int min_count = 4;         /* min repeat count */
  | 
        
        
            | 
            | 
           1014 | 
              | 
        
        
            | 
            | 
           1015 | 
               if (nextlen == 0) max_count = 138, min_count = 3;
  | 
        
        
            | 
            | 
           1016 | 
               tree[max_code+1].dl.len = (ush)-1; /* guard */
  | 
        
        
            | 
            | 
           1017 | 
              | 
        
        
            | 
            | 
           1018 | 
               for (n = 0; n <= max_code; n++) {
  | 
        
        
            | 
            | 
           1019 | 
                   curlen = nextlen; nextlen = tree[n+1].dl.len;
  | 
        
        
            | 
            | 
           1020 | 
                   if (++count < max_count && curlen == nextlen) {
  | 
        
        
            | 
            | 
           1021 | 
                       continue;
  | 
        
        
            | 
            | 
           1022 | 
                   } else if (count < min_count) {
  | 
        
        
            | 
            | 
           1023 | 
                       state.ts.bl_tree[curlen].fc.freq = (ush)(state.ts.bl_tree[curlen].fc.freq + count);
  | 
        
        
            | 
            | 
           1024 | 
                   } else if (curlen != 0) {
  | 
        
        
            | 
            | 
           1025 | 
                       if (curlen != prevlen) state.ts.bl_tree[curlen].fc.freq++;
  | 
        
        
            | 
            | 
           1026 | 
                       state.ts.bl_tree[REP_3_6].fc.freq++;
  | 
        
        
            | 
            | 
           1027 | 
                   } else if (count <= 10) {
  | 
        
        
            | 
            | 
           1028 | 
                       state.ts.bl_tree[REPZ_3_10].fc.freq++;
  | 
        
        
            | 
            | 
           1029 | 
                   } else {
  | 
        
        
            | 
            | 
           1030 | 
                       state.ts.bl_tree[REPZ_11_138].fc.freq++;
  | 
        
        
            | 
            | 
           1031 | 
                   }
  | 
        
        
            | 
            | 
           1032 | 
                   count = 0; prevlen = curlen;
  | 
        
        
            | 
            | 
           1033 | 
                   if (nextlen == 0) {
  | 
        
        
            | 
            | 
           1034 | 
                       max_count = 138, min_count = 3;
  | 
        
        
            | 
            | 
           1035 | 
                   } else if (curlen == nextlen) {
  | 
        
        
            | 
            | 
           1036 | 
                       max_count = 6, min_count = 3;
  | 
        
        
            | 
            | 
           1037 | 
                   } else {
  | 
        
        
            | 
            | 
           1038 | 
                       max_count = 7, min_count = 4;
  | 
        
        
            | 
            | 
           1039 | 
                   }
  | 
        
        
            | 
            | 
           1040 | 
               }
  | 
        
        
            | 
            | 
           1041 | 
           }
  | 
        
        
            | 
            | 
           1042 | 
              | 
        
        
            | 
            | 
           1043 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1044 | 
            * Send a literal or distance tree in compressed form, using the codes in
  | 
        
        
            | 
            | 
           1045 | 
            * bl_tree.
  | 
        
        
            | 
            | 
           1046 | 
            */
  | 
        
        
            | 
            | 
           1047 | 
           void send_tree (TState &state, ct_data *tree, int max_code)
  | 
        
        
            | 
            | 
           1048 | 
           {
  | 
        
        
            | 
            | 
           1049 | 
               int n;                     /* iterates over all tree elements */
  | 
        
        
            | 
            | 
           1050 | 
               int prevlen = -1;          /* last emitted length */
  | 
        
        
            | 
            | 
           1051 | 
               int curlen;                /* length of current code */
  | 
        
        
            | 
            | 
           1052 | 
               int nextlen = tree[0].dl.len; /* length of next code */
  | 
        
        
            | 
            | 
           1053 | 
               int count = 0;             /* repeat count of the current code */
  | 
        
        
            | 
            | 
           1054 | 
               int max_count = 7;         /* max repeat count */
  | 
        
        
            | 
            | 
           1055 | 
               int min_count = 4;         /* min repeat count */
  | 
        
        
            | 
            | 
           1056 | 
              | 
        
        
            | 
            | 
           1057 | 
               /* tree[max_code+1].dl.len = -1; */  /* guard already set */
  | 
        
        
            | 
            | 
           1058 | 
               if (nextlen == 0) max_count = 138, min_count = 3;
  | 
        
        
            | 
            | 
           1059 | 
              | 
        
        
            | 
            | 
           1060 | 
               for (n = 0; n <= max_code; n++) {
  | 
        
        
            | 
            | 
           1061 | 
                   curlen = nextlen; nextlen = tree[n+1].dl.len;
  | 
        
        
            | 
            | 
           1062 | 
                   if (++count < max_count && curlen == nextlen) {
  | 
        
        
            | 
            | 
           1063 | 
                       continue;
  | 
        
        
            | 
            | 
           1064 | 
                   } else if (count < min_count) {
  | 
        
        
            | 
            | 
           1065 | 
                       do { send_code(state, curlen, state.ts.bl_tree); } while (--count != 0);
  | 
        
        
            | 
            | 
           1066 | 
              | 
        
        
            | 
            | 
           1067 | 
                   } else if (curlen != 0) {
  | 
        
        
            | 
            | 
           1068 | 
                       if (curlen != prevlen) {
  | 
        
        
            | 
            | 
           1069 | 
                           send_code(state, curlen, state.ts.bl_tree); count--;
  | 
        
        
            | 
            | 
           1070 | 
                       }
  | 
        
        
            | 
            | 
           1071 | 
                       Assert(state,count >= 3 && count <= 6, " 3_6?");
  | 
        
        
            | 
            | 
           1072 | 
                       send_code(state,REP_3_6, state.ts.bl_tree); send_bits(state,count-3, 2);
  | 
        
        
            | 
            | 
           1073 | 
              | 
        
        
            | 
            | 
           1074 | 
                   } else if (count <= 10) {
  | 
        
        
            | 
            | 
           1075 | 
                       send_code(state,REPZ_3_10, state.ts.bl_tree); send_bits(state,count-3, 3);
  | 
        
        
            | 
            | 
           1076 | 
              | 
        
        
            | 
            | 
           1077 | 
                   } else {
  | 
        
        
            | 
            | 
           1078 | 
                       send_code(state,REPZ_11_138, state.ts.bl_tree); send_bits(state,count-11, 7);
  | 
        
        
            | 
            | 
           1079 | 
                   }
  | 
        
        
            | 
            | 
           1080 | 
                   count = 0; prevlen = curlen;
  | 
        
        
            | 
            | 
           1081 | 
                   if (nextlen == 0) {
  | 
        
        
            | 
            | 
           1082 | 
                       max_count = 138, min_count = 3;
  | 
        
        
            | 
            | 
           1083 | 
                   } else if (curlen == nextlen) {
  | 
        
        
            | 
            | 
           1084 | 
                       max_count = 6, min_count = 3;
  | 
        
        
            | 
            | 
           1085 | 
                   } else {
  | 
        
        
            | 
            | 
           1086 | 
                       max_count = 7, min_count = 4;
  | 
        
        
            | 
            | 
           1087 | 
                   }
  | 
        
        
            | 
            | 
           1088 | 
               }
  | 
        
        
            | 
            | 
           1089 | 
           }
  | 
        
        
            | 
            | 
           1090 | 
              | 
        
        
            | 
            | 
           1091 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1092 | 
            * Construct the Huffman tree for the bit lengths and return the index in
  | 
        
        
            | 
            | 
           1093 | 
            * bl_order of the last bit length code to send.
  | 
        
        
            | 
            | 
           1094 | 
            */
  | 
        
        
            | 
            | 
           1095 | 
           int build_bl_tree(TState &state)
  | 
        
        
            | 
            | 
           1096 | 
           {
  | 
        
        
            | 
            | 
           1097 | 
               int max_blindex;  /* index of last bit length code of non zero freq */
  | 
        
        
            | 
            | 
           1098 | 
              | 
        
        
            | 
            | 
           1099 | 
               /* Determine the bit length frequencies for literal and distance trees */
  | 
        
        
            | 
            | 
           1100 | 
               scan_tree(state,(ct_data *)state.ts.dyn_ltree, state.ts.l_desc.max_code);
  | 
        
        
            | 
            | 
           1101 | 
               scan_tree(state,(ct_data *)state.ts.dyn_dtree, state.ts.d_desc.max_code);
  | 
        
        
            | 
            | 
           1102 | 
              | 
        
        
            | 
            | 
           1103 | 
               /* Build the bit length tree: */
  | 
        
        
            | 
            | 
           1104 | 
               build_tree(state,(tree_desc *)(&state.ts.bl_desc));
  | 
        
        
            | 
            | 
           1105 | 
               /* opt_len now includes the length of the tree representations, except
  | 
        
        
            | 
            | 
           1106 | 
                * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
  | 
        
        
            | 
            | 
           1107 | 
                */
  | 
        
        
            | 
            | 
           1108 | 
              | 
        
        
            | 
            | 
           1109 | 
               /* Determine the number of bit length codes to send. The pkzip format
  | 
        
        
            | 
            | 
           1110 | 
                * requires that at least 4 bit length codes be sent. (appnote.txt says
  | 
        
        
            | 
            | 
           1111 | 
                * 3 but the actual value used is 4.)
  | 
        
        
            | 
            | 
           1112 | 
                */
  | 
        
        
            | 
            | 
           1113 | 
               for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
  | 
        
        
            | 
            | 
           1114 | 
                   if (state.ts.bl_tree[bl_order[max_blindex]].dl.len != 0) break;
  | 
        
        
            | 
            | 
           1115 | 
               }
  | 
        
        
            | 
            | 
           1116 | 
               /* Update opt_len to include the bit length tree and counts */
  | 
        
        
            | 
            | 
           1117 | 
               state.ts.opt_len += 3*(max_blindex+1) + 5+5+4;
  | 
        
        
            | 
            | 
           1118 | 
               Trace("\ndyn trees: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len);
  | 
        
        
            | 
            | 
           1119 | 
              | 
        
        
            | 
            | 
           1120 | 
               return max_blindex;
  | 
        
        
            | 
            | 
           1121 | 
           }
  | 
        
        
            | 
            | 
           1122 | 
              | 
        
        
            | 
            | 
           1123 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1124 | 
            * Send the header for a block using dynamic Huffman trees: the counts, the
  | 
        
        
            | 
            | 
           1125 | 
            * lengths of the bit length codes, the literal tree and the distance tree.
  | 
        
        
            | 
            | 
           1126 | 
            * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
  | 
        
        
            | 
            | 
           1127 | 
            */
  | 
        
        
            | 
            | 
           1128 | 
           void send_all_trees(TState &state,int lcodes, int dcodes, int blcodes)
  | 
        
        
            | 
            | 
           1129 | 
           {
  | 
        
        
            | 
            | 
           1130 | 
               int rank;                    /* index in bl_order */
  | 
        
        
            | 
            | 
           1131 | 
              | 
        
        
            | 
            | 
           1132 | 
               Assert(state,lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
  | 
        
        
            | 
            | 
           1133 | 
               Assert(state,lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
  | 
        
        
            | 
            | 
           1134 | 
                       "too many codes");
  | 
        
        
            | 
            | 
           1135 | 
               Trace("\nbl counts: ");
  | 
        
        
            | 
            | 
           1136 | 
               send_bits(state,lcodes-257, 5);
  | 
        
        
            | 
            | 
           1137 | 
               /* not +255 as stated in appnote.txt 1.93a or -256 in 2.04c */
  | 
        
        
            | 
            | 
           1138 | 
               send_bits(state,dcodes-1,   5);
  | 
        
        
            | 
            | 
           1139 | 
               send_bits(state,blcodes-4,  4); /* not -3 as stated in appnote.txt */
  | 
        
        
            | 
            | 
           1140 | 
               for (rank = 0; rank < blcodes; rank++) {
  | 
        
        
            | 
            | 
           1141 | 
                   Trace("\nbl code %2d ", bl_order[rank]);
  | 
        
        
            | 
            | 
           1142 | 
                   send_bits(state,state.ts.bl_tree[bl_order[rank]].dl.len, 3);
  | 
        
        
            | 
            | 
           1143 | 
               }    
  | 
        
        
            | 
            | 
           1144 | 
               Trace("\nbl tree: sent %ld", state.bs.bits_sent);
  | 
        
        
            | 
            | 
           1145 | 
              | 
        
        
            | 
            | 
           1146 | 
               send_tree(state,(ct_data *)state.ts.dyn_ltree, lcodes-1); /* send the literal tree */
  | 
        
        
            | 
            | 
           1147 | 
               Trace("\nlit tree: sent %ld", state.bs.bits_sent);
  | 
        
        
            | 
            | 
           1148 | 
              | 
        
        
            | 
            | 
           1149 | 
               send_tree(state,(ct_data *)state.ts.dyn_dtree, dcodes-1); /* send the distance tree */
  | 
        
        
            | 
            | 
           1150 | 
               Trace("\ndist tree: sent %ld", state.bs.bits_sent);
  | 
        
        
            | 
            | 
           1151 | 
           }
  | 
        
        
            | 
            | 
           1152 | 
              | 
        
        
            | 
            | 
           1153 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1154 | 
            * Determine the best encoding for the current block: dynamic trees, static
  | 
        
        
            | 
            | 
           1155 | 
            * trees or store, and output the encoded block to the zip file. This function
  | 
        
        
            | 
            | 
           1156 | 
            * returns the total compressed length (in bytes) for the file so far.
  | 
        
        
            | 
            | 
           1157 | 
            */
  | 
        
        
            | 
            | 
           1158 | 
           ulg flush_block(TState &state,char *buf, ulg stored_len, int eof)
  | 
        
        
            | 
            | 
           1159 | 
           {
  | 
        
        
            | 
            | 
           1160 | 
               ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
  | 
        
        
            | 
            | 
           1161 | 
               int max_blindex;  /* index of last bit length code of non zero freq */
  | 
        
        
            | 
            | 
           1162 | 
              | 
        
        
            | 
            | 
           1163 | 
               state.ts.flag_buf[state.ts.last_flags] = state.ts.flags; /* Save the flags for the last 8 items */
  | 
        
        
            | 
            | 
           1164 | 
              | 
        
        
            | 
            | 
           1165 | 
                /* Check if the file is ascii or binary */
  | 
        
        
            | 
            | 
           1166 | 
               if (*state.ts.file_type == (ush)UNKNOWN) set_file_type(state);
  | 
        
        
            | 
            | 
           1167 | 
              | 
        
        
            | 
            | 
           1168 | 
               /* Construct the literal and distance trees */
  | 
        
        
            | 
            | 
           1169 | 
               build_tree(state,(tree_desc *)(&state.ts.l_desc));
  | 
        
        
            | 
            | 
           1170 | 
               Trace("\nlit data: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len);
  | 
        
        
            | 
            | 
           1171 | 
              | 
        
        
            | 
            | 
           1172 | 
               build_tree(state,(tree_desc *)(&state.ts.d_desc));
  | 
        
        
            | 
            | 
           1173 | 
               Trace("\ndist data: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len);
  | 
        
        
            | 
            | 
           1174 | 
               /* At this point, opt_len and static_len are the total bit lengths of
  | 
        
        
            | 
            | 
           1175 | 
                * the compressed block data, excluding the tree representations.
  | 
        
        
            | 
            | 
           1176 | 
                */
  | 
        
        
            | 
            | 
           1177 | 
              | 
        
        
            | 
            | 
           1178 | 
               /* Build the bit length tree for the above two trees, and get the index
  | 
        
        
            | 
            | 
           1179 | 
                * in bl_order of the last bit length code to send.
  | 
        
        
            | 
            | 
           1180 | 
                */
  | 
        
        
            | 
            | 
           1181 | 
               max_blindex = build_bl_tree(state);
  | 
        
        
            | 
            | 
           1182 | 
              | 
        
        
            | 
            | 
           1183 | 
               /* Determine the best encoding. Compute first the block length in bytes */
  | 
        
        
            | 
            | 
           1184 | 
               opt_lenb = (state.ts.opt_len+3+7)>>3;
  | 
        
        
            | 
            | 
           1185 | 
               static_lenb = (state.ts.static_len+3+7)>>3;
  | 
        
        
            | 
            | 
           1186 | 
               state.ts.input_len += stored_len; /* for debugging only */
  | 
        
        
            | 
            | 
           1187 | 
              | 
        
        
            | 
            | 
           1188 | 
               Trace("\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
  | 
        
        
            | 
            | 
           1189 | 
                       opt_lenb, state.ts.opt_len, static_lenb, state.ts.static_len, stored_len,
  | 
        
        
            | 
            | 
           1190 | 
                       state.ts.last_lit, state.ts.last_dist);
  | 
        
        
            | 
            | 
           1191 | 
              | 
        
        
            | 
            | 
           1192 | 
               if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
  | 
        
        
            | 
            | 
           1193 | 
              | 
        
        
            | 
            | 
           1194 | 
               // Originally, zip allowed the file to be transformed from a compressed
  | 
        
        
            | 
            | 
           1195 | 
               // into a stored file in the case where compression failed, there
  | 
        
        
            | 
            | 
           1196 | 
               // was only one block, and it was allowed to change. I've removed this
  | 
        
        
            | 
            | 
           1197 | 
               // possibility since the code's cleaner if no changes are allowed.
  | 
        
        
            | 
            | 
           1198 | 
               //if (stored_len <= opt_lenb && eof && state.ts.cmpr_bytelen == 0L
  | 
        
        
            | 
            | 
           1199 | 
               //   && state.ts.cmpr_len_bits == 0L && state.seekable)
  | 
        
        
            | 
            | 
           1200 | 
               //{   // && state.ts.file_method != NULL
  | 
        
        
            | 
            | 
           1201 | 
               //    // Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there:
  | 
        
        
            | 
            | 
           1202 | 
               //    Assert(state,buf!=NULL,"block vanished");
  | 
        
        
            | 
            | 
           1203 | 
               //    copy_block(state,buf, (unsigned)stored_len, 0); // without header
  | 
        
        
            | 
            | 
           1204 | 
               //    state.ts.cmpr_bytelen = stored_len;
  | 
        
        
            | 
            | 
           1205 | 
               //    Assert(state,false,"unimplemented *state.ts.file_method = STORE;");
  | 
        
        
            | 
            | 
           1206 | 
               //    //*state.ts.file_method = STORE;
  | 
        
        
            | 
            | 
           1207 | 
               //}
  | 
        
        
            | 
            | 
           1208 | 
               //else
  | 
        
        
            | 
            | 
           1209 | 
               if (stored_len+4 <= opt_lenb && buf != (char*)NULL) {
  | 
        
        
            | 
            | 
           1210 | 
                                  /* 4: two words for the lengths */
  | 
        
        
            | 
            | 
           1211 | 
                   /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
  | 
        
        
            | 
            | 
           1212 | 
                    * Otherwise we can't have processed more than WSIZE input bytes since
  | 
        
        
            | 
            | 
           1213 | 
                    * the last block flush, because compression would have been
  | 
        
        
            | 
            | 
           1214 | 
                    * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
  | 
        
        
            | 
            | 
           1215 | 
                    * transform a block into a stored block.
  | 
        
        
            | 
            | 
           1216 | 
                    */
  | 
        
        
            | 
            | 
           1217 | 
                   send_bits(state,(STORED_BLOCK<<1)+eof, 3);  /* send block type */
  | 
        
        
            | 
            | 
           1218 | 
                   state.ts.cmpr_bytelen += ((state.ts.cmpr_len_bits + 3 + 7) >> 3) + stored_len + 4;
  | 
        
        
            | 
            | 
           1219 | 
                   state.ts.cmpr_len_bits = 0L;
  | 
        
        
            | 
            | 
           1220 | 
              | 
        
        
            | 
            | 
           1221 | 
                   copy_block(state,buf, (unsigned)stored_len, 1); /* with header */
  | 
        
        
            | 
            | 
           1222 | 
               }
  | 
        
        
            | 
            | 
           1223 | 
               else if (static_lenb == opt_lenb) {
  | 
        
        
            | 
            | 
           1224 | 
                   send_bits(state,(STATIC_TREES<<1)+eof, 3);
  | 
        
        
            | 
            | 
           1225 | 
                   compress_block(state,(ct_data *)state.ts.static_ltree, (ct_data *)state.ts.static_dtree);
  | 
        
        
            | 
            | 
           1226 | 
                   state.ts.cmpr_len_bits += 3 + state.ts.static_len;
  | 
        
        
            | 
            | 
           1227 | 
                   state.ts.cmpr_bytelen += state.ts.cmpr_len_bits >> 3;
  | 
        
        
            | 
            | 
           1228 | 
                   state.ts.cmpr_len_bits &= 7L;
  | 
        
        
            | 
            | 
           1229 | 
               }
  | 
        
        
            | 
            | 
           1230 | 
               else {
  | 
        
        
            | 
            | 
           1231 | 
                   send_bits(state,(DYN_TREES<<1)+eof, 3);
  | 
        
        
            | 
            | 
           1232 | 
                   send_all_trees(state,state.ts.l_desc.max_code+1, state.ts.d_desc.max_code+1, max_blindex+1);
  | 
        
        
            | 
            | 
           1233 | 
                   compress_block(state,(ct_data *)state.ts.dyn_ltree, (ct_data *)state.ts.dyn_dtree);
  | 
        
        
            | 
            | 
           1234 | 
                   state.ts.cmpr_len_bits += 3 + state.ts.opt_len;
  | 
        
        
            | 
            | 
           1235 | 
                   state.ts.cmpr_bytelen += state.ts.cmpr_len_bits >> 3;
  | 
        
        
            | 
            | 
           1236 | 
                   state.ts.cmpr_len_bits &= 7L;
  | 
        
        
            | 
            | 
           1237 | 
               }
  | 
        
        
            | 
            | 
           1238 | 
               Assert(state,((state.ts.cmpr_bytelen << 3) + state.ts.cmpr_len_bits) == state.bs.bits_sent, "bad compressed size");
  | 
        
        
            | 
            | 
           1239 | 
               init_block(state);
  | 
        
        
            | 
            | 
           1240 | 
              | 
        
        
            | 
            | 
           1241 | 
               if (eof) {
  | 
        
        
            | 
            | 
           1242 | 
                   // Assert(state,input_len == isize, "bad input size");
  | 
        
        
            | 
            | 
           1243 | 
                   bi_windup(state);
  | 
        
        
            | 
            | 
           1244 | 
                   state.ts.cmpr_len_bits += 7;  /* align on byte boundary */
  | 
        
        
            | 
            | 
           1245 | 
               }
  | 
        
        
            | 
            | 
           1246 | 
               Trace("\n");
  | 
        
        
            | 
            | 
           1247 | 
              | 
        
        
            | 
            | 
           1248 | 
               return state.ts.cmpr_bytelen + (state.ts.cmpr_len_bits >> 3);
  | 
        
        
            | 
            | 
           1249 | 
           }
  | 
        
        
            | 
            | 
           1250 | 
              | 
        
        
            | 
            | 
           1251 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1252 | 
            * Save the match info and tally the frequency counts. Return true if
  | 
        
        
            | 
            | 
           1253 | 
            * the current block must be flushed.
  | 
        
        
            | 
            | 
           1254 | 
            */
  | 
        
        
            | 
            | 
           1255 | 
           int ct_tally (TState &state,int dist, int lc)
  | 
        
        
            | 
            | 
           1256 | 
           {
  | 
        
        
            | 
            | 
           1257 | 
               state.ts.l_buf[state.ts.last_lit++] = (uch)lc;
  | 
        
        
            | 
            | 
           1258 | 
               if (dist == 0) {
  | 
        
        
            | 
            | 
           1259 | 
                   /* lc is the unmatched char */
  | 
        
        
            | 
            | 
           1260 | 
                   state.ts.dyn_ltree[lc].fc.freq++;
  | 
        
        
            | 
            | 
           1261 | 
               } else {
  | 
        
        
            | 
            | 
           1262 | 
                   /* Here, lc is the match length - MIN_MATCH */
  | 
        
        
            | 
            | 
           1263 | 
                   dist--;             /* dist = match distance - 1 */
  | 
        
        
            | 
            | 
           1264 | 
                   Assert(state,(ush)dist < (ush)MAX_DIST &&
  | 
        
        
            | 
            | 
           1265 | 
                          (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
  | 
        
        
            | 
            | 
           1266 | 
                          (ush)d_code(dist) < (ush)D_CODES,  "ct_tally: bad match");
  | 
        
        
            | 
            | 
           1267 | 
              | 
        
        
            | 
            | 
           1268 | 
                   state.ts.dyn_ltree[state.ts.length_code[lc]+LITERALS+1].fc.freq++;
  | 
        
        
            | 
            | 
           1269 | 
                   state.ts.dyn_dtree[d_code(dist)].fc.freq++;
  | 
        
        
            | 
            | 
           1270 | 
              | 
        
        
            | 
            | 
           1271 | 
                   state.ts.d_buf[state.ts.last_dist++] = (ush)dist;
  | 
        
        
            | 
            | 
           1272 | 
                   state.ts.flags |= state.ts.flag_bit;
  | 
        
        
            | 
            | 
           1273 | 
               }
  | 
        
        
            | 
            | 
           1274 | 
               state.ts.flag_bit <<= 1;
  | 
        
        
            | 
            | 
           1275 | 
              | 
        
        
            | 
            | 
           1276 | 
               /* Output the flags if they fill a byte: */
  | 
        
        
            | 
            | 
           1277 | 
               if ((state.ts.last_lit & 7) == 0) {
  | 
        
        
            | 
            | 
           1278 | 
                   state.ts.flag_buf[state.ts.last_flags++] = state.ts.flags;
  | 
        
        
            | 
            | 
           1279 | 
                   state.ts.flags = 0, state.ts.flag_bit = 1;
  | 
        
        
            | 
            | 
           1280 | 
               }
  | 
        
        
            | 
            | 
           1281 | 
               /* Try to guess if it is profitable to stop the current block here */
  | 
        
        
            | 
            | 
           1282 | 
               if (state.level > 2 && (state.ts.last_lit & 0xfff) == 0) {
  | 
        
        
            | 
            | 
           1283 | 
                   /* Compute an upper bound for the compressed length */
  | 
        
        
            | 
            | 
           1284 | 
                   ulg out_length = (ulg)state.ts.last_lit*8L;
  | 
        
        
            | 
            | 
           1285 | 
                   ulg in_length = (ulg)state.ds.strstart-state.ds.block_start;
  | 
        
        
            | 
            | 
           1286 | 
                   int dcode;
  | 
        
        
            | 
            | 
           1287 | 
                   for (dcode = 0; dcode < D_CODES; dcode++) {
  | 
        
        
            | 
            | 
           1288 | 
                       out_length += (ulg)state.ts.dyn_dtree[dcode].fc.freq*(5L+extra_dbits[dcode]);
  | 
        
        
            | 
            | 
           1289 | 
                   }
  | 
        
        
            | 
            | 
           1290 | 
                   out_length >>= 3;
  | 
        
        
            | 
            | 
           1291 | 
                   Trace("\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
  | 
        
        
            | 
            | 
           1292 | 
                          state.ts.last_lit, state.ts.last_dist, in_length, out_length,
  | 
        
        
            | 
            | 
           1293 | 
                          100L - out_length*100L/in_length);
  | 
        
        
            | 
            | 
           1294 | 
                   if (state.ts.last_dist < state.ts.last_lit/2 && out_length < in_length/2) return 1;
  | 
        
        
            | 
            | 
           1295 | 
               }
  | 
        
        
            | 
            | 
           1296 | 
               return (state.ts.last_lit == LIT_BUFSIZE-1 || state.ts.last_dist == DIST_BUFSIZE);
  | 
        
        
            | 
            | 
           1297 | 
               /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
  | 
        
        
            | 
            | 
           1298 | 
                * on 16 bit machines and because stored blocks are restricted to
  | 
        
        
            | 
            | 
           1299 | 
                * 64K-1 bytes.
  | 
        
        
            | 
            | 
           1300 | 
                */
  | 
        
        
            | 
            | 
           1301 | 
           }
  | 
        
        
            | 
            | 
           1302 | 
              | 
        
        
            | 
            | 
           1303 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1304 | 
            * Send the block data compressed using the given Huffman trees
  | 
        
        
            | 
            | 
           1305 | 
            */
  | 
        
        
            | 
            | 
           1306 | 
           void compress_block(TState &state,ct_data *ltree, ct_data *dtree)
  | 
        
        
            | 
            | 
           1307 | 
           {
  | 
        
        
            | 
            | 
           1308 | 
               unsigned dist;      /* distance of matched string */
  | 
        
        
            | 
            | 
           1309 | 
               int lc;             /* match length or unmatched char (if dist == 0) */
  | 
        
        
            | 
            | 
           1310 | 
               unsigned lx = 0;    /* running index in l_buf */
  | 
        
        
            | 
            | 
           1311 | 
               unsigned dx = 0;    /* running index in d_buf */
  | 
        
        
            | 
            | 
           1312 | 
               unsigned fx = 0;    /* running index in flag_buf */
  | 
        
        
            | 
            | 
           1313 | 
               uch flag = 0;       /* current flags */
  | 
        
        
            | 
            | 
           1314 | 
               unsigned code;      /* the code to send */
  | 
        
        
            | 
            | 
           1315 | 
               int extra;          /* number of extra bits to send */
  | 
        
        
            | 
            | 
           1316 | 
              | 
        
        
            | 
            | 
           1317 | 
               if (state.ts.last_lit != 0) do {
  | 
        
        
            | 
            | 
           1318 | 
                   if ((lx & 7) == 0) flag = state.ts.flag_buf[fx++];
  | 
        
        
            | 
            | 
           1319 | 
                   lc = state.ts.l_buf[lx++];
  | 
        
        
            | 
            | 
           1320 | 
                   if ((flag & 1) == 0) {
  | 
        
        
            | 
            | 
           1321 | 
                       send_code(state,lc, ltree); /* send a literal byte */
  | 
        
        
            | 
            | 
           1322 | 
                   } else {
  | 
        
        
            | 
            | 
           1323 | 
                       /* Here, lc is the match length - MIN_MATCH */
  | 
        
        
            | 
            | 
           1324 | 
                       code = state.ts.length_code[lc];
  | 
        
        
            | 
            | 
           1325 | 
                       send_code(state,code+LITERALS+1, ltree); /* send the length code */
  | 
        
        
            | 
            | 
           1326 | 
                       extra = extra_lbits[code];
  | 
        
        
            | 
            | 
           1327 | 
                       if (extra != 0) {
  | 
        
        
            | 
            | 
           1328 | 
                           lc -= state.ts.base_length[code];
  | 
        
        
            | 
            | 
           1329 | 
                           send_bits(state,lc, extra);        /* send the extra length bits */
  | 
        
        
            | 
            | 
           1330 | 
                       }
  | 
        
        
            | 
            | 
           1331 | 
                       dist = state.ts.d_buf[dx++];
  | 
        
        
            | 
            | 
           1332 | 
                       /* Here, dist is the match distance - 1 */
  | 
        
        
            | 
            | 
           1333 | 
                       code = d_code(dist);
  | 
        
        
            | 
            | 
           1334 | 
                       Assert(state,code < D_CODES, "bad d_code");
  | 
        
        
            | 
            | 
           1335 | 
              | 
        
        
            | 
            | 
           1336 | 
                       send_code(state,code, dtree);       /* send the distance code */
  | 
        
        
            | 
            | 
           1337 | 
                       extra = extra_dbits[code];
  | 
        
        
            | 
            | 
           1338 | 
                       if (extra != 0) {
  | 
        
        
            | 
            | 
           1339 | 
                           dist -= state.ts.base_dist[code];
  | 
        
        
            | 
            | 
           1340 | 
                           send_bits(state,dist, extra);   /* send the extra distance bits */
  | 
        
        
            | 
            | 
           1341 | 
                       }
  | 
        
        
            | 
            | 
           1342 | 
                   } /* literal or match pair ? */
  | 
        
        
            | 
            | 
           1343 | 
                   flag >>= 1;
  | 
        
        
            | 
            | 
           1344 | 
               } while (lx < state.ts.last_lit);
  | 
        
        
            | 
            | 
           1345 | 
              | 
        
        
            | 
            | 
           1346 | 
               send_code(state,END_BLOCK, ltree);
  | 
        
        
            | 
            | 
           1347 | 
           }
  | 
        
        
            | 
            | 
           1348 | 
              | 
        
        
            | 
            | 
           1349 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1350 | 
            * Set the file type to ASCII or BINARY, using a crude approximation:
  | 
        
        
            | 
            | 
           1351 | 
            * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
  | 
        
        
            | 
            | 
           1352 | 
            * IN assertion: the fields freq of dyn_ltree are set and the total of all
  | 
        
        
            | 
            | 
           1353 | 
            * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
  | 
        
        
            | 
            | 
           1354 | 
            */
  | 
        
        
            | 
            | 
           1355 | 
           void set_file_type(TState &state)
  | 
        
        
            | 
            | 
           1356 | 
           {
  | 
        
        
            | 
            | 
           1357 | 
               int n = 0;
  | 
        
        
            | 
            | 
           1358 | 
               unsigned ascii_freq = 0;
  | 
        
        
            | 
            | 
           1359 | 
               unsigned bin_freq = 0;
  | 
        
        
            | 
            | 
           1360 | 
               while (n < 7)        bin_freq += state.ts.dyn_ltree[n++].fc.freq;
  | 
        
        
            | 
            | 
           1361 | 
               while (n < 128)    ascii_freq += state.ts.dyn_ltree[n++].fc.freq;
  | 
        
        
            | 
            | 
           1362 | 
               while (n < LITERALS) bin_freq += state.ts.dyn_ltree[n++].fc.freq;
  | 
        
        
            | 
            | 
           1363 | 
               *state.ts.file_type = (ush)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII);
  | 
        
        
            | 
            | 
           1364 | 
           }
  | 
        
        
            | 
            | 
           1365 | 
              | 
        
        
            | 
            | 
           1366 | 
              | 
        
        
            | 
            | 
           1367 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1368 | 
            * Initialize the bit string routines.
  | 
        
        
            | 
            | 
           1369 | 
            */
  | 
        
        
            | 
            | 
           1370 | 
           void bi_init (TState &state,char *tgt_buf, unsigned tgt_size, int flsh_allowed)
  | 
        
        
            | 
            | 
           1371 | 
           {
  | 
        
        
            | 
            | 
           1372 | 
               state.bs.out_buf = tgt_buf;
  | 
        
        
            | 
            | 
           1373 | 
               state.bs.out_size = tgt_size;
  | 
        
        
            | 
            | 
           1374 | 
               state.bs.out_offset = 0;
  | 
        
        
            | 
            | 
           1375 | 
               state.bs.flush_flg = flsh_allowed;
  | 
        
        
            | 
            | 
           1376 | 
              | 
        
        
            | 
            | 
           1377 | 
               state.bs.bi_buf = 0;
  | 
        
        
            | 
            | 
           1378 | 
               state.bs.bi_valid = 0;
  | 
        
        
            | 
            | 
           1379 | 
               state.bs.bits_sent = 0L;
  | 
        
        
            | 
            | 
           1380 | 
           }
  | 
        
        
            | 
            | 
           1381 | 
              | 
        
        
            | 
            | 
           1382 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1383 | 
            * Send a value on a given number of bits.
  | 
        
        
            | 
            | 
           1384 | 
            * IN assertion: length <= 16 and value fits in length bits.
  | 
        
        
            | 
            | 
           1385 | 
            */
  | 
        
        
            | 
            | 
           1386 | 
           void send_bits(TState &state,int value, int length)
  | 
        
        
            | 
            | 
           1387 | 
           {
  | 
        
        
            | 
            | 
           1388 | 
               Assert(state,length > 0 && length <= 15, "invalid length");
  | 
        
        
            | 
            | 
           1389 | 
               state.bs.bits_sent += (ulg)length;
  | 
        
        
            | 
            | 
           1390 | 
               /* If not enough room in bi_buf, use (bi_valid) bits from bi_buf and
  | 
        
        
            | 
            | 
           1391 | 
                * (Buf_size - bi_valid) bits from value to flush the filled bi_buf,
  | 
        
        
            | 
            | 
           1392 | 
                * then fill in the rest of (value), leaving (length - (Buf_size-bi_valid))
  | 
        
        
            | 
            | 
           1393 | 
                * unused bits in bi_buf.
  | 
        
        
            | 
            | 
           1394 | 
                */
  | 
        
        
            | 
            | 
           1395 | 
               state.bs.bi_buf |= (value << state.bs.bi_valid);
  | 
        
        
            | 
            | 
           1396 | 
               state.bs.bi_valid += length;
  | 
        
        
            | 
            | 
           1397 | 
               if (state.bs.bi_valid > (int)Buf_size) {
  | 
        
        
            | 
            | 
           1398 | 
                   PUTSHORT(state,state.bs.bi_buf);
  | 
        
        
            | 
            | 
           1399 | 
                   state.bs.bi_valid -= Buf_size;
  | 
        
        
            | 
            | 
           1400 | 
                   state.bs.bi_buf = (unsigned)value >> (length - state.bs.bi_valid);
  | 
        
        
            | 
            | 
           1401 | 
               }
  | 
        
        
            | 
            | 
           1402 | 
           }
  | 
        
        
            | 
            | 
           1403 | 
              | 
        
        
            | 
            | 
           1404 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1405 | 
            * Reverse the first len bits of a code, using straightforward code (a faster
  | 
        
        
            | 
            | 
           1406 | 
            * method would use a table)
  | 
        
        
            | 
            | 
           1407 | 
            * IN assertion: 1 <= len <= 15
  | 
        
        
            | 
            | 
           1408 | 
            */
  | 
        
        
            | 
            | 
           1409 | 
           unsigned bi_reverse(unsigned code, int len)
  | 
        
        
            | 
            | 
           1410 | 
           {
  | 
        
        
            | 
            | 
           1411 | 
               register unsigned res = 0;
  | 
        
        
            | 
            | 
           1412 | 
               do {
  | 
        
        
            | 
            | 
           1413 | 
                   res |= code & 1;
  | 
        
        
            | 
            | 
           1414 | 
                   code >>= 1, res <<= 1;
  | 
        
        
            | 
            | 
           1415 | 
               } while (--len > 0);
  | 
        
        
            | 
            | 
           1416 | 
               return res >> 1;
  | 
        
        
            | 
            | 
           1417 | 
           }
  | 
        
        
            | 
            | 
           1418 | 
              | 
        
        
            | 
            | 
           1419 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1420 | 
            * Write out any remaining bits in an incomplete byte.
  | 
        
        
            | 
            | 
           1421 | 
            */
  | 
        
        
            | 
            | 
           1422 | 
           void bi_windup(TState &state)
  | 
        
        
            | 
            | 
           1423 | 
           {
  | 
        
        
            | 
            | 
           1424 | 
               if (state.bs.bi_valid > 8) {
  | 
        
        
            | 
            | 
           1425 | 
                   PUTSHORT(state,state.bs.bi_buf);
  | 
        
        
            | 
            | 
           1426 | 
               } else if (state.bs.bi_valid > 0) {
  | 
        
        
            | 
            | 
           1427 | 
                   PUTBYTE(state,state.bs.bi_buf);
  | 
        
        
            | 
            | 
           1428 | 
               }
  | 
        
        
            | 
            | 
           1429 | 
               if (state.bs.flush_flg) {
  | 
        
        
            | 
            | 
           1430 | 
                   state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset);
  | 
        
        
            | 
            | 
           1431 | 
               }
  | 
        
        
            | 
            | 
           1432 | 
               state.bs.bi_buf = 0;
  | 
        
        
            | 
            | 
           1433 | 
               state.bs.bi_valid = 0;
  | 
        
        
            | 
            | 
           1434 | 
               state.bs.bits_sent = (state.bs.bits_sent+7) & ~7;
  | 
        
        
            | 
            | 
           1435 | 
           }
  | 
        
        
            | 
            | 
           1436 | 
              | 
        
        
            | 
            | 
           1437 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1438 | 
            * Copy a stored block to the zip file, storing first the length and its
  | 
        
        
            | 
            | 
           1439 | 
            * one's complement if requested.
  | 
        
        
            | 
            | 
           1440 | 
            */
  | 
        
        
            | 
            | 
           1441 | 
           void copy_block(TState &state, char *block, unsigned len, int header)
  | 
        
        
            | 
            | 
           1442 | 
           {
  | 
        
        
            | 
            | 
           1443 | 
               bi_windup(state);              /* align on byte boundary */
  | 
        
        
            | 
            | 
           1444 | 
              | 
        
        
            | 
            | 
           1445 | 
               if (header) {
  | 
        
        
            | 
            | 
           1446 | 
                   PUTSHORT(state,(ush)len);
  | 
        
        
            | 
            | 
           1447 | 
                   PUTSHORT(state,(ush)~len);
  | 
        
        
            | 
            | 
           1448 | 
                   state.bs.bits_sent += 2*16;
  | 
        
        
            | 
            | 
           1449 | 
               }
  | 
        
        
            | 
            | 
           1450 | 
               if (state.bs.flush_flg) {
  | 
        
        
            | 
            | 
           1451 | 
                   state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset);
  | 
        
        
            | 
            | 
           1452 | 
                   state.bs.out_offset = len;
  | 
        
        
            | 
            | 
           1453 | 
                   state.flush_outbuf(state.param,block, &state.bs.out_offset);
  | 
        
        
            | 
            | 
           1454 | 
               } else if (state.bs.out_offset + len > state.bs.out_size) {
  | 
        
        
            | 
            | 
           1455 | 
                   Assert(state,false,"output buffer too small for in-memory compression");
  | 
        
        
            | 
            | 
           1456 | 
               } else {
  | 
        
        
            | 
            | 
           1457 | 
                   memcpy(state.bs.out_buf + state.bs.out_offset, block, len);
  | 
        
        
            | 
            | 
           1458 | 
                   state.bs.out_offset += len;
  | 
        
        
            | 
            | 
           1459 | 
               }
  | 
        
        
            | 
            | 
           1460 | 
               state.bs.bits_sent += (ulg)len<<3;
  | 
        
        
            | 
            | 
           1461 | 
           }
  | 
        
        
            | 
            | 
           1462 | 
              | 
        
        
            | 
            | 
           1463 | 
              | 
        
        
            | 
            | 
           1464 | 
              | 
        
        
            | 
            | 
           1465 | 
              | 
        
        
            | 
            | 
           1466 | 
              | 
        
        
            | 
            | 
           1467 | 
              | 
        
        
            | 
            | 
           1468 | 
              | 
        
        
            | 
            | 
           1469 | 
              | 
        
        
            | 
            | 
           1470 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1471 | 
            *  Prototypes for functions.
  | 
        
        
            | 
            | 
           1472 | 
            */
  | 
        
        
            | 
            | 
           1473 | 
              | 
        
        
            | 
            | 
           1474 | 
           void fill_window  (TState &state);
  | 
        
        
            | 
            | 
           1475 | 
           ulg deflate_fast  (TState &state);
  | 
        
        
            | 
            | 
           1476 | 
              | 
        
        
            | 
            | 
           1477 | 
           int  longest_match (TState &state,IPos cur_match);
  | 
        
        
            | 
            | 
           1478 | 
              | 
        
        
            | 
            | 
           1479 | 
              | 
        
        
            | 
            | 
           1480 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1481 | 
            * Update a hash value with the given input byte
  | 
        
        
            | 
            | 
           1482 | 
            * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
  | 
        
        
            | 
            | 
           1483 | 
            *    input characters, so that a running hash key can be computed from the
  | 
        
        
            | 
            | 
           1484 | 
            *    previous key instead of complete recalculation each time.
  | 
        
        
            | 
            | 
           1485 | 
            */
  | 
        
        
            | 
            | 
           1486 | 
           #define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
  | 
        
        
            | 
            | 
           1487 | 
              | 
        
        
            | 
            | 
           1488 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1489 | 
            * Insert string s in the dictionary and set match_head to the previous head
  | 
        
        
            | 
            | 
           1490 | 
            * of the hash chain (the most recent string with same hash key). Return
  | 
        
        
            | 
            | 
           1491 | 
            * the previous length of the hash chain.
  | 
        
        
            | 
            | 
           1492 | 
            * IN  assertion: all calls to to INSERT_STRING are made with consecutive
  | 
        
        
            | 
            | 
           1493 | 
            *    input characters and the first MIN_MATCH bytes of s are valid
  | 
        
        
            | 
            | 
           1494 | 
            *    (except for the last MIN_MATCH-1 bytes of the input file).
  | 
        
        
            | 
            | 
           1495 | 
            */
  | 
        
        
            | 
            | 
           1496 | 
           #define INSERT_STRING(s, match_head) \
  | 
        
        
            | 
            | 
           1497 | 
              (UPDATE_HASH(state.ds.ins_h, state.ds.window[(s) + (MIN_MATCH-1)]), \
  | 
        
        
            | 
            | 
           1498 | 
               state.ds.prev[(s) & WMASK] = match_head = state.ds.head[state.ds.ins_h], \
  | 
        
        
            | 
            | 
           1499 | 
               state.ds.head[state.ds.ins_h] = (s))
  | 
        
        
            | 
            | 
           1500 | 
              | 
        
        
            | 
            | 
           1501 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1502 | 
            * Initialize the "longest match" routines for a new file
  | 
        
        
            | 
            | 
           1503 | 
            *
  | 
        
        
            | 
            | 
           1504 | 
            * IN assertion: window_size is > 0 if the input file is already read or
  | 
        
        
            | 
            | 
           1505 | 
            *    mmap'ed in the window[] array, 0 otherwise. In the first case,
  | 
        
        
            | 
            | 
           1506 | 
            *    window_size is sufficient to contain the whole input file plus
  | 
        
        
            | 
            | 
           1507 | 
            *    MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end
  | 
        
        
            | 
            | 
           1508 | 
            *    of window[] when looking for matches towards the end).
  | 
        
        
            | 
            | 
           1509 | 
            */
  | 
        
        
            | 
            | 
           1510 | 
           void lm_init (TState &state, int pack_level, ush *flags)
  | 
        
        
            | 
            | 
           1511 | 
           {
  | 
        
        
            | 
            | 
           1512 | 
               register unsigned j;
  | 
        
        
            | 
            | 
           1513 | 
              | 
        
        
            | 
            | 
           1514 | 
               Assert(state,pack_level>=1 && pack_level<=8,"bad pack level");
  | 
        
        
            | 
            | 
           1515 | 
              | 
        
        
            | 
            | 
           1516 | 
               /* Do not slide the window if the whole input is already in memory
  | 
        
        
            | 
            | 
           1517 | 
                * (window_size > 0)
  | 
        
        
            | 
            | 
           1518 | 
                */
  | 
        
        
            | 
            | 
           1519 | 
               state.ds.sliding = 0;
  | 
        
        
            | 
            | 
           1520 | 
               if (state.ds.window_size == 0L) {
  | 
        
        
            | 
            | 
           1521 | 
                   state.ds.sliding = 1;
  | 
        
        
            | 
            | 
           1522 | 
                   state.ds.window_size = (ulg)2L*WSIZE;
  | 
        
        
            | 
            | 
           1523 | 
               }
  | 
        
        
            | 
            | 
           1524 | 
              | 
        
        
            | 
            | 
           1525 | 
               /* Initialize the hash table (avoiding 64K overflow for 16 bit systems).
  | 
        
        
            | 
            | 
           1526 | 
                * prev[] will be initialized on the fly.
  | 
        
        
            | 
            | 
           1527 | 
                */
  | 
        
        
            | 
            | 
           1528 | 
               state.ds.head[HASH_SIZE-1] = NIL;
  | 
        
        
            | 
            | 
           1529 | 
               memset((char*)state.ds.head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*state.ds.head));
  | 
        
        
            | 
            | 
           1530 | 
              | 
        
        
            | 
            | 
           1531 | 
               /* Set the default configuration parameters:
  | 
        
        
            | 
            | 
           1532 | 
                */
  | 
        
        
            | 
            | 
           1533 | 
               state.ds.max_lazy_match   = configuration_table[pack_level].max_lazy;
  | 
        
        
            | 
            | 
           1534 | 
               state.ds.good_match       = configuration_table[pack_level].good_length;
  | 
        
        
            | 
            | 
           1535 | 
               state.ds.nice_match       = configuration_table[pack_level].nice_length;
  | 
        
        
            | 
            | 
           1536 | 
               state.ds.max_chain_length = configuration_table[pack_level].max_chain;
  | 
        
        
            | 
            | 
           1537 | 
               if (pack_level <= 2) {
  | 
        
        
            | 
            | 
           1538 | 
                  *flags |= FAST;
  | 
        
        
            | 
            | 
           1539 | 
               } else if (pack_level >= 8) {
  | 
        
        
            | 
            | 
           1540 | 
                  *flags |= SLOW;
  | 
        
        
            | 
            | 
           1541 | 
               }
  | 
        
        
            | 
            | 
           1542 | 
               /* ??? reduce max_chain_length for binary files */
  | 
        
        
            | 
            | 
           1543 | 
              | 
        
        
            | 
            | 
           1544 | 
               state.ds.strstart = 0;
  | 
        
        
            | 
            | 
           1545 | 
               state.ds.block_start = 0L;
  | 
        
        
            | 
            | 
           1546 | 
              | 
        
        
            | 
            | 
           1547 | 
               j = WSIZE;
  | 
        
        
            | 
            | 
           1548 | 
               j <<= 1; // Can read 64K in one step
  | 
        
        
            | 
            | 
           1549 | 
               state.ds.lookahead = state.readfunc(state, (char*)state.ds.window, j);
  | 
        
        
            | 
            | 
           1550 | 
              | 
        
        
            | 
            | 
           1551 | 
               if (state.ds.lookahead == 0 || state.ds.lookahead == (unsigned)EOF) {
  | 
        
        
            | 
            | 
           1552 | 
                  state.ds.eofile = 1, state.ds.lookahead = 0;
  | 
        
        
            | 
            | 
           1553 | 
                  return;
  | 
        
        
            | 
            | 
           1554 | 
               }
  | 
        
        
            | 
            | 
           1555 | 
               state.ds.eofile = 0;
  | 
        
        
            | 
            | 
           1556 | 
               /* Make sure that we always have enough lookahead. This is important
  | 
        
        
            | 
            | 
           1557 | 
                * if input comes from a device such as a tty.
  | 
        
        
            | 
            | 
           1558 | 
                */
  | 
        
        
            | 
            | 
           1559 | 
               if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state);
  | 
        
        
            | 
            | 
           1560 | 
              | 
        
        
            | 
            | 
           1561 | 
               state.ds.ins_h = 0;
  | 
        
        
            | 
            | 
           1562 | 
               for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(state.ds.ins_h, state.ds.window[j]);
  | 
        
        
            | 
            | 
           1563 | 
               /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
  | 
        
        
            | 
            | 
           1564 | 
                * not important since only literal bytes will be emitted.
  | 
        
        
            | 
            | 
           1565 | 
                */
  | 
        
        
            | 
            | 
           1566 | 
           }
  | 
        
        
            | 
            | 
           1567 | 
              | 
        
        
            | 
            | 
           1568 | 
              | 
        
        
            | 
            | 
           1569 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1570 | 
            * Set match_start to the longest match starting at the given string and
  | 
        
        
            | 
            | 
           1571 | 
            * return its length. Matches shorter or equal to prev_length are discarded,
  | 
        
        
            | 
            | 
           1572 | 
            * in which case the result is equal to prev_length and match_start is
  | 
        
        
            | 
            | 
           1573 | 
            * garbage.
  | 
        
        
            | 
            | 
           1574 | 
            * IN assertions: cur_match is the head of the hash chain for the current
  | 
        
        
            | 
            | 
           1575 | 
            *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
  | 
        
        
            | 
            | 
           1576 | 
            */
  | 
        
        
            | 
            | 
           1577 | 
           // For 80x86 and 680x0 and ARM, an optimized version is in match.asm or
  | 
        
        
            | 
            | 
           1578 | 
           // match.S. The code is functionally equivalent, so you can use the C version
  | 
        
        
            | 
            | 
           1579 | 
           // if desired. Which I do so desire!
  | 
        
        
            | 
            | 
           1580 | 
           int longest_match(TState &state,IPos cur_match)
  | 
        
        
            | 
            | 
           1581 | 
           {
  | 
        
        
            | 
            | 
           1582 | 
               unsigned chain_length = state.ds.max_chain_length;   /* max hash chain length */
  | 
        
        
            | 
            | 
           1583 | 
               register uch far *scan = state.ds.window + state.ds.strstart; /* current string */
  | 
        
        
            | 
            | 
           1584 | 
               register uch far *match;                    /* matched string */
  | 
        
        
            | 
            | 
           1585 | 
               register int len;                           /* length of current match */
  | 
        
        
            | 
            | 
           1586 | 
               int best_len = state.ds.prev_length;                 /* best match length so far */
  | 
        
        
            | 
            | 
           1587 | 
               IPos limit = state.ds.strstart > (IPos)MAX_DIST ? state.ds.strstart - (IPos)MAX_DIST : NIL;
  | 
        
        
            | 
            | 
           1588 | 
               /* Stop when cur_match becomes <= limit. To simplify the code,
  | 
        
        
            | 
            | 
           1589 | 
                * we prevent matches with the string of window index 0.
  | 
        
        
            | 
            | 
           1590 | 
                */
  | 
        
        
            | 
            | 
           1591 | 
              | 
        
        
            | 
            | 
           1592 | 
             // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
  | 
        
        
            | 
            | 
           1593 | 
             // It is easy to get rid of this optimization if necessary.
  | 
        
        
            | 
            | 
           1594 | 
               Assert(state,HASH_BITS>=8 && MAX_MATCH==258,"Code too clever");
  | 
        
        
            | 
            | 
           1595 | 
              | 
        
        
            | 
            | 
           1596 | 
              | 
        
        
            | 
            | 
           1597 | 
              | 
        
        
            | 
            | 
           1598 | 
               register uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH;
  | 
        
        
            | 
            | 
           1599 | 
               register uch scan_end1  = scan[best_len-1];
  | 
        
        
            | 
            | 
           1600 | 
               register uch scan_end   = scan[best_len];
  | 
        
        
            | 
            | 
           1601 | 
              | 
        
        
            | 
            | 
           1602 | 
               /* Do not waste too much time if we already have a good match: */
  | 
        
        
            | 
            | 
           1603 | 
               if (state.ds.prev_length >= state.ds.good_match) {
  | 
        
        
            | 
            | 
           1604 | 
                   chain_length >>= 2;
  | 
        
        
            | 
            | 
           1605 | 
               }
  | 
        
        
            | 
            | 
           1606 | 
              | 
        
        
            | 
            | 
           1607 | 
               Assert(state,state.ds.strstart <= state.ds.window_size-MIN_LOOKAHEAD, "insufficient lookahead");
  | 
        
        
            | 
            | 
           1608 | 
              | 
        
        
            | 
            | 
           1609 | 
               do {
  | 
        
        
            | 
            | 
           1610 | 
                   Assert(state,cur_match < state.ds.strstart, "no future");
  | 
        
        
            | 
            | 
           1611 | 
                   match = state.ds.window + cur_match;
  | 
        
        
            | 
            | 
           1612 | 
              | 
        
        
            | 
            | 
           1613 | 
                   /* Skip to next match if the match length cannot increase
  | 
        
        
            | 
            | 
           1614 | 
                    * or if the match length is less than 2:
  | 
        
        
            | 
            | 
           1615 | 
                    */
  | 
        
        
            | 
            | 
           1616 | 
                   if (match[best_len]   != scan_end  ||
  | 
        
        
            | 
            | 
           1617 | 
                       match[best_len-1] != scan_end1 ||
  | 
        
        
            | 
            | 
           1618 | 
                       *match            != *scan     ||
  | 
        
        
            | 
            | 
           1619 | 
                       *++match          != scan[1])      continue;
  | 
        
        
            | 
            | 
           1620 | 
              | 
        
        
            | 
            | 
           1621 | 
                   /* The check at best_len-1 can be removed because it will be made
  | 
        
        
            | 
            | 
           1622 | 
                    * again later. (This heuristic is not always a win.)
  | 
        
        
            | 
            | 
           1623 | 
                    * It is not necessary to compare scan[2] and match[2] since they
  | 
        
        
            | 
            | 
           1624 | 
                    * are always equal when the other bytes match, given that
  | 
        
        
            | 
            | 
           1625 | 
                    * the hash keys are equal and that HASH_BITS >= 8.
  | 
        
        
            | 
            | 
           1626 | 
                    */
  | 
        
        
            | 
            | 
           1627 | 
                   scan += 2, match++;
  | 
        
        
            | 
            | 
           1628 | 
              | 
        
        
            | 
            | 
           1629 | 
                   /* We check for insufficient lookahead only every 8th comparison;
  | 
        
        
            | 
            | 
           1630 | 
                    * the 256th check will be made at strstart+258.
  | 
        
        
            | 
            | 
           1631 | 
                    */
  | 
        
        
            | 
            | 
           1632 | 
                   do {
  | 
        
        
            | 
            | 
           1633 | 
                   } while (*++scan == *++match && *++scan == *++match &&
  | 
        
        
            | 
            | 
           1634 | 
                            *++scan == *++match && *++scan == *++match &&
  | 
        
        
            | 
            | 
           1635 | 
                            *++scan == *++match && *++scan == *++match &&
  | 
        
        
            | 
            | 
           1636 | 
                            *++scan == *++match && *++scan == *++match &&
  | 
        
        
            | 
            | 
           1637 | 
                            scan < strend);
  | 
        
        
            | 
            | 
           1638 | 
              | 
        
        
            | 
            | 
           1639 | 
                   Assert(state,scan <= state.ds.window+(unsigned)(state.ds.window_size-1), "wild scan");
  | 
        
        
            | 
            | 
           1640 | 
              | 
        
        
            | 
            | 
           1641 | 
                   len = MAX_MATCH - (int)(strend - scan);
  | 
        
        
            | 
            | 
           1642 | 
                   scan = strend - MAX_MATCH;
  | 
        
        
            | 
            | 
           1643 | 
              | 
        
        
            | 
            | 
           1644 | 
              | 
        
        
            | 
            | 
           1645 | 
                   if (len > best_len) {
  | 
        
        
            | 
            | 
           1646 | 
                       state.ds.match_start = cur_match;
  | 
        
        
            | 
            | 
           1647 | 
                       best_len = len;
  | 
        
        
            | 
            | 
           1648 | 
                       if (len >= state.ds.nice_match) break;
  | 
        
        
            | 
            | 
           1649 | 
                       scan_end1  = scan[best_len-1];
  | 
        
        
            | 
            | 
           1650 | 
                       scan_end   = scan[best_len];
  | 
        
        
            | 
            | 
           1651 | 
                   }
  | 
        
        
            | 
            | 
           1652 | 
               } while ((cur_match = state.ds.prev[cur_match & WMASK]) > limit
  | 
        
        
            | 
            | 
           1653 | 
                        && --chain_length != 0);
  | 
        
        
            | 
            | 
           1654 | 
              | 
        
        
            | 
            | 
           1655 | 
               return best_len;
  | 
        
        
            | 
            | 
           1656 | 
           }
  | 
        
        
            | 
            | 
           1657 | 
              | 
        
        
            | 
            | 
           1658 | 
              | 
        
        
            | 
            | 
           1659 | 
              | 
        
        
            | 
            | 
           1660 | 
           #define check_match(state,start, match, length)
  | 
        
        
            | 
            | 
           1661 | 
           // or alternatively...
  | 
        
        
            | 
            | 
           1662 | 
           //void check_match(TState &state,IPos start, IPos match, int length)
  | 
        
        
            | 
            | 
           1663 | 
           //{ // check that the match is indeed a match
  | 
        
        
            | 
            | 
           1664 | 
           //    if (memcmp((char*)state.ds.window + match,
  | 
        
        
            | 
            | 
           1665 | 
           //                (char*)state.ds.window + start, length) != EQUAL) {
  | 
        
        
            | 
            | 
           1666 | 
           //        fprintf(stderr,
  | 
        
        
            | 
            | 
           1667 | 
           //            " start %d, match %d, length %d\n",
  | 
        
        
            | 
            | 
           1668 | 
           //            start, match, length);
  | 
        
        
            | 
            | 
           1669 | 
           //        error("invalid match");
  | 
        
        
            | 
            | 
           1670 | 
           //    }
  | 
        
        
            | 
            | 
           1671 | 
           //    if (state.verbose > 1) {
  | 
        
        
            | 
            | 
           1672 | 
           //        fprintf(stderr,"\\[%d,%d]", start-match, length);
  | 
        
        
            | 
            | 
           1673 | 
           //        do { fprintf(stdout,"%c",state.ds.window[start++]); } while (--length != 0);
  | 
        
        
            | 
            | 
           1674 | 
           //    }
  | 
        
        
            | 
            | 
           1675 | 
           //}
  | 
        
        
            | 
            | 
           1676 | 
              | 
        
        
            | 
            | 
           1677 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1678 | 
            * Fill the window when the lookahead becomes insufficient.
  | 
        
        
            | 
            | 
           1679 | 
            * Updates strstart and lookahead, and sets eofile if end of input file.
  | 
        
        
            | 
            | 
           1680 | 
            *
  | 
        
        
            | 
            | 
           1681 | 
            * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
  | 
        
        
            | 
            | 
           1682 | 
            * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
  | 
        
        
            | 
            | 
           1683 | 
            *    At least one byte has been read, or eofile is set; file reads are
  | 
        
        
            | 
            | 
           1684 | 
            *    performed for at least two bytes (required for the translate_eol option).
  | 
        
        
            | 
            | 
           1685 | 
            */
  | 
        
        
            | 
            | 
           1686 | 
           void fill_window(TState &state)
  | 
        
        
            | 
            | 
           1687 | 
           {
  | 
        
        
            | 
            | 
           1688 | 
               register unsigned n, m;
  | 
        
        
            | 
            | 
           1689 | 
               unsigned more;    /* Amount of free space at the end of the window. */
  | 
        
        
            | 
            | 
           1690 | 
              | 
        
        
            | 
            | 
           1691 | 
               do {
  | 
        
        
            | 
            | 
           1692 | 
                   more = (unsigned)(state.ds.window_size - (ulg)state.ds.lookahead - (ulg)state.ds.strstart);
  | 
        
        
            | 
            | 
           1693 | 
              | 
        
        
            | 
            | 
           1694 | 
                   /* If the window is almost full and there is insufficient lookahead,
  | 
        
        
            | 
            | 
           1695 | 
                    * move the upper half to the lower one to make room in the upper half.
  | 
        
        
            | 
            | 
           1696 | 
                    */
  | 
        
        
            | 
            | 
           1697 | 
                   if (more == (unsigned)EOF) {
  | 
        
        
            | 
            | 
           1698 | 
                       /* Very unlikely, but possible on 16 bit machine if strstart == 0
  | 
        
        
            | 
            | 
           1699 | 
                        * and lookahead == 1 (input done one byte at time)
  | 
        
        
            | 
            | 
           1700 | 
                        */
  | 
        
        
            | 
            | 
           1701 | 
                       more--;
  | 
        
        
            | 
            | 
           1702 | 
              | 
        
        
            | 
            | 
           1703 | 
                   /* For MMAP or BIG_MEM, the whole input file is already in memory so
  | 
        
        
            | 
            | 
           1704 | 
                    * we must not perform sliding. We must however call (*read_buf)() in
  | 
        
        
            | 
            | 
           1705 | 
                    * order to compute the crc, update lookahead and possibly set eofile.
  | 
        
        
            | 
            | 
           1706 | 
                    */
  | 
        
        
            | 
            | 
           1707 | 
                   } else if (state.ds.strstart >= WSIZE+MAX_DIST && state.ds.sliding) {
  | 
        
        
            | 
            | 
           1708 | 
              | 
        
        
            | 
            | 
           1709 | 
                       /* By the IN assertion, the window is not empty so we can't confuse
  | 
        
        
            | 
            | 
           1710 | 
                        * more == 0 with more == 64K on a 16 bit machine.
  | 
        
        
            | 
            | 
           1711 | 
                        */
  | 
        
        
            | 
            | 
           1712 | 
                       memcpy((char*)state.ds.window, (char*)state.ds.window+WSIZE, (unsigned)WSIZE);
  | 
        
        
            | 
            | 
           1713 | 
                       state.ds.match_start -= WSIZE;
  | 
        
        
            | 
            | 
           1714 | 
                       state.ds.strstart    -= WSIZE; /* we now have strstart >= MAX_DIST: */
  | 
        
        
            | 
            | 
           1715 | 
              | 
        
        
            | 
            | 
           1716 | 
                       state.ds.block_start -= (long) WSIZE;
  | 
        
        
            | 
            | 
           1717 | 
              | 
        
        
            | 
            | 
           1718 | 
                       for (n = 0; n < HASH_SIZE; n++) {
  | 
        
        
            | 
            | 
           1719 | 
                           m = state.ds.head[n];
  | 
        
        
            | 
            | 
           1720 | 
                           state.ds.head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL);
  | 
        
        
            | 
            | 
           1721 | 
                       }
  | 
        
        
            | 
            | 
           1722 | 
                       for (n = 0; n < WSIZE; n++) {
  | 
        
        
            | 
            | 
           1723 | 
                           m = state.ds.prev[n];
  | 
        
        
            | 
            | 
           1724 | 
                           state.ds.prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL);
  | 
        
        
            | 
            | 
           1725 | 
                           /* If n is not on any hash chain, prev[n] is garbage but
  | 
        
        
            | 
            | 
           1726 | 
                            * its value will never be used.
  | 
        
        
            | 
            | 
           1727 | 
                            */
  | 
        
        
            | 
            | 
           1728 | 
                       }
  | 
        
        
            | 
            | 
           1729 | 
                       more += WSIZE;
  | 
        
        
            | 
            | 
           1730 | 
                   }
  | 
        
        
            | 
            | 
           1731 | 
                   if (state.ds.eofile) return;
  | 
        
        
            | 
            | 
           1732 | 
              | 
        
        
            | 
            | 
           1733 | 
                   /* If there was no sliding:
  | 
        
        
            | 
            | 
           1734 | 
                    *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
  | 
        
        
            | 
            | 
           1735 | 
                    *    more == window_size - lookahead - strstart
  | 
        
        
            | 
            | 
           1736 | 
                    * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
  | 
        
        
            | 
            | 
           1737 | 
                    * => more >= window_size - 2*WSIZE + 2
  | 
        
        
            | 
            | 
           1738 | 
                    * In the MMAP or BIG_MEM case (not yet supported in gzip),
  | 
        
        
            | 
            | 
           1739 | 
                    *   window_size == input_size + MIN_LOOKAHEAD  &&
  | 
        
        
            | 
            | 
           1740 | 
                    *   strstart + lookahead <= input_size => more >= MIN_LOOKAHEAD.
  | 
        
        
            | 
            | 
           1741 | 
                    * Otherwise, window_size == 2*WSIZE so more >= 2.
  | 
        
        
            | 
            | 
           1742 | 
                    * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
  | 
        
        
            | 
            | 
           1743 | 
                    */
  | 
        
        
            | 
            | 
           1744 | 
                   Assert(state,more >= 2, "more < 2");
  | 
        
        
            | 
            | 
           1745 | 
              | 
        
        
            | 
            | 
           1746 | 
                   n = state.readfunc(state, (char*)state.ds.window+state.ds.strstart+state.ds.lookahead, more);
  | 
        
        
            | 
            | 
           1747 | 
              | 
        
        
            | 
            | 
           1748 | 
                   if (n == 0 || n == (unsigned)EOF) {
  | 
        
        
            | 
            | 
           1749 | 
                       state.ds.eofile = 1;
  | 
        
        
            | 
            | 
           1750 | 
                   } else {
  | 
        
        
            | 
            | 
           1751 | 
                       state.ds.lookahead += n;
  | 
        
        
            | 
            | 
           1752 | 
                   }
  | 
        
        
            | 
            | 
           1753 | 
               } while (state.ds.lookahead < MIN_LOOKAHEAD && !state.ds.eofile);
  | 
        
        
            | 
            | 
           1754 | 
           }
  | 
        
        
            | 
            | 
           1755 | 
              | 
        
        
            | 
            | 
           1756 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1757 | 
            * Flush the current block, with given end-of-file flag.
  | 
        
        
            | 
            | 
           1758 | 
            * IN assertion: strstart is set to the end of the current match.
  | 
        
        
            | 
            | 
           1759 | 
            */
  | 
        
        
            | 
            | 
           1760 | 
           #define FLUSH_BLOCK(state,eof) \
  | 
        
        
            | 
            | 
           1761 | 
              flush_block(state,state.ds.block_start >= 0L ? (char*)&state.ds.window[(unsigned)state.ds.block_start] : \
  | 
        
        
            | 
            | 
           1762 | 
                           (char*)NULL, (long)state.ds.strstart - state.ds.block_start, (eof))
  | 
        
        
            | 
            | 
           1763 | 
              | 
        
        
            | 
            | 
           1764 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1765 | 
            * Processes a new input file and return its compressed length. This
  | 
        
        
            | 
            | 
           1766 | 
            * function does not perform lazy evaluation of matches and inserts
  | 
        
        
            | 
            | 
           1767 | 
            * new strings in the dictionary only for unmatched strings or for short
  | 
        
        
            | 
            | 
           1768 | 
            * matches. It is used only for the fast compression options.
  | 
        
        
            | 
            | 
           1769 | 
            */
  | 
        
        
            | 
            | 
           1770 | 
           ulg deflate_fast(TState &state)
  | 
        
        
            | 
            | 
           1771 | 
           {
  | 
        
        
            | 
            | 
           1772 | 
               IPos hash_head = NIL;       /* head of the hash chain */
  | 
        
        
            | 
            | 
           1773 | 
               int flush;                  /* set if current block must be flushed */
  | 
        
        
            | 
            | 
           1774 | 
               unsigned match_length = 0;  /* length of best match */
  | 
        
        
            | 
            | 
           1775 | 
              | 
        
        
            | 
            | 
           1776 | 
               state.ds.prev_length = MIN_MATCH-1;
  | 
        
        
            | 
            | 
           1777 | 
               while (state.ds.lookahead != 0) {
  | 
        
        
            | 
            | 
           1778 | 
                   /* Insert the string window[strstart .. strstart+2] in the
  | 
        
        
            | 
            | 
           1779 | 
                    * dictionary, and set hash_head to the head of the hash chain:
  | 
        
        
            | 
            | 
           1780 | 
                    */
  | 
        
        
            | 
            | 
           1781 | 
                   if (state.ds.lookahead >= MIN_MATCH)
  | 
        
        
            | 
            | 
           1782 | 
                   INSERT_STRING(state.ds.strstart, hash_head);
  | 
        
        
            | 
            | 
           1783 | 
              | 
        
        
            | 
            | 
           1784 | 
                   /* Find the longest match, discarding those <= prev_length.
  | 
        
        
            | 
            | 
           1785 | 
                    * At this point we have always match_length < MIN_MATCH
  | 
        
        
            | 
            | 
           1786 | 
                    */
  | 
        
        
            | 
            | 
           1787 | 
                   if (hash_head != NIL && state.ds.strstart - hash_head <= MAX_DIST) {
  | 
        
        
            | 
            | 
           1788 | 
                       /* To simplify the code, we prevent matches with the string
  | 
        
        
            | 
            | 
           1789 | 
                        * of window index 0 (in particular we have to avoid a match
  | 
        
        
            | 
            | 
           1790 | 
                        * of the string with itself at the start of the input file).
  | 
        
        
            | 
            | 
           1791 | 
                        */
  | 
        
        
            | 
            | 
           1792 | 
                       /* Do not look for matches beyond the end of the input.
  | 
        
        
            | 
            | 
           1793 | 
                        * This is necessary to make deflate deterministic.
  | 
        
        
            | 
            | 
           1794 | 
                        */
  | 
        
        
            | 
            | 
           1795 | 
                       if ((unsigned)state.ds.nice_match > state.ds.lookahead) state.ds.nice_match = (int)state.ds.lookahead;
  | 
        
        
            | 
            | 
           1796 | 
                       match_length = longest_match (state,hash_head);
  | 
        
        
            | 
            | 
           1797 | 
                       /* longest_match() sets match_start */
  | 
        
        
            | 
            | 
           1798 | 
                       if (match_length > state.ds.lookahead) match_length = state.ds.lookahead;
  | 
        
        
            | 
            | 
           1799 | 
                   }
  | 
        
        
            | 
            | 
           1800 | 
                   if (match_length >= MIN_MATCH) {
  | 
        
        
            | 
            | 
           1801 | 
                       check_match(state,state.ds.strstart, state.ds.match_start, match_length);
  | 
        
        
            | 
            | 
           1802 | 
              | 
        
        
            | 
            | 
           1803 | 
                       flush = ct_tally(state,state.ds.strstart-state.ds.match_start, match_length - MIN_MATCH);
  | 
        
        
            | 
            | 
           1804 | 
              | 
        
        
            | 
            | 
           1805 | 
                       state.ds.lookahead -= match_length;
  | 
        
        
            | 
            | 
           1806 | 
              | 
        
        
            | 
            | 
           1807 | 
                       /* Insert new strings in the hash table only if the match length
  | 
        
        
            | 
            | 
           1808 | 
                        * is not too large. This saves time but degrades compression.
  | 
        
        
            | 
            | 
           1809 | 
                        */
  | 
        
        
            | 
            | 
           1810 | 
                       if (match_length <= state.ds.max_insert_length
  | 
        
        
            | 
            | 
           1811 | 
                           && state.ds.lookahead >= MIN_MATCH) {
  | 
        
        
            | 
            | 
           1812 | 
                           match_length--; /* string at strstart already in hash table */
  | 
        
        
            | 
            | 
           1813 | 
                           do {
  | 
        
        
            | 
            | 
           1814 | 
                               state.ds.strstart++;
  | 
        
        
            | 
            | 
           1815 | 
                               INSERT_STRING(state.ds.strstart, hash_head);
  | 
        
        
            | 
            | 
           1816 | 
                               /* strstart never exceeds WSIZE-MAX_MATCH, so there are
  | 
        
        
            | 
            | 
           1817 | 
                                * always MIN_MATCH bytes ahead.
  | 
        
        
            | 
            | 
           1818 | 
                                */
  | 
        
        
            | 
            | 
           1819 | 
                           } while (--match_length != 0);
  | 
        
        
            | 
            | 
           1820 | 
                           state.ds.strstart++;
  | 
        
        
            | 
            | 
           1821 | 
                       } else {
  | 
        
        
            | 
            | 
           1822 | 
                           state.ds.strstart += match_length;
  | 
        
        
            | 
            | 
           1823 | 
                           match_length = 0;
  | 
        
        
            | 
            | 
           1824 | 
                           state.ds.ins_h = state.ds.window[state.ds.strstart];
  | 
        
        
            | 
            | 
           1825 | 
                           UPDATE_HASH(state.ds.ins_h, state.ds.window[state.ds.strstart+1]);
  | 
        
        
            | 
            | 
           1826 | 
                           Assert(state,MIN_MATCH==3,"Call UPDATE_HASH() MIN_MATCH-3 more times");
  | 
        
        
            | 
            | 
           1827 | 
                       }
  | 
        
        
            | 
            | 
           1828 | 
                   } else {
  | 
        
        
            | 
            | 
           1829 | 
                       /* No match, output a literal byte */
  | 
        
        
            | 
            | 
           1830 | 
                       flush = ct_tally (state,0, state.ds.window[state.ds.strstart]);
  | 
        
        
            | 
            | 
           1831 | 
                       state.ds.lookahead--;
  | 
        
        
            | 
            | 
           1832 | 
                       state.ds.strstart++;
  | 
        
        
            | 
            | 
           1833 | 
                   }
  | 
        
        
            | 
            | 
           1834 | 
                   if (flush) FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart;
  | 
        
        
            | 
            | 
           1835 | 
              | 
        
        
            | 
            | 
           1836 | 
                   /* Make sure that we always have enough lookahead, except
  | 
        
        
            | 
            | 
           1837 | 
                    * at the end of the input file. We need MAX_MATCH bytes
  | 
        
        
            | 
            | 
           1838 | 
                    * for the next match, plus MIN_MATCH bytes to insert the
  | 
        
        
            | 
            | 
           1839 | 
                    * string following the next match.
  | 
        
        
            | 
            | 
           1840 | 
                    */
  | 
        
        
            | 
            | 
           1841 | 
                   if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state);
  | 
        
        
            | 
            | 
           1842 | 
               }
  | 
        
        
            | 
            | 
           1843 | 
               return FLUSH_BLOCK(state,1); /* eof */
  | 
        
        
            | 
            | 
           1844 | 
           }
  | 
        
        
            | 
            | 
           1845 | 
              | 
        
        
            | 
            | 
           1846 | 
           /* ===========================================================================
  | 
        
        
            | 
            | 
           1847 | 
            * Same as above, but achieves better compression. We use a lazy
  | 
        
        
            | 
            | 
           1848 | 
            * evaluation for matches: a match is finally adopted only if there is
  | 
        
        
            | 
            | 
           1849 | 
            * no better match at the next window position.
  | 
        
        
            | 
            | 
           1850 | 
            */
  | 
        
        
            | 
            | 
           1851 | 
           ulg deflate(TState &state)
  | 
        
        
            | 
            | 
           1852 | 
           {
  | 
        
        
            | 
            | 
           1853 | 
               IPos hash_head = NIL;       /* head of hash chain */
  | 
        
        
            | 
            | 
           1854 | 
               IPos prev_match;            /* previous match */
  | 
        
        
            | 
            | 
           1855 | 
               int flush;                  /* set if current block must be flushed */
  | 
        
        
            | 
            | 
           1856 | 
               int match_available = 0;    /* set if previous match exists */
  | 
        
        
            | 
            | 
           1857 | 
               register unsigned match_length = MIN_MATCH-1; /* length of best match */
  | 
        
        
            | 
            | 
           1858 | 
              | 
        
        
            | 
            | 
           1859 | 
               if (state.level <= 3) return deflate_fast(state); /* optimized for speed */
  | 
        
        
            | 
            | 
           1860 | 
              | 
        
        
            | 
            | 
           1861 | 
               /* Process the input block. */
  | 
        
        
            | 
            | 
           1862 | 
               while (state.ds.lookahead != 0) {
  | 
        
        
            | 
            | 
           1863 | 
                   /* Insert the string window[strstart .. strstart+2] in the
  | 
        
        
            | 
            | 
           1864 | 
                    * dictionary, and set hash_head to the head of the hash chain:
  | 
        
        
            | 
            | 
           1865 | 
                    */
  | 
        
        
            | 
            | 
           1866 | 
                   if (state.ds.lookahead >= MIN_MATCH)
  | 
        
        
            | 
            | 
           1867 | 
                   INSERT_STRING(state.ds.strstart, hash_head);
  | 
        
        
            | 
            | 
           1868 | 
              | 
        
        
            | 
            | 
           1869 | 
                   /* Find the longest match, discarding those <= prev_length.
  | 
        
        
            | 
            | 
           1870 | 
                    */
  | 
        
        
            | 
            | 
           1871 | 
                   state.ds.prev_length = match_length, prev_match = state.ds.match_start;
  | 
        
        
            | 
            | 
           1872 | 
                   match_length = MIN_MATCH-1;
  | 
        
        
            | 
            | 
           1873 | 
              | 
        
        
            | 
            | 
           1874 | 
                   if (hash_head != NIL && state.ds.prev_length < state.ds.max_lazy_match &&
  | 
        
        
            | 
            | 
           1875 | 
                       state.ds.strstart - hash_head <= MAX_DIST) {
  | 
        
        
            | 
            | 
           1876 | 
                       /* To simplify the code, we prevent matches with the string
  | 
        
        
            | 
            | 
           1877 | 
                        * of window index 0 (in particular we have to avoid a match
  | 
        
        
            | 
            | 
           1878 | 
                        * of the string with itself at the start of the input file).
  | 
        
        
            | 
            | 
           1879 | 
                        */
  | 
        
        
            | 
            | 
           1880 | 
                       /* Do not look for matches beyond the end of the input.
  | 
        
        
            | 
            | 
           1881 | 
                        * This is necessary to make deflate deterministic.
  | 
        
        
            | 
            | 
           1882 | 
                        */
  | 
        
        
            | 
            | 
           1883 | 
                       if ((unsigned)state.ds.nice_match > state.ds.lookahead) state.ds.nice_match = (int)state.ds.lookahead;
  | 
        
        
            | 
            | 
           1884 | 
                       match_length = longest_match (state,hash_head);
  | 
        
        
            | 
            | 
           1885 | 
                       /* longest_match() sets match_start */
  | 
        
        
            | 
            | 
           1886 | 
                       if (match_length > state.ds.lookahead) match_length = state.ds.lookahead;
  | 
        
        
            | 
            | 
           1887 | 
              | 
        
        
            | 
            | 
           1888 | 
                       /* Ignore a length 3 match if it is too distant: */
  | 
        
        
            | 
            | 
           1889 | 
                       if (match_length == MIN_MATCH && state.ds.strstart-state.ds.match_start > TOO_FAR){
  | 
        
        
            | 
            | 
           1890 | 
                           /* If prev_match is also MIN_MATCH, match_start is garbage
  | 
        
        
            | 
            | 
           1891 | 
                            * but we will ignore the current match anyway.
  | 
        
        
            | 
            | 
           1892 | 
                            */
  | 
        
        
            | 
            | 
           1893 | 
                           match_length = MIN_MATCH-1;
  | 
        
        
            | 
            | 
           1894 | 
                       }
  | 
        
        
            | 
            | 
           1895 | 
                   }
  | 
        
        
            | 
            | 
           1896 | 
                   /* If there was a match at the previous step and the current
  | 
        
        
            | 
            | 
           1897 | 
                    * match is not better, output the previous match:
  | 
        
        
            | 
            | 
           1898 | 
                    */
  | 
        
        
            | 
            | 
           1899 | 
                   if (state.ds.prev_length >= MIN_MATCH && match_length <= state.ds.prev_length) {
  | 
        
        
            | 
            | 
           1900 | 
                       unsigned max_insert = state.ds.strstart + state.ds.lookahead - MIN_MATCH;
  | 
        
        
            | 
            | 
           1901 | 
                       check_match(state,state.ds.strstart-1, prev_match, state.ds.prev_length);
  | 
        
        
            | 
            | 
           1902 | 
                       flush = ct_tally(state,state.ds.strstart-1-prev_match, state.ds.prev_length - MIN_MATCH);
  | 
        
        
            | 
            | 
           1903 | 
              | 
        
        
            | 
            | 
           1904 | 
                       /* Insert in hash table all strings up to the end of the match.
  | 
        
        
            | 
            | 
           1905 | 
                        * strstart-1 and strstart are already inserted.
  | 
        
        
            | 
            | 
           1906 | 
                        */
  | 
        
        
            | 
            | 
           1907 | 
                       state.ds.lookahead -= state.ds.prev_length-1;
  | 
        
        
            | 
            | 
           1908 | 
                       state.ds.prev_length -= 2;
  | 
        
        
            | 
            | 
           1909 | 
                       do {
  | 
        
        
            | 
            | 
           1910 | 
                           if (++state.ds.strstart <= max_insert) {
  | 
        
        
            | 
            | 
           1911 | 
                               INSERT_STRING(state.ds.strstart, hash_head);
  | 
        
        
            | 
            | 
           1912 | 
                               /* strstart never exceeds WSIZE-MAX_MATCH, so there are
  | 
        
        
            | 
            | 
           1913 | 
                                * always MIN_MATCH bytes ahead.
  | 
        
        
            | 
            | 
           1914 | 
                                */
  | 
        
        
            | 
            | 
           1915 | 
                           }
  | 
        
        
            | 
            | 
           1916 | 
                       } while (--state.ds.prev_length != 0);
  | 
        
        
            | 
            | 
           1917 | 
                       state.ds.strstart++;
  | 
        
        
            | 
            | 
           1918 | 
                       match_available = 0;
  | 
        
        
            | 
            | 
           1919 | 
                       match_length = MIN_MATCH-1;
  | 
        
        
            | 
            | 
           1920 | 
              | 
        
        
            | 
            | 
           1921 | 
                       if (flush) FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart;
  | 
        
        
            | 
            | 
           1922 | 
              | 
        
        
            | 
            | 
           1923 | 
                   } else if (match_available) {
  | 
        
        
            | 
            | 
           1924 | 
                       /* If there was no match at the previous position, output a
  | 
        
        
            | 
            | 
           1925 | 
                        * single literal. If there was a match but the current match
  | 
        
        
            | 
            | 
           1926 | 
                        * is longer, truncate the previous match to a single literal.
  | 
        
        
            | 
            | 
           1927 | 
                        */
  | 
        
        
            | 
            | 
           1928 | 
                       if (ct_tally (state,0, state.ds.window[state.ds.strstart-1])) {
  | 
        
        
            | 
            | 
           1929 | 
                           FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart;
  | 
        
        
            | 
            | 
           1930 | 
                       }
  | 
        
        
            | 
            | 
           1931 | 
                       state.ds.strstart++;
  | 
        
        
            | 
            | 
           1932 | 
                       state.ds.lookahead--;
  | 
        
        
            | 
            | 
           1933 | 
                   } else {
  | 
        
        
            | 
            | 
           1934 | 
                       /* There is no previous match to compare with, wait for
  | 
        
        
            | 
            | 
           1935 | 
                        * the next step to decide.
  | 
        
        
            | 
            | 
           1936 | 
                        */
  | 
        
        
            | 
            | 
           1937 | 
                       match_available = 1;
  | 
        
        
            | 
            | 
           1938 | 
                       state.ds.strstart++;
  | 
        
        
            | 
            | 
           1939 | 
                       state.ds.lookahead--;
  | 
        
        
            | 
            | 
           1940 | 
                   }
  | 
        
        
            | 
            | 
           1941 | 
           //        Assert(state,strstart <= isize && lookahead <= isize, "a bit too far");
  | 
        
        
            | 
            | 
           1942 | 
              | 
        
        
            | 
            | 
           1943 | 
                   /* Make sure that we always have enough lookahead, except
  | 
        
        
            | 
            | 
           1944 | 
                    * at the end of the input file. We need MAX_MATCH bytes
  | 
        
        
            | 
            | 
           1945 | 
                    * for the next match, plus MIN_MATCH bytes to insert the
  | 
        
        
            | 
            | 
           1946 | 
                    * string following the next match.
  | 
        
        
            | 
            | 
           1947 | 
                    */
  | 
        
        
            | 
            | 
           1948 | 
                   if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state);
  | 
        
        
            | 
            | 
           1949 | 
               }
  | 
        
        
            | 
            | 
           1950 | 
               if (match_available) ct_tally (state,0, state.ds.window[state.ds.strstart-1]);
  | 
        
        
            | 
            | 
           1951 | 
              | 
        
        
            | 
            | 
           1952 | 
               return FLUSH_BLOCK(state,1); /* eof */
  | 
        
        
            | 
            | 
           1953 | 
           }
  | 
        
        
            | 
            | 
           1954 | 
              | 
        
        
            | 
            | 
           1955 | 
              | 
        
        
            | 
            | 
           1956 | 
              | 
        
        
            | 
            | 
           1957 | 
              | 
        
        
            | 
            | 
           1958 | 
              | 
        
        
            | 
            | 
           1959 | 
              | 
        
        
            | 
            | 
           1960 | 
              | 
        
        
            | 
            | 
           1961 | 
              | 
        
        
            | 
            | 
           1962 | 
              | 
        
        
            | 
            | 
           1963 | 
              | 
        
        
            | 
            | 
           1964 | 
              | 
        
        
            | 
            | 
           1965 | 
              | 
        
        
            | 
            | 
           1966 | 
           int putlocal(struct zlist far *z, WRITEFUNC wfunc,void *param)
  | 
        
        
            | 
            | 
           1967 | 
           { // Write a local header described by *z to file *f.  Return a ZE_ error code.
  | 
        
        
            | 
            | 
           1968 | 
             PUTLG(LOCSIG, f);
  | 
        
        
            | 
            | 
           1969 | 
             PUTSH(z->ver, f);
  | 
        
        
            | 
            | 
           1970 | 
             PUTSH(z->lflg, f);
  | 
        
        
            | 
            | 
           1971 | 
             PUTSH(z->how, f);
  | 
        
        
            | 
            | 
           1972 | 
             PUTLG(z->tim, f);
  | 
        
        
            | 
            | 
           1973 | 
             PUTLG(z->crc, f);
  | 
        
        
            | 
            | 
           1974 | 
             PUTLG(z->siz, f);
  | 
        
        
            | 
            | 
           1975 | 
             PUTLG(z->len, f);
  | 
        
        
            | 
            | 
           1976 | 
             PUTSH(z->nam, f);
  | 
        
        
            | 
            | 
           1977 | 
             PUTSH(z->ext, f);
  | 
        
        
            | 
            | 
           1978 | 
             size_t res = (size_t)wfunc(param, z->iname, (unsigned int)z->nam);
  | 
        
        
            | 
            | 
           1979 | 
             if (res!=z->nam) return ZE_TEMP;
  | 
        
        
            | 
            | 
           1980 | 
             if (z->ext)
  | 
        
        
            | 
            | 
           1981 | 
             { res = (size_t)wfunc(param, z->extra, (unsigned int)z->ext);
  | 
        
        
            | 
            | 
           1982 | 
               if (res!=z->ext) return ZE_TEMP;
  | 
        
        
            | 
            | 
           1983 | 
             }
  | 
        
        
            | 
            | 
           1984 | 
             return ZE_OK;
  | 
        
        
            | 
            | 
           1985 | 
           }
  | 
        
        
            | 
            | 
           1986 | 
              | 
        
        
            | 
            | 
           1987 | 
           int putextended(struct zlist far *z, WRITEFUNC wfunc, void *param)
  | 
        
        
            | 
            | 
           1988 | 
           { // Write an extended local header described by *z to file *f. Returns a ZE_ code
  | 
        
        
            | 
            | 
           1989 | 
             PUTLG(EXTLOCSIG, f);
  | 
        
        
            | 
            | 
           1990 | 
             PUTLG(z->crc, f);
  | 
        
        
            | 
            | 
           1991 | 
             PUTLG(z->siz, f);
  | 
        
        
            | 
            | 
           1992 | 
             PUTLG(z->len, f);
  | 
        
        
            | 
            | 
           1993 | 
             return ZE_OK;
  | 
        
        
            | 
            | 
           1994 | 
           }
  | 
        
        
            | 
            | 
           1995 | 
              | 
        
        
            | 
            | 
           1996 | 
           int putcentral(struct zlist far *z, WRITEFUNC wfunc, void *param)
  | 
        
        
            | 
            | 
           1997 | 
           { // Write a central header entry of *z to file *f. Returns a ZE_ code.
  | 
        
        
            | 
            | 
           1998 | 
             PUTLG(CENSIG, f);
  | 
        
        
            | 
            | 
           1999 | 
             PUTSH(z->vem, f);
  | 
        
        
            | 
            | 
           2000 | 
             PUTSH(z->ver, f);
  | 
        
        
            | 
            | 
           2001 | 
             PUTSH(z->flg, f);
  | 
        
        
            | 
            | 
           2002 | 
             PUTSH(z->how, f);
  | 
        
        
            | 
            | 
           2003 | 
             PUTLG(z->tim, f);
  | 
        
        
            | 
            | 
           2004 | 
             PUTLG(z->crc, f);
  | 
        
        
            | 
            | 
           2005 | 
             PUTLG(z->siz, f);
  | 
        
        
            | 
            | 
           2006 | 
             PUTLG(z->len, f);
  | 
        
        
            | 
            | 
           2007 | 
             PUTSH(z->nam, f);
  | 
        
        
            | 
            | 
           2008 | 
             PUTSH(z->cext, f);
  | 
        
        
            | 
            | 
           2009 | 
             PUTSH(z->com, f);
  | 
        
        
            | 
            | 
           2010 | 
             PUTSH(z->dsk, f);
  | 
        
        
            | 
            | 
           2011 | 
             PUTSH(z->att, f);
  | 
        
        
            | 
            | 
           2012 | 
             PUTLG(z->atx, f);
  | 
        
        
            | 
            | 
           2013 | 
             PUTLG(z->off, f);
  | 
        
        
            | 
            | 
           2014 | 
             if ((size_t)wfunc(param, z->iname, (unsigned int)z->nam) != z->nam ||
  | 
        
        
            | 
            | 
           2015 | 
                 (z->cext && (size_t)wfunc(param, z->cextra, (unsigned int)z->cext) != z->cext) ||
  | 
        
        
            | 
            | 
           2016 | 
                 (z->com && (size_t)wfunc(param, z->comment, (unsigned int)z->com) != z->com))
  | 
        
        
            | 
            | 
           2017 | 
               return ZE_TEMP;
  | 
        
        
            | 
            | 
           2018 | 
             return ZE_OK;
  | 
        
        
            | 
            | 
           2019 | 
           }
  | 
        
        
            | 
            | 
           2020 | 
              | 
        
        
            | 
            | 
           2021 | 
              | 
        
        
            | 
            | 
           2022 | 
           int putend(int n, ulg s, ulg c, extent m, char *z, WRITEFUNC wfunc, void *param)
  | 
        
        
            | 
            | 
           2023 | 
           { // write the end of the central-directory-data to file *f.
  | 
        
        
            | 
            | 
           2024 | 
             PUTLG(ENDSIG, f);
  | 
        
        
            | 
            | 
           2025 | 
             PUTSH(0, f);
  | 
        
        
            | 
            | 
           2026 | 
             PUTSH(0, f);
  | 
        
        
            | 
            | 
           2027 | 
             PUTSH(n, f);
  | 
        
        
            | 
            | 
           2028 | 
             PUTSH(n, f);
  | 
        
        
            | 
            | 
           2029 | 
             PUTLG(s, f);
  | 
        
        
            | 
            | 
           2030 | 
             PUTLG(c, f);
  | 
        
        
            | 
            | 
           2031 | 
             PUTSH(m, f);
  | 
        
        
            | 
            | 
           2032 | 
             // Write the comment, if any
  | 
        
        
            | 
            | 
           2033 | 
             if (m && wfunc(param, z, (unsigned int)m) != m) return ZE_TEMP;
  | 
        
        
            | 
            | 
           2034 | 
             return ZE_OK;
  | 
        
        
            | 
            | 
           2035 | 
           }
  | 
        
        
            | 
            | 
           2036 | 
              | 
        
        
            | 
            | 
           2037 | 
              | 
        
        
            | 
            | 
           2038 | 
              | 
        
        
            | 
            | 
           2039 | 
              | 
        
        
            | 
            | 
           2040 | 
              | 
        
        
            | 
            | 
           2041 | 
              | 
        
        
            | 
            | 
           2042 | 
           const ulg crc_table[256] = {
  | 
        
        
            | 
            | 
           2043 | 
             0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  | 
        
        
            | 
            | 
           2044 | 
             0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  | 
        
        
            | 
            | 
           2045 | 
             0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  | 
        
        
            | 
            | 
           2046 | 
             0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  | 
        
        
            | 
            | 
           2047 | 
             0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  | 
        
        
            | 
            | 
           2048 | 
             0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  | 
        
        
            | 
            | 
           2049 | 
             0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  | 
        
        
            | 
            | 
           2050 | 
             0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  | 
        
        
            | 
            | 
           2051 | 
             0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  | 
        
        
            | 
            | 
           2052 | 
             0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  | 
        
        
            | 
            | 
           2053 | 
             0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  | 
        
        
            | 
            | 
           2054 | 
             0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  | 
        
        
            | 
            | 
           2055 | 
             0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  | 
        
        
            | 
            | 
           2056 | 
             0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  | 
        
        
            | 
            | 
           2057 | 
             0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  | 
        
        
            | 
            | 
           2058 | 
             0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  | 
        
        
            | 
            | 
           2059 | 
             0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  | 
        
        
            | 
            | 
           2060 | 
             0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  | 
        
        
            | 
            | 
           2061 | 
             0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  | 
        
        
            | 
            | 
           2062 | 
             0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  | 
        
        
            | 
            | 
           2063 | 
             0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  | 
        
        
            | 
            | 
           2064 | 
             0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  | 
        
        
            | 
            | 
           2065 | 
             0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  | 
        
        
            | 
            | 
           2066 | 
             0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  | 
        
        
            | 
            | 
           2067 | 
             0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  | 
        
        
            | 
            | 
           2068 | 
             0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  | 
        
        
            | 
            | 
           2069 | 
             0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  | 
        
        
            | 
            | 
           2070 | 
             0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  | 
        
        
            | 
            | 
           2071 | 
             0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  | 
        
        
            | 
            | 
           2072 | 
             0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  | 
        
        
            | 
            | 
           2073 | 
             0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  | 
        
        
            | 
            | 
           2074 | 
             0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  | 
        
        
            | 
            | 
           2075 | 
             0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  | 
        
        
            | 
            | 
           2076 | 
             0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  | 
        
        
            | 
            | 
           2077 | 
             0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  | 
        
        
            | 
            | 
           2078 | 
             0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  | 
        
        
            | 
            | 
           2079 | 
             0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  | 
        
        
            | 
            | 
           2080 | 
             0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  | 
        
        
            | 
            | 
           2081 | 
             0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  | 
        
        
            | 
            | 
           2082 | 
             0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  | 
        
        
            | 
            | 
           2083 | 
             0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  | 
        
        
            | 
            | 
           2084 | 
             0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  | 
        
        
            | 
            | 
           2085 | 
             0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  | 
        
        
            | 
            | 
           2086 | 
             0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  | 
        
        
            | 
            | 
           2087 | 
             0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  | 
        
        
            | 
            | 
           2088 | 
             0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  | 
        
        
            | 
            | 
           2089 | 
             0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  | 
        
        
            | 
            | 
           2090 | 
             0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  | 
        
        
            | 
            | 
           2091 | 
             0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  | 
        
        
            | 
            | 
           2092 | 
             0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  | 
        
        
            | 
            | 
           2093 | 
             0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  | 
        
        
            | 
            | 
           2094 | 
             0x2d02ef8dL
  | 
        
        
            | 
            | 
           2095 | 
           };
  | 
        
        
            | 
            | 
           2096 | 
              | 
        
        
            | 
            | 
           2097 | 
           #define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
  | 
        
        
            | 
            | 
           2098 | 
           #define DO1(buf)  crc = CRC32(crc, *buf++)
  | 
        
        
            | 
            | 
           2099 | 
           #define DO2(buf)  DO1(buf); DO1(buf)
  | 
        
        
            | 
            | 
           2100 | 
           #define DO4(buf)  DO2(buf); DO2(buf)
  | 
        
        
            | 
            | 
           2101 | 
           #define DO8(buf)  DO4(buf); DO4(buf)
  | 
        
        
            | 
            | 
           2102 | 
              | 
        
        
            | 
            | 
           2103 | 
           ulg crc32(ulg crc, const uch *buf, extent len)
  | 
        
        
            | 
            | 
           2104 | 
           { if (buf==NULL) return 0L;
  | 
        
        
            | 
            | 
           2105 | 
             crc = crc ^ 0xffffffffL;
  | 
        
        
            | 
            | 
           2106 | 
             while (len >= 8) {DO8(buf); len -= 8;}
  | 
        
        
            | 
            | 
           2107 | 
             if (len) do {DO1(buf);} while (--len);
  | 
        
        
            | 
            | 
           2108 | 
             return crc ^ 0xffffffffL;  // (instead of ~c for 64-bit machines)
  | 
        
        
            | 
            | 
           2109 | 
           }
  | 
        
        
            | 
            | 
           2110 | 
              | 
        
        
            | 
            | 
           2111 | 
              | 
        
        
            | 
            | 
           2112 | 
           void update_keys(unsigned long *keys, char c)
  | 
        
        
            | 
            | 
           2113 | 
           { keys[0] = CRC32(keys[0],c);
  | 
        
        
            | 
            | 
           2114 | 
             keys[1] += keys[0] & 0xFF;
  | 
        
        
            | 
            | 
           2115 | 
             keys[1] = keys[1]*134775813L +1;
  | 
        
        
            | 
            | 
           2116 | 
             keys[2] = CRC32(keys[2], keys[1] >> 24);
  | 
        
        
            | 
            | 
           2117 | 
           }
  | 
        
        
            | 
            | 
           2118 | 
           char decrypt_byte(unsigned long *keys)
  | 
        
        
            | 
            | 
           2119 | 
           { unsigned temp = ((unsigned)keys[2] & 0xffff) | 2;
  | 
        
        
            | 
            | 
           2120 | 
             return (char)(((temp * (temp ^ 1)) >> 8) & 0xff);
  | 
        
        
            | 
            | 
           2121 | 
           }
  | 
        
        
            | 
            | 
           2122 | 
           char zencode(unsigned long *keys, char c)
  | 
        
        
            | 
            | 
           2123 | 
           { int t=decrypt_byte(keys);
  | 
        
        
            | 
            | 
           2124 | 
             update_keys(keys,c);
  | 
        
        
            | 
            | 
           2125 | 
             return (char)(t^c);
  | 
        
        
            | 
            | 
           2126 | 
           }
  | 
        
        
            | 
            | 
           2127 | 
              | 
        
        
            | 
            | 
           2128 | 
              | 
        
        
            | 
            | 
           2129 | 
              | 
        
        
            | 
            | 
           2130 | 
              | 
        
        
            | 
            | 
           2131 | 
              | 
        
        
            | 
            | 
           2132 | 
              | 
        
        
            | 
            | 
           2133 | 
              | 
        
        
            | 
            | 
           2134 | 
           bool HasZipSuffix(const TCHAR *fn)
  | 
        
        
            | 
            | 
           2135 | 
           { const TCHAR *ext = fn+_tcslen(fn);
  | 
        
        
            | 
            | 
           2136 | 
             while (ext>fn && *ext!='.') ext--;
  | 
        
        
            | 
            | 
           2137 | 
             if (ext==fn && *ext!='.') return false;
  | 
        
        
            | 
            | 
           2138 | 
             if (_tcsicmp(ext,_T(".Z"))==0) return true;
  | 
        
        
            | 
            | 
           2139 | 
             if (_tcsicmp(ext,_T(".zip"))==0) return true;
  | 
        
        
            | 
            | 
           2140 | 
             if (_tcsicmp(ext,_T(".zoo"))==0) return true;
  | 
        
        
            | 
            | 
           2141 | 
             if (_tcsicmp(ext,_T(".arc"))==0) return true;
  | 
        
        
            | 
            | 
           2142 | 
             if (_tcsicmp(ext,_T(".lzh"))==0) return true;
  | 
        
        
            | 
            | 
           2143 | 
             if (_tcsicmp(ext,_T(".arj"))==0) return true;
  | 
        
        
            | 
            | 
           2144 | 
             if (_tcsicmp(ext,_T(".gz"))==0) return true;
  | 
        
        
            | 
            | 
           2145 | 
             if (_tcsicmp(ext,_T(".tgz"))==0) return true;
  | 
        
        
            | 
            | 
           2146 | 
             return false;
  | 
        
        
            | 
            | 
           2147 | 
           }
  | 
        
        
            | 
            | 
           2148 | 
              | 
        
        
            | 
            | 
           2149 | 
              | 
        
        
            | 
            | 
           2150 | 
           lutime_t filetime2timet(const FILETIME ft)
  | 
        
        
            | 
            | 
           2151 | 
           { __int64 i = *(__int64*)&ft;
  | 
        
        
            | 
            | 
           2152 | 
             return (lutime_t)((i-116444736000000000)/10000000);
  | 
        
        
            | 
            | 
           2153 | 
           }
  | 
        
        
            | 
            | 
           2154 | 
              | 
        
        
            | 
            | 
           2155 | 
           void filetime2dosdatetime(const FILETIME ft, WORD *dosdate,WORD *dostime)
  | 
        
        
            | 
            | 
           2156 | 
           { // date: bits 0-4 are day of month 1-31. Bits 5-8 are month 1..12. Bits 9-15 are year-1980
  | 
        
        
            | 
            | 
           2157 | 
             // time: bits 0-4 are seconds/2, bits 5-10 are minute 0..59. Bits 11-15 are hour 0..23
  | 
        
        
            | 
            | 
           2158 | 
             SYSTEMTIME st; FileTimeToSystemTime(&ft,&st); 
  | 
        
        
            | 
            | 
           2159 | 
             *dosdate = (WORD)(((st.wYear-1980)&0x7f) << 9);
  | 
        
        
            | 
            | 
           2160 | 
             *dosdate |= (WORD)((st.wMonth&0xf) << 5);
  | 
        
        
            | 
            | 
           2161 | 
             *dosdate |= (WORD)((st.wDay&0x1f));
  | 
        
        
            | 
            | 
           2162 | 
             *dostime = (WORD)((st.wHour&0x1f) << 11);
  | 
        
        
            | 
            | 
           2163 | 
             *dostime |= (WORD)((st.wMinute&0x3f) << 5);
  | 
        
        
            | 
            | 
           2164 | 
             *dostime |= (WORD)((st.wSecond*2)&0x1f);
  | 
        
        
            | 
            | 
           2165 | 
           }
  | 
        
        
            | 
            | 
           2166 | 
              | 
        
        
            | 
            | 
           2167 | 
              | 
        
        
            | 
            | 
           2168 | 
           ZRESULT GetFileInfo(HANDLE hf, ulg *attr, long *size, iztimes *times, ulg *timestamp)
  | 
        
        
            | 
            | 
           2169 | 
           { // The handle must be a handle to a file
  | 
        
        
            | 
            | 
           2170 | 
             // The date and time is returned in a long with the date most significant to allow
  | 
        
        
            | 
            | 
           2171 | 
             // unsigned integer comparison of absolute times. The attributes have two
  | 
        
        
            | 
            | 
           2172 | 
             // high bytes unix attr, and two low bytes a mapping of that to DOS attr.
  | 
        
        
            | 
            | 
           2173 | 
             //struct stat s; int res=stat(fn,&s); if (res!=0) return false;
  | 
        
        
            | 
            | 
           2174 | 
             // translate windows file attributes into zip ones.
  | 
        
        
            | 
            | 
           2175 | 
             BY_HANDLE_FILE_INFORMATION bhi; BOOL res=GetFileInformationByHandle(hf,&bhi);
  | 
        
        
            | 
            | 
           2176 | 
             if (!res) return ZR_NOFILE;
  | 
        
        
            | 
            | 
           2177 | 
             DWORD fa=bhi.dwFileAttributes; ulg a=0;
  | 
        
        
            | 
            | 
           2178 | 
             // Zip uses the lower word for its interpretation of windows stuff
  | 
        
        
            | 
            | 
           2179 | 
             if (fa&FILE_ATTRIBUTE_READONLY) a|=0x01;
  | 
        
        
            | 
            | 
           2180 | 
             if (fa&FILE_ATTRIBUTE_HIDDEN)   a|=0x02;
  | 
        
        
            | 
            | 
           2181 | 
             if (fa&FILE_ATTRIBUTE_SYSTEM)   a|=0x04;
  | 
        
        
            | 
            | 
           2182 | 
             if (fa&FILE_ATTRIBUTE_DIRECTORY)a|=0x10;
  | 
        
        
            | 
            | 
           2183 | 
             if (fa&FILE_ATTRIBUTE_ARCHIVE)  a|=0x20;
  | 
        
        
            | 
            | 
           2184 | 
             // It uses the upper word for standard unix attr, which we manually construct
  | 
        
        
            | 
            | 
           2185 | 
             if (fa&FILE_ATTRIBUTE_DIRECTORY)a|=0x40000000;  // directory
  | 
        
        
            | 
            | 
           2186 | 
             else a|=0x80000000;  // normal file
  | 
        
        
            | 
            | 
           2187 | 
             a|=0x01000000;      // readable
  | 
        
        
            | 
            | 
           2188 | 
             if (fa&FILE_ATTRIBUTE_READONLY) {} else a|=0x00800000; // writeable
  | 
        
        
            | 
            | 
           2189 | 
             // now just a small heuristic to check if it's an executable:
  | 
        
        
            | 
            | 
           2190 | 
             DWORD red, hsize=GetFileSize(hf,NULL); if (hsize>40)
  | 
        
        
            | 
            | 
           2191 | 
             { SetFilePointer(hf,0,NULL,FILE_BEGIN); unsigned short magic; ReadFile(hf,&magic,sizeof(magic),&red,NULL);
  | 
        
        
            | 
            | 
           2192 | 
               SetFilePointer(hf,36,NULL,FILE_BEGIN); unsigned long hpos;  ReadFile(hf,&hpos,sizeof(hpos),&red,NULL);
  | 
        
        
            | 
            | 
           2193 | 
               if (magic==0x54AD && hsize>hpos+4+20+28)
  | 
        
        
            | 
            | 
           2194 | 
               { SetFilePointer(hf,hpos,NULL,FILE_BEGIN); unsigned long signature; ReadFile(hf,&signature,sizeof(signature),&red,NULL);
  | 
        
        
            | 
            | 
           2195 | 
                 if (signature==IMAGE_DOS_SIGNATURE || signature==IMAGE_OS2_SIGNATURE
  | 
        
        
            | 
            | 
           2196 | 
                    || signature==IMAGE_OS2_SIGNATURE_LE || signature==IMAGE_NT_SIGNATURE)
  | 
        
        
            | 
            | 
           2197 | 
                 { a |= 0x00400000; // executable
  | 
        
        
            | 
            | 
           2198 | 
                 }
  | 
        
        
            | 
            | 
           2199 | 
               }
  | 
        
        
            | 
            | 
           2200 | 
             }
  | 
        
        
            | 
            | 
           2201 | 
             //
  | 
        
        
            | 
            | 
           2202 | 
             if (attr!=NULL) *attr = a;
  | 
        
        
            | 
            | 
           2203 | 
             if (size!=NULL) *size = hsize;
  | 
        
        
            | 
            | 
           2204 | 
             if (times!=NULL)
  | 
        
        
            | 
            | 
           2205 | 
             { // lutime_t is 32bit number of seconds elapsed since 0:0:0GMT, Jan1, 1970.
  | 
        
        
            | 
            | 
           2206 | 
               // but FILETIME is 64bit number of 100-nanosecs since Jan1, 1601
  | 
        
        
            | 
            | 
           2207 | 
               times->atime = filetime2timet(bhi.ftLastAccessTime);
  | 
        
        
            | 
            | 
           2208 | 
               times->mtime = filetime2timet(bhi.ftLastWriteTime);
  | 
        
        
            | 
            | 
           2209 | 
               times->ctime = filetime2timet(bhi.ftCreationTime);
  | 
        
        
            | 
            | 
           2210 | 
             }
  | 
        
        
            | 
            | 
           2211 | 
             if (timestamp!=NULL)
  | 
        
        
            | 
            | 
           2212 | 
             { WORD dosdate,dostime;
  | 
        
        
            | 
            | 
           2213 | 
               filetime2dosdatetime(bhi.ftLastWriteTime,&dosdate,&dostime);
  | 
        
        
            | 
            | 
           2214 | 
               *timestamp = (WORD)dostime | (((DWORD)dosdate)<<16);
  | 
        
        
            | 
            | 
           2215 | 
             }
  | 
        
        
            | 
            | 
           2216 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2217 | 
           }
  | 
        
        
            | 
            | 
           2218 | 
              | 
        
        
            | 
            | 
           2219 | 
              | 
        
        
            | 
            | 
           2220 | 
              | 
        
        
            | 
            | 
           2221 | 
              | 
        
        
            | 
            | 
           2222 | 
              | 
        
        
            | 
            | 
           2223 | 
              | 
        
        
            | 
            | 
           2224 | 
              | 
        
        
            | 
            | 
           2225 | 
              | 
        
        
            | 
            | 
           2226 | 
           class TZip
  | 
        
        
            | 
            | 
           2227 | 
           { public:
  | 
        
        
            | 
            | 
           2228 | 
             TZip(const char *pwd) : hfout(0),mustclosehfout(false),hmapout(0),zfis(0),obuf(0),hfin(0),writ(0),oerr(false),hasputcen(false),ooffset(0),encwriting(false),encbuf(0),password(0), state(0) {if (pwd!=0 && *pwd!=0) {password=new char[strlen(pwd)+1]; strcpy(password,pwd);}}
  | 
        
        
            | 
            | 
           2229 | 
             ~TZip() {if (state!=0) delete state; state=0; if (encbuf!=0) delete[] encbuf; encbuf=0; if (password!=0) delete[] password; password=0;}
  | 
        
        
            | 
            | 
           2230 | 
              | 
        
        
            | 
            | 
           2231 | 
             // These variables say about the file we're writing into
  | 
        
        
            | 
            | 
           2232 | 
             // We can write to pipe, file-by-handle, file-by-name, memory-to-memmapfile
  | 
        
        
            | 
            | 
           2233 | 
             char *password;           // keep a copy of the password
  | 
        
        
            | 
            | 
           2234 | 
             HANDLE hfout;             // if valid, we'll write here (for files or pipes)
  | 
        
        
            | 
            | 
           2235 | 
             bool mustclosehfout;      // if true, we are responsible for closing hfout
  | 
        
        
            | 
            | 
           2236 | 
             HANDLE hmapout;           // otherwise, we'll write here (for memmap)
  | 
        
        
            | 
            | 
           2237 | 
             unsigned ooffset;         // for hfout, this is where the pointer was initially
  | 
        
        
            | 
            | 
           2238 | 
             ZRESULT oerr;             // did a write operation give rise to an error?
  | 
        
        
            | 
            | 
           2239 | 
             unsigned writ;            // how far have we written. This is maintained by Add, not write(), to avoid confusion over seeks
  | 
        
        
            | 
            | 
           2240 | 
             bool ocanseek;            // can we seek?
  | 
        
        
            | 
            | 
           2241 | 
             char *obuf;               // this is where we've locked mmap to view.
  | 
        
        
            | 
            | 
           2242 | 
             unsigned int opos;        // current pos in the mmap
  | 
        
        
            | 
            | 
           2243 | 
             unsigned int mapsize;     // the size of the map we created
  | 
        
        
            | 
            | 
           2244 | 
             bool hasputcen;           // have we yet placed the central directory?
  | 
        
        
            | 
            | 
           2245 | 
             bool encwriting;          // if true, then we'll encrypt stuff using 'keys' before we write it to disk
  | 
        
        
            | 
            | 
           2246 | 
             unsigned long keys[3];    // keys are initialised inside Add()
  | 
        
        
            | 
            | 
           2247 | 
             char *encbuf;             // if encrypting, then this is a temporary workspace for encrypting the data
  | 
        
        
            | 
            | 
           2248 | 
             unsigned int encbufsize;  // (to be used and resized inside write(), and deleted in the destructor)
  | 
        
        
            | 
            | 
           2249 | 
             //
  | 
        
        
            | 
            | 
           2250 | 
             TZipFileInfo *zfis;       // each file gets added onto this list, for writing the table at the end
  | 
        
        
            | 
            | 
           2251 | 
             TState *state;            // we use just one state object per zip, because it's big (500k)
  | 
        
        
            | 
            | 
           2252 | 
              | 
        
        
            | 
            | 
           2253 | 
             ZRESULT Create(void *z,unsigned int len,DWORD flags);
  | 
        
        
            | 
            | 
           2254 | 
             static unsigned sflush(void *param,const char *buf, unsigned *size);
  | 
        
        
            | 
            | 
           2255 | 
             static unsigned swrite(void *param,const char *buf, unsigned size);
  | 
        
        
            | 
            | 
           2256 | 
             unsigned int write(const char *buf,unsigned int size);
  | 
        
        
            | 
            | 
           2257 | 
             bool oseek(unsigned int pos);
  | 
        
        
            | 
            | 
           2258 | 
             ZRESULT GetMemory(void **pbuf, unsigned long *plen);
  | 
        
        
            | 
            | 
           2259 | 
             ZRESULT Close();
  | 
        
        
            | 
            | 
           2260 | 
              | 
        
        
            | 
            | 
           2261 | 
             // some variables to do with the file currently being read:
  | 
        
        
            | 
            | 
           2262 | 
             // I haven't done it object-orientedly here, just put them all
  | 
        
        
            | 
            | 
           2263 | 
             // together, since OO didn't seem to make the design any clearer.
  | 
        
        
            | 
            | 
           2264 | 
             ulg attr; iztimes times; ulg timestamp;  // all open_* methods set these
  | 
        
        
            | 
            | 
           2265 | 
             bool iseekable; long isize,ired;         // size is not set until close() on pips
  | 
        
        
            | 
            | 
           2266 | 
             ulg crc;                                 // crc is not set until close(). iwrit is cumulative
  | 
        
        
            | 
            | 
           2267 | 
             HANDLE hfin; bool selfclosehf;           // for input files and pipes
  | 
        
        
            | 
            | 
           2268 | 
             const char *bufin; unsigned int lenin,posin; // for memory
  | 
        
        
            | 
            | 
           2269 | 
             // and a variable for what we've done with the input: (i.e. compressed it!)
  | 
        
        
            | 
            | 
           2270 | 
             ulg csize;                               // compressed size, set by the compression routines
  | 
        
        
            | 
            | 
           2271 | 
             // and this is used by some of the compression routines
  | 
        
        
            | 
            | 
           2272 | 
             char buf[16384];
  | 
        
        
            | 
            | 
           2273 | 
              | 
        
        
            | 
            | 
           2274 | 
              | 
        
        
            | 
            | 
           2275 | 
             ZRESULT open_file(const TCHAR *fn);
  | 
        
        
            | 
            | 
           2276 | 
             ZRESULT open_handle(HANDLE hf,unsigned int len);
  | 
        
        
            | 
            | 
           2277 | 
             ZRESULT open_mem(void *src,unsigned int len);
  | 
        
        
            | 
            | 
           2278 | 
             ZRESULT open_dir();
  | 
        
        
            | 
            | 
           2279 | 
             static unsigned sread(TState &s,char *buf,unsigned size);
  | 
        
        
            | 
            | 
           2280 | 
             unsigned read(char *buf, unsigned size);
  | 
        
        
            | 
            | 
           2281 | 
             ZRESULT iclose();
  | 
        
        
            | 
            | 
           2282 | 
              | 
        
        
            | 
            | 
           2283 | 
             ZRESULT ideflate(TZipFileInfo *zfi);
  | 
        
        
            | 
            | 
           2284 | 
             ZRESULT istore();
  | 
        
        
            | 
            | 
           2285 | 
              | 
        
        
            | 
            | 
           2286 | 
             ZRESULT Add(const TCHAR *odstzn, void *src,unsigned int len, DWORD flags);
  | 
        
        
            | 
            | 
           2287 | 
             ZRESULT AddCentral();
  | 
        
        
            | 
            | 
           2288 | 
              | 
        
        
            | 
            | 
           2289 | 
           };
  | 
        
        
            | 
            | 
           2290 | 
              | 
        
        
            | 
            | 
           2291 | 
              | 
        
        
            | 
            | 
           2292 | 
              | 
        
        
            | 
            | 
           2293 | 
           ZRESULT TZip::Create(void *z,unsigned int len,DWORD flags)
  | 
        
        
            | 
            | 
           2294 | 
           { if (hfout!=0 || hmapout!=0 || obuf!=0 || writ!=0 || oerr!=ZR_OK || hasputcen) return ZR_NOTINITED;
  | 
        
        
            | 
            | 
           2295 | 
             //
  | 
        
        
            | 
            | 
           2296 | 
             if (flags==ZIP_HANDLE)
  | 
        
        
            | 
            | 
           2297 | 
             { HANDLE hf = (HANDLE)z;
  | 
        
        
            | 
            | 
           2298 | 
               hfout=hf; mustclosehfout=false;
  | 
        
        
            | 
            | 
           2299 | 
           #ifdef DuplicateHandle
  | 
        
        
            | 
            | 
           2300 | 
               BOOL res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&hfout,0,FALSE,DUPLICATE_SAME_ACCESS);
  | 
        
        
            | 
            | 
           2301 | 
               if (res) mustclosehandle=true;
  | 
        
        
            | 
            | 
           2302 | 
           #endif
  | 
        
        
            | 
            | 
           2303 | 
               // now we have hfout. Either we duplicated the handle and we close it ourselves
  | 
        
        
            | 
            | 
           2304 | 
               // (while the caller closes h themselves), or we couldn't duplicate it.
  | 
        
        
            | 
            | 
           2305 | 
               DWORD res = SetFilePointer(hfout,0,0,FILE_CURRENT);
  | 
        
        
            | 
            | 
           2306 | 
               ocanseek = (res!=0xFFFFFFFF);
  | 
        
        
            | 
            | 
           2307 | 
               if (ocanseek) ooffset=res; else ooffset=0;
  | 
        
        
            | 
            | 
           2308 | 
               return ZR_OK;
  | 
        
        
            | 
            | 
           2309 | 
             }
  | 
        
        
            | 
            | 
           2310 | 
             else if (flags==ZIP_FILENAME)
  | 
        
        
            | 
            | 
           2311 | 
             { const TCHAR *fn = (const TCHAR*)z;
  | 
        
        
            | 
            | 
           2312 | 
               hfout = CreateFile(fn,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  | 
        
        
            | 
            | 
           2313 | 
               if (hfout==INVALID_HANDLE_VALUE) {hfout=0; return ZR_NOFILE;}
  | 
        
        
            | 
            | 
           2314 | 
               ocanseek=true;
  | 
        
        
            | 
            | 
           2315 | 
               ooffset=0;
  | 
        
        
            | 
            | 
           2316 | 
               mustclosehfout=true;
  | 
        
        
            | 
            | 
           2317 | 
               return ZR_OK;
  | 
        
        
            | 
            | 
           2318 | 
             }
  | 
        
        
            | 
            | 
           2319 | 
             else if (flags==ZIP_MEMORY)
  | 
        
        
            | 
            | 
           2320 | 
             { unsigned int size = len;
  | 
        
        
            | 
            | 
           2321 | 
               if (size==0) return ZR_MEMSIZE;
  | 
        
        
            | 
            | 
           2322 | 
               if (z!=0) obuf=(char*)z;
  | 
        
        
            | 
            | 
           2323 | 
               else
  | 
        
        
            | 
            | 
           2324 | 
               { hmapout = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,size,NULL);
  | 
        
        
            | 
            | 
           2325 | 
                 if (hmapout==NULL) return ZR_NOALLOC;
  | 
        
        
            | 
            | 
           2326 | 
                 obuf = (char*)MapViewOfFile(hmapout,FILE_MAP_ALL_ACCESS,0,0,size);
  | 
        
        
            | 
            | 
           2327 | 
                 if (obuf==0) {CloseHandle(hmapout); hmapout=0; return ZR_NOALLOC;}
  | 
        
        
            | 
            | 
           2328 | 
               }
  | 
        
        
            | 
            | 
           2329 | 
               ocanseek=true;
  | 
        
        
            | 
            | 
           2330 | 
               opos=0; mapsize=size;
  | 
        
        
            | 
            | 
           2331 | 
               return ZR_OK;
  | 
        
        
            | 
            | 
           2332 | 
             }
  | 
        
        
            | 
            | 
           2333 | 
             else return ZR_ARGS;
  | 
        
        
            | 
            | 
           2334 | 
           }
  | 
        
        
            | 
            | 
           2335 | 
              | 
        
        
            | 
            | 
           2336 | 
           unsigned TZip::sflush(void *param,const char *buf, unsigned *size)
  | 
        
        
            | 
            | 
           2337 | 
           { // static
  | 
        
        
            | 
            | 
           2338 | 
             if (*size==0) return 0;
  | 
        
        
            | 
            | 
           2339 | 
             TZip *zip = (TZip*)param;
  | 
        
        
            | 
            | 
           2340 | 
             unsigned int writ = zip->write(buf,*size);
  | 
        
        
            | 
            | 
           2341 | 
             if (writ!=0) *size=0;
  | 
        
        
            | 
            | 
           2342 | 
             return writ;
  | 
        
        
            | 
            | 
           2343 | 
           }
  | 
        
        
            | 
            | 
           2344 | 
           unsigned TZip::swrite(void *param,const char *buf, unsigned size)
  | 
        
        
            | 
            | 
           2345 | 
           { // static
  | 
        
        
            | 
            | 
           2346 | 
             if (size==0) return 0;
  | 
        
        
            | 
            | 
           2347 | 
             TZip *zip=(TZip*)param; return zip->write(buf,size);
  | 
        
        
            | 
            | 
           2348 | 
           }
  | 
        
        
            | 
            | 
           2349 | 
           unsigned int TZip::write(const char *buf,unsigned int size)
  | 
        
        
            | 
            | 
           2350 | 
           { const char *srcbuf=buf;
  | 
        
        
            | 
            | 
           2351 | 
             if (encwriting)
  | 
        
        
            | 
            | 
           2352 | 
             { if (encbuf!=0 && encbufsize<size) {delete[] encbuf; encbuf=0;}
  | 
        
        
            | 
            | 
           2353 | 
               if (encbuf==0) {encbuf=new char[size*2]; encbufsize=size;}
  | 
        
        
            | 
            | 
           2354 | 
               memcpy(encbuf,buf,size);
  | 
        
        
            | 
            | 
           2355 | 
               for (unsigned int i=0; i<size; i++) encbuf[i]=zencode(keys,encbuf[i]);
  | 
        
        
            | 
            | 
           2356 | 
               srcbuf=encbuf;
  | 
        
        
            | 
            | 
           2357 | 
             }
  | 
        
        
            | 
            | 
           2358 | 
             if (obuf!=0)
  | 
        
        
            | 
            | 
           2359 | 
             { if (opos+size>=mapsize) {oerr=ZR_MEMSIZE; return 0;}
  | 
        
        
            | 
            | 
           2360 | 
               memcpy(obuf+opos, srcbuf, size);
  | 
        
        
            | 
            | 
           2361 | 
               opos+=size;
  | 
        
        
            | 
            | 
           2362 | 
               return size;
  | 
        
        
            | 
            | 
           2363 | 
             }
  | 
        
        
            | 
            | 
           2364 | 
             else if (hfout!=0)
  | 
        
        
            | 
            | 
           2365 | 
             { DWORD writ; WriteFile(hfout,srcbuf,size,&writ,NULL);
  | 
        
        
            | 
            | 
           2366 | 
               return writ;
  | 
        
        
            | 
            | 
           2367 | 
             }
  | 
        
        
            | 
            | 
           2368 | 
             oerr=ZR_NOTINITED; return 0;
  | 
        
        
            | 
            | 
           2369 | 
           }
  | 
        
        
            | 
            | 
           2370 | 
              | 
        
        
            | 
            | 
           2371 | 
           bool TZip::oseek(unsigned int pos)
  | 
        
        
            | 
            | 
           2372 | 
           { if (!ocanseek) {oerr=ZR_SEEK; return false;}
  | 
        
        
            | 
            | 
           2373 | 
             if (obuf!=0)
  | 
        
        
            | 
            | 
           2374 | 
             { if (pos>=mapsize) {oerr=ZR_MEMSIZE; return false;}
  | 
        
        
            | 
            | 
           2375 | 
               opos=pos;
  | 
        
        
            | 
            | 
           2376 | 
               return true;
  | 
        
        
            | 
            | 
           2377 | 
             }
  | 
        
        
            | 
            | 
           2378 | 
             else if (hfout!=0)
  | 
        
        
            | 
            | 
           2379 | 
             { SetFilePointer(hfout,pos+ooffset,NULL,FILE_BEGIN);
  | 
        
        
            | 
            | 
           2380 | 
               return true;
  | 
        
        
            | 
            | 
           2381 | 
             }
  | 
        
        
            | 
            | 
           2382 | 
             oerr=ZR_NOTINITED; return 0;
  | 
        
        
            | 
            | 
           2383 | 
           }
  | 
        
        
            | 
            | 
           2384 | 
              | 
        
        
            | 
            | 
           2385 | 
           ZRESULT TZip::GetMemory(void **pbuf, unsigned long *plen)
  | 
        
        
            | 
            | 
           2386 | 
           { // When the user calls GetMemory, they're presumably at the end
  | 
        
        
            | 
            | 
           2387 | 
             // of all their adding. In any case, we have to add the central
  | 
        
        
            | 
            | 
           2388 | 
             // directory now, otherwise the memory we tell them won't be complete.
  | 
        
        
            | 
            | 
           2389 | 
             if (!hasputcen) AddCentral(); hasputcen=true;
  | 
        
        
            | 
            | 
           2390 | 
             if (pbuf!=NULL) *pbuf=(void*)obuf;
  | 
        
        
            | 
            | 
           2391 | 
             if (plen!=NULL) *plen=writ;
  | 
        
        
            | 
            | 
           2392 | 
             if (obuf==NULL) return ZR_NOTMMAP;
  | 
        
        
            | 
            | 
           2393 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2394 | 
           }
  | 
        
        
            | 
            | 
           2395 | 
              | 
        
        
            | 
            | 
           2396 | 
           ZRESULT TZip::Close()
  | 
        
        
            | 
            | 
           2397 | 
           { // if the directory hadn't already been added through a call to GetMemory,
  | 
        
        
            | 
            | 
           2398 | 
             // then we do it now
  | 
        
        
            | 
            | 
           2399 | 
             ZRESULT res=ZR_OK; if (!hasputcen) res=AddCentral(); hasputcen=true;
  | 
        
        
            | 
            | 
           2400 | 
             if (obuf!=0 && hmapout!=0) UnmapViewOfFile(obuf); obuf=0;
  | 
        
        
            | 
            | 
           2401 | 
             if (hmapout!=0) CloseHandle(hmapout); hmapout=0;
  | 
        
        
            | 
            | 
           2402 | 
             if (hfout!=0 && mustclosehfout) CloseHandle(hfout); hfout=0; mustclosehfout=false;
  | 
        
        
            | 
            | 
           2403 | 
             return res;
  | 
        
        
            | 
            | 
           2404 | 
           }
  | 
        
        
            | 
            | 
           2405 | 
              | 
        
        
            | 
            | 
           2406 | 
              | 
        
        
            | 
            | 
           2407 | 
              | 
        
        
            | 
            | 
           2408 | 
              | 
        
        
            | 
            | 
           2409 | 
           ZRESULT TZip::open_file(const TCHAR *fn)
  | 
        
        
            | 
            | 
           2410 | 
           { hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0;
  | 
        
        
            | 
            | 
           2411 | 
             if (fn==0) return ZR_ARGS;
  | 
        
        
            | 
            | 
           2412 | 
             HANDLE hf = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
  | 
        
        
            | 
            | 
           2413 | 
             if (hf==INVALID_HANDLE_VALUE) return ZR_NOFILE;
  | 
        
        
            | 
            | 
           2414 | 
             ZRESULT res = open_handle(hf,0);
  | 
        
        
            | 
            | 
           2415 | 
             if (res!=ZR_OK) {CloseHandle(hf); return res;}
  | 
        
        
            | 
            | 
           2416 | 
             selfclosehf=true;
  | 
        
        
            | 
            | 
           2417 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2418 | 
           }
  | 
        
        
            | 
            | 
           2419 | 
           ZRESULT TZip::open_handle(HANDLE hf,unsigned int len)
  | 
        
        
            | 
            | 
           2420 | 
           { hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0;
  | 
        
        
            | 
            | 
           2421 | 
             if (hf==0 || hf==INVALID_HANDLE_VALUE) return ZR_ARGS;
  | 
        
        
            | 
            | 
           2422 | 
             DWORD res = SetFilePointer(hfout,0,0,FILE_CURRENT);
  | 
        
        
            | 
            | 
           2423 | 
             if (res!=0xFFFFFFFF)
  | 
        
        
            | 
            | 
           2424 | 
             { ZRESULT res = GetFileInfo(hf,&attr,&isize,×,×tamp);
  | 
        
        
            | 
            | 
           2425 | 
               if (res!=ZR_OK) return res;
  | 
        
        
            | 
            | 
           2426 | 
               SetFilePointer(hf,0,NULL,FILE_BEGIN); // because GetFileInfo will have screwed it up
  | 
        
        
            | 
            | 
           2427 | 
               iseekable=true; hfin=hf;
  | 
        
        
            | 
            | 
           2428 | 
               return ZR_OK;
  | 
        
        
            | 
            | 
           2429 | 
             }
  | 
        
        
            | 
            | 
           2430 | 
             else
  | 
        
        
            | 
            | 
           2431 | 
             { attr= 0x80000000;      // just a normal file
  | 
        
        
            | 
            | 
           2432 | 
               isize = -1;            // can't know size until at the end
  | 
        
        
            | 
            | 
           2433 | 
               if (len!=0) isize=len; // unless we were told explicitly!
  | 
        
        
            | 
            | 
           2434 | 
               iseekable=false;
  | 
        
        
            | 
            | 
           2435 | 
               SYSTEMTIME st; GetLocalTime(&st);
  | 
        
        
            | 
            | 
           2436 | 
               FILETIME ft;   SystemTimeToFileTime(&st,&ft);
  | 
        
        
            | 
            | 
           2437 | 
               WORD dosdate,dostime; filetime2dosdatetime(ft,&dosdate,&dostime);
  | 
        
        
            | 
            | 
           2438 | 
               times.atime = filetime2timet(ft);
  | 
        
        
            | 
            | 
           2439 | 
               times.mtime = times.atime;
  | 
        
        
            | 
            | 
           2440 | 
               times.ctime = times.atime;
  | 
        
        
            | 
            | 
           2441 | 
               timestamp = (WORD)dostime | (((DWORD)dosdate)<<16);
  | 
        
        
            | 
            | 
           2442 | 
               hfin=hf;
  | 
        
        
            | 
            | 
           2443 | 
               return ZR_OK;
  | 
        
        
            | 
            | 
           2444 | 
             }
  | 
        
        
            | 
            | 
           2445 | 
           }
  | 
        
        
            | 
            | 
           2446 | 
           ZRESULT TZip::open_mem(void *src,unsigned int len)
  | 
        
        
            | 
            | 
           2447 | 
           { hfin=0; bufin=(const char*)src; selfclosehf=false; crc=CRCVAL_INITIAL; ired=0; csize=0; ired=0;
  | 
        
        
            | 
            | 
           2448 | 
             lenin=len; posin=0;
  | 
        
        
            | 
            | 
           2449 | 
             if (src==0 || len==0) return ZR_ARGS;
  | 
        
        
            | 
            | 
           2450 | 
             attr= 0x80000000; // just a normal file
  | 
        
        
            | 
            | 
           2451 | 
             isize = len;
  | 
        
        
            | 
            | 
           2452 | 
             iseekable=true;
  | 
        
        
            | 
            | 
           2453 | 
             SYSTEMTIME st; GetLocalTime(&st);
  | 
        
        
            | 
            | 
           2454 | 
             FILETIME ft;   SystemTimeToFileTime(&st,&ft);
  | 
        
        
            | 
            | 
           2455 | 
             WORD dosdate,dostime; filetime2dosdatetime(ft,&dosdate,&dostime);
  | 
        
        
            | 
            | 
           2456 | 
             times.atime = filetime2timet(ft);
  | 
        
        
            | 
            | 
           2457 | 
             times.mtime = times.atime;
  | 
        
        
            | 
            | 
           2458 | 
             times.ctime = times.atime;
  | 
        
        
            | 
            | 
           2459 | 
             timestamp = (WORD)dostime | (((DWORD)dosdate)<<16);
  | 
        
        
            | 
            | 
           2460 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2461 | 
           }
  | 
        
        
            | 
            | 
           2462 | 
           ZRESULT TZip::open_dir()
  | 
        
        
            | 
            | 
           2463 | 
           { hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0;
  | 
        
        
            | 
            | 
           2464 | 
             attr= 0x41C00010; // a readable writable directory, and again directory
  | 
        
        
            | 
            | 
           2465 | 
             isize = 0;
  | 
        
        
            | 
            | 
           2466 | 
             iseekable=false;
  | 
        
        
            | 
            | 
           2467 | 
             SYSTEMTIME st; GetLocalTime(&st);
  | 
        
        
            | 
            | 
           2468 | 
             FILETIME ft;   SystemTimeToFileTime(&st,&ft);
  | 
        
        
            | 
            | 
           2469 | 
             WORD dosdate,dostime; filetime2dosdatetime(ft,&dosdate,&dostime);
  | 
        
        
            | 
            | 
           2470 | 
             times.atime = filetime2timet(ft);
  | 
        
        
            | 
            | 
           2471 | 
             times.mtime = times.atime;
  | 
        
        
            | 
            | 
           2472 | 
             times.ctime = times.atime;
  | 
        
        
            | 
            | 
           2473 | 
             timestamp = (WORD)dostime | (((DWORD)dosdate)<<16);
  | 
        
        
            | 
            | 
           2474 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2475 | 
           }
  | 
        
        
            | 
            | 
           2476 | 
              | 
        
        
            | 
            | 
           2477 | 
           unsigned TZip::sread(TState &s,char *buf,unsigned size)
  | 
        
        
            | 
            | 
           2478 | 
           { // static
  | 
        
        
            | 
            | 
           2479 | 
             TZip *zip = (TZip*)s.param;
  | 
        
        
            | 
            | 
           2480 | 
             return zip->read(buf,size);
  | 
        
        
            | 
            | 
           2481 | 
           }
  | 
        
        
            | 
            | 
           2482 | 
              | 
        
        
            | 
            | 
           2483 | 
           unsigned TZip::read(char *buf, unsigned size)
  | 
        
        
            | 
            | 
           2484 | 
           { if (bufin!=0)
  | 
        
        
            | 
            | 
           2485 | 
             { if (posin>=lenin) return 0; // end of input
  | 
        
        
            | 
            | 
           2486 | 
               ulg red = lenin-posin;
  | 
        
        
            | 
            | 
           2487 | 
               if (red>size) red=size;
  | 
        
        
            | 
            | 
           2488 | 
               memcpy(buf, bufin+posin, red);
  | 
        
        
            | 
            | 
           2489 | 
               posin += red;
  | 
        
        
            | 
            | 
           2490 | 
               ired += red;
  | 
        
        
            | 
            | 
           2491 | 
               crc = crc32(crc, (uch*)buf, red);
  | 
        
        
            | 
            | 
           2492 | 
               return red;
  | 
        
        
            | 
            | 
           2493 | 
             }
  | 
        
        
            | 
            | 
           2494 | 
             else if (hfin!=0)
  | 
        
        
            | 
            | 
           2495 | 
             { DWORD red;
  | 
        
        
            | 
            | 
           2496 | 
               BOOL ok = ReadFile(hfin,buf,size,&red,NULL);
  | 
        
        
            | 
            | 
           2497 | 
               if (!ok) return 0;
  | 
        
        
            | 
            | 
           2498 | 
               ired += red;
  | 
        
        
            | 
            | 
           2499 | 
               crc = crc32(crc, (uch*)buf, red);
  | 
        
        
            | 
            | 
           2500 | 
               return red;
  | 
        
        
            | 
            | 
           2501 | 
             }
  | 
        
        
            | 
            | 
           2502 | 
             else {oerr=ZR_NOTINITED; return 0;}
  | 
        
        
            | 
            | 
           2503 | 
           }
  | 
        
        
            | 
            | 
           2504 | 
              | 
        
        
            | 
            | 
           2505 | 
           ZRESULT TZip::iclose()
  | 
        
        
            | 
            | 
           2506 | 
           { if (selfclosehf && hfin!=0) CloseHandle(hfin); hfin=0;
  | 
        
        
            | 
            | 
           2507 | 
             bool mismatch = (isize!=-1 && isize!=ired);
  | 
        
        
            | 
            | 
           2508 | 
             isize=ired; // and crc has been being updated anyway
  | 
        
        
            | 
            | 
           2509 | 
             if (mismatch) return ZR_MISSIZE;
  | 
        
        
            | 
            | 
           2510 | 
             else return ZR_OK;
  | 
        
        
            | 
            | 
           2511 | 
           }
  | 
        
        
            | 
            | 
           2512 | 
              | 
        
        
            | 
            | 
           2513 | 
              | 
        
        
            | 
            | 
           2514 | 
              | 
        
        
            | 
            | 
           2515 | 
           ZRESULT TZip::ideflate(TZipFileInfo *zfi)
  | 
        
        
            | 
            | 
           2516 | 
           { if (state==0) state=new TState();
  | 
        
        
            | 
            | 
           2517 | 
             // It's a very big object! 500k! We allocate it on the heap, because PocketPC's
  | 
        
        
            | 
            | 
           2518 | 
             // stack breaks if we try to put it all on the stack. It will be deleted lazily
  | 
        
        
            | 
            | 
           2519 | 
             state->err=0;
  | 
        
        
            | 
            | 
           2520 | 
             state->readfunc=sread; state->flush_outbuf=sflush;
  | 
        
        
            | 
            | 
           2521 | 
             state->param=this; state->level=8; state->seekable=iseekable; state->err=NULL;
  | 
        
        
            | 
            | 
           2522 | 
             // the following line will make ct_init realise it has to perform the init
  | 
        
        
            | 
            | 
           2523 | 
             state->ts.static_dtree[0].dl.len = 0;
  | 
        
        
            | 
            | 
           2524 | 
             // Thanks to Alvin77 for this crucial fix:
  | 
        
        
            | 
            | 
           2525 | 
             state->ds.window_size=0;
  | 
        
        
            | 
            | 
           2526 | 
             //  I think that covers everything that needs to be initted.
  | 
        
        
            | 
            | 
           2527 | 
             //
  | 
        
        
            | 
            | 
           2528 | 
             bi_init(*state,buf, sizeof(buf), TRUE); // it used to be just 1024-size, not 16384 as here
  | 
        
        
            | 
            | 
           2529 | 
             ct_init(*state,&zfi->att);
  | 
        
        
            | 
            | 
           2530 | 
             lm_init(*state,state->level, &zfi->flg);
  | 
        
        
            | 
            | 
           2531 | 
             ulg sz = deflate(*state);
  | 
        
        
            | 
            | 
           2532 | 
             csize=sz;
  | 
        
        
            | 
            | 
           2533 | 
             ZRESULT r=ZR_OK; if (state->err!=NULL) r=ZR_FLATE;
  | 
        
        
            | 
            | 
           2534 | 
             return r;
  | 
        
        
            | 
            | 
           2535 | 
           }
  | 
        
        
            | 
            | 
           2536 | 
              | 
        
        
            | 
            | 
           2537 | 
           ZRESULT TZip::istore()
  | 
        
        
            | 
            | 
           2538 | 
           { ulg size=0;
  | 
        
        
            | 
            | 
           2539 | 
             for (;;)
  | 
        
        
            | 
            | 
           2540 | 
             { unsigned int cin=read(buf,16384); if (cin<=0 || cin==(unsigned int)EOF) break;
  | 
        
        
            | 
            | 
           2541 | 
               unsigned int cout = write(buf,cin); if (cout!=cin) return ZR_MISSIZE;
  | 
        
        
            | 
            | 
           2542 | 
               size += cin;
  | 
        
        
            | 
            | 
           2543 | 
             }
  | 
        
        
            | 
            | 
           2544 | 
             csize=size;
  | 
        
        
            | 
            | 
           2545 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2546 | 
           }
  | 
        
        
            | 
            | 
           2547 | 
              | 
        
        
            | 
            | 
           2548 | 
              | 
        
        
            | 
            | 
           2549 | 
              | 
        
        
            | 
            | 
           2550 | 
              | 
        
        
            | 
            | 
           2551 | 
              | 
        
        
            | 
            | 
           2552 | 
           bool has_seeded=false;
  | 
        
        
            | 
            | 
           2553 | 
           ZRESULT TZip::Add(const TCHAR *odstzn, void *src,unsigned int len, DWORD flags)
  | 
        
        
            | 
            | 
           2554 | 
           { if (oerr) return ZR_FAILED;
  | 
        
        
            | 
            | 
           2555 | 
             if (hasputcen) return ZR_ENDED;
  | 
        
        
            | 
            | 
           2556 | 
              | 
        
        
            | 
            | 
           2557 | 
             // if we use password encryption, then every isize and csize is 12 bytes bigger
  | 
        
        
            | 
            | 
           2558 | 
             int passex=0; if (password!=0 && flags!=ZIP_FOLDER) passex=12;
  | 
        
        
            | 
            | 
           2559 | 
              | 
        
        
            | 
            | 
           2560 | 
             // zip has its own notion of what its names should look like: i.e. dir/file.stuff
  | 
        
        
            | 
            | 
           2561 | 
             TCHAR dstzn[MAX_PATH]; _tcscpy(dstzn,odstzn);
  | 
        
        
            | 
            | 
           2562 | 
             if (*dstzn==0) return ZR_ARGS;
  | 
        
        
            | 
            | 
           2563 | 
             TCHAR *d=dstzn; while (*d!=0) {if (*d=='\\') *d='/'; d++;}
  | 
        
        
            | 
            | 
           2564 | 
             bool isdir = (flags==ZIP_FOLDER);
  | 
        
        
            | 
            | 
           2565 | 
             bool needs_trailing_slash = (isdir && dstzn[_tcslen(dstzn)-1]!='/');
  | 
        
        
            | 
            | 
           2566 | 
             int method=DEFLATE; if (isdir || HasZipSuffix(dstzn)) method=STORE;
  | 
        
        
            | 
            | 
           2567 | 
              | 
        
        
            | 
            | 
           2568 | 
             // now open whatever was our input source:
  | 
        
        
            | 
            | 
           2569 | 
             ZRESULT openres;
  | 
        
        
            | 
            | 
           2570 | 
             if (flags==ZIP_FILENAME) openres=open_file((const TCHAR*)src);
  | 
        
        
            | 
            | 
           2571 | 
             else if (flags==ZIP_HANDLE) openres=open_handle((HANDLE)src,len);
  | 
        
        
            | 
            | 
           2572 | 
             else if (flags==ZIP_MEMORY) openres=open_mem(src,len);
  | 
        
        
            | 
            | 
           2573 | 
             else if (flags==ZIP_FOLDER) openres=open_dir();
  | 
        
        
            | 
            | 
           2574 | 
             else return ZR_ARGS;
  | 
        
        
            | 
            | 
           2575 | 
             if (openres!=ZR_OK) return openres;
  | 
        
        
            | 
            | 
           2576 | 
              | 
        
        
            | 
            | 
           2577 | 
             // A zip "entry" consists of a local header (which includes the file name),
  | 
        
        
            | 
            | 
           2578 | 
             // then the compressed data, and possibly an extended local header.
  | 
        
        
            | 
            | 
           2579 | 
              | 
        
        
            | 
            | 
           2580 | 
             // Initialize the local header
  | 
        
        
            | 
            | 
           2581 | 
             TZipFileInfo zfi; zfi.nxt=NULL;
  | 
        
        
            | 
            | 
           2582 | 
             strcpy(zfi.name,"");
  | 
        
        
            | 
            | 
           2583 | 
           #ifdef UNICODE
  | 
        
        
            | 
            | 
           2584 | 
             WideCharToMultiByte(CP_UTF8,0,dstzn,-1,zfi.iname,MAX_PATH,0,0);
  | 
        
        
            | 
            | 
           2585 | 
           #else
  | 
        
        
            | 
            | 
           2586 | 
             strcpy(zfi.iname,dstzn);
  | 
        
        
            | 
            | 
           2587 | 
           #endif
  | 
        
        
            | 
            | 
           2588 | 
             zfi.nam=strlen(zfi.iname);
  | 
        
        
            | 
            | 
           2589 | 
             if (needs_trailing_slash) {strcat(zfi.iname,"/"); zfi.nam++;}
  | 
        
        
            | 
            | 
           2590 | 
             strcpy(zfi.zname,"");
  | 
        
        
            | 
            | 
           2591 | 
             zfi.extra=NULL; zfi.ext=0;   // extra header to go after this compressed data, and its length
  | 
        
        
            | 
            | 
           2592 | 
             zfi.cextra=NULL; zfi.cext=0; // extra header to go in the central end-of-zip directory, and its length
  | 
        
        
            | 
            | 
           2593 | 
             zfi.comment=NULL; zfi.com=0; // comment, and its length
  | 
        
        
            | 
            | 
           2594 | 
             zfi.mark = 1;
  | 
        
        
            | 
            | 
           2595 | 
             zfi.dosflag = 0;
  | 
        
        
            | 
            | 
           2596 | 
             zfi.att = (ush)BINARY;
  | 
        
        
            | 
            | 
           2597 | 
             zfi.vem = (ush)0xB17; // 0xB00 is win32 os-code. 0x17 is 23 in decimal: zip 2.3
  | 
        
        
            | 
            | 
           2598 | 
             zfi.ver = (ush)20;    // Needs PKUNZIP 2.0 to unzip it
  | 
        
        
            | 
            | 
           2599 | 
             zfi.tim = timestamp;
  | 
        
        
            | 
            | 
           2600 | 
             // Even though we write the header now, it will have to be rewritten, since we don't know compressed size or crc.
  | 
        
        
            | 
            | 
           2601 | 
             zfi.crc = 0;            // to be updated later
  | 
        
        
            | 
            | 
           2602 | 
             zfi.flg = 8;            // 8 means 'there is an extra header'. Assume for the moment that we need it.
  | 
        
        
            | 
            | 
           2603 | 
             if (password!=0 && !isdir) zfi.flg=9;  // and 1 means 'password-encrypted'
  | 
        
        
            | 
            | 
           2604 | 
             zfi.lflg = zfi.flg;     // to be updated later
  | 
        
        
            | 
            | 
           2605 | 
             zfi.how = (ush)method;  // to be updated later
  | 
        
        
            | 
            | 
           2606 | 
             zfi.siz = (ulg)(method==STORE && isize>=0 ? isize+passex : 0); // to be updated later
  | 
        
        
            | 
            | 
           2607 | 
             zfi.len = (ulg)(isize);  // to be updated later
  | 
        
        
            | 
            | 
           2608 | 
             zfi.dsk = 0;
  | 
        
        
            | 
            | 
           2609 | 
             zfi.atx = attr;
  | 
        
        
            | 
            | 
           2610 | 
             zfi.off = writ+ooffset;         // offset within file of the start of this local record
  | 
        
        
            | 
            | 
           2611 | 
             // stuff the 'times' structure into zfi.extra
  | 
        
        
            | 
            | 
           2612 | 
              | 
        
        
            | 
            | 
           2613 | 
             // nb. apparently there's a problem with PocketPC CE(zip)->CE(unzip) fails. And removing the following block fixes it up.
  | 
        
        
            | 
            | 
           2614 | 
             char xloc[EB_L_UT_SIZE]; zfi.extra=xloc;  zfi.ext=EB_L_UT_SIZE;
  | 
        
        
            | 
            | 
           2615 | 
             char xcen[EB_C_UT_SIZE]; zfi.cextra=xcen; zfi.cext=EB_C_UT_SIZE;
  | 
        
        
            | 
            | 
           2616 | 
             xloc[0]  = 'U';
  | 
        
        
            | 
            | 
           2617 | 
             xloc[1]  = 'T';
  | 
        
        
            | 
            | 
           2618 | 
             xloc[2]  = EB_UT_LEN(3);       // length of data part of e.f.
  | 
        
        
            | 
            | 
           2619 | 
             xloc[3]  = 0;
  | 
        
        
            | 
            | 
           2620 | 
             xloc[4]  = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME;
  | 
        
        
            | 
            | 
           2621 | 
             xloc[5]  = (char)(times.mtime);
  | 
        
        
            | 
            | 
           2622 | 
             xloc[6]  = (char)(times.mtime >> 8);
  | 
        
        
            | 
            | 
           2623 | 
             xloc[7]  = (char)(times.mtime >> 16);
  | 
        
        
            | 
            | 
           2624 | 
             xloc[8]  = (char)(times.mtime >> 24);
  | 
        
        
            | 
            | 
           2625 | 
             xloc[9]  = (char)(times.atime);
  | 
        
        
            | 
            | 
           2626 | 
             xloc[10] = (char)(times.atime >> 8);
  | 
        
        
            | 
            | 
           2627 | 
             xloc[11] = (char)(times.atime >> 16);
  | 
        
        
            | 
            | 
           2628 | 
             xloc[12] = (char)(times.atime >> 24);
  | 
        
        
            | 
            | 
           2629 | 
             xloc[13] = (char)(times.ctime);
  | 
        
        
            | 
            | 
           2630 | 
             xloc[14] = (char)(times.ctime >> 8);
  | 
        
        
            | 
            | 
           2631 | 
             xloc[15] = (char)(times.ctime >> 16);
  | 
        
        
            | 
            | 
           2632 | 
             xloc[16] = (char)(times.ctime >> 24);
  | 
        
        
            | 
            | 
           2633 | 
             memcpy(zfi.cextra,zfi.extra,EB_C_UT_SIZE);
  | 
        
        
            | 
            | 
           2634 | 
             zfi.cextra[EB_LEN] = EB_UT_LEN(1);
  | 
        
        
            | 
            | 
           2635 | 
              | 
        
        
            | 
            | 
           2636 | 
              | 
        
        
            | 
            | 
           2637 | 
             // (1) Start by writing the local header:
  | 
        
        
            | 
            | 
           2638 | 
             int r = putlocal(&zfi,swrite,this);
  | 
        
        
            | 
            | 
           2639 | 
             if (r!=ZE_OK) {iclose(); return ZR_WRITE;}
  | 
        
        
            | 
            | 
           2640 | 
             writ += 4 + LOCHEAD + (unsigned int)zfi.nam + (unsigned int)zfi.ext;
  | 
        
        
            | 
            | 
           2641 | 
             if (oerr!=ZR_OK) {iclose(); return oerr;}
  | 
        
        
            | 
            | 
           2642 | 
              | 
        
        
            | 
            | 
           2643 | 
             // (1.5) if necessary, write the encryption header
  | 
        
        
            | 
            | 
           2644 | 
             keys[0]=305419896L;
  | 
        
        
            | 
            | 
           2645 | 
             keys[1]=591751049L;
  | 
        
        
            | 
            | 
           2646 | 
             keys[2]=878082192L;
  | 
        
        
            | 
            | 
           2647 | 
             for (const char *cp=password; cp!=0 && *cp!=0; cp++) update_keys(keys,*cp);
  | 
        
        
            | 
            | 
           2648 | 
             // generate some random bytes
  | 
        
        
            | 
            | 
           2649 | 
             if (!has_seeded) srand(GetTickCount()^(unsigned long)GetDesktopWindow());
  | 
        
        
            | 
            | 
           2650 | 
             char encbuf[12]; for (int i=0; i<12; i++) encbuf[i]=(char)((rand()>>7)&0xff);
  | 
        
        
            | 
            | 
           2651 | 
             encbuf[11] = (char)((zfi.tim>>8)&0xff);
  | 
        
        
            | 
            | 
           2652 | 
             for (int ei=0; ei<12; ei++) encbuf[ei]=zencode(keys,encbuf[ei]);
  | 
        
        
            | 
            | 
           2653 | 
             if (password!=0 && !isdir) {swrite(this,encbuf,12); writ+=12;}
  | 
        
        
            | 
            | 
           2654 | 
              | 
        
        
            | 
            | 
           2655 | 
             //(2) Write deflated/stored file to zip file
  | 
        
        
            | 
            | 
           2656 | 
             ZRESULT writeres=ZR_OK;
  | 
        
        
            | 
            | 
           2657 | 
             encwriting = (password!=0 && !isdir);  // an object member variable to say whether we write to disk encrypted
  | 
        
        
            | 
            | 
           2658 | 
             if (!isdir && method==DEFLATE) writeres=ideflate(&zfi);
  | 
        
        
            | 
            | 
           2659 | 
             else if (!isdir && method==STORE) writeres=istore();
  | 
        
        
            | 
            | 
           2660 | 
             else if (isdir) csize=0;
  | 
        
        
            | 
            | 
           2661 | 
             encwriting = false;
  | 
        
        
            | 
            | 
           2662 | 
             iclose();
  | 
        
        
            | 
            | 
           2663 | 
             writ += csize;
  | 
        
        
            | 
            | 
           2664 | 
             if (oerr!=ZR_OK) return oerr;
  | 
        
        
            | 
            | 
           2665 | 
             if (writeres!=ZR_OK) return ZR_WRITE;
  | 
        
        
            | 
            | 
           2666 | 
              | 
        
        
            | 
            | 
           2667 | 
             // (3) Either rewrite the local header with correct information...
  | 
        
        
            | 
            | 
           2668 | 
             bool first_header_has_size_right = (zfi.siz==csize+passex);
  | 
        
        
            | 
            | 
           2669 | 
             zfi.crc = crc;
  | 
        
        
            | 
            | 
           2670 | 
             zfi.siz = csize+passex;
  | 
        
        
            | 
            | 
           2671 | 
             zfi.len = isize;
  | 
        
        
            | 
            | 
           2672 | 
             if (ocanseek && (password==0 || isdir))
  | 
        
        
            | 
            | 
           2673 | 
             { zfi.how = (ush)method;
  | 
        
        
            | 
            | 
           2674 | 
               if ((zfi.flg & 1) == 0) zfi.flg &= ~8; // clear the extended local header flag
  | 
        
        
            | 
            | 
           2675 | 
               zfi.lflg = zfi.flg;
  | 
        
        
            | 
            | 
           2676 | 
               // rewrite the local header:
  | 
        
        
            | 
            | 
           2677 | 
               if (!oseek(zfi.off-ooffset)) return ZR_SEEK;
  | 
        
        
            | 
            | 
           2678 | 
               if ((r = putlocal(&zfi, swrite,this)) != ZE_OK) return ZR_WRITE;
  | 
        
        
            | 
            | 
           2679 | 
               if (!oseek(writ)) return ZR_SEEK;
  | 
        
        
            | 
            | 
           2680 | 
             }
  | 
        
        
            | 
            | 
           2681 | 
             else
  | 
        
        
            | 
            | 
           2682 | 
             { // (4) ... or put an updated header at the end
  | 
        
        
            | 
            | 
           2683 | 
               if (zfi.how != (ush) method) return ZR_NOCHANGE;
  | 
        
        
            | 
            | 
           2684 | 
               if (method==STORE && !first_header_has_size_right) return ZR_NOCHANGE;
  | 
        
        
            | 
            | 
           2685 | 
               if ((r = putextended(&zfi, swrite,this)) != ZE_OK) return ZR_WRITE;
  | 
        
        
            | 
            | 
           2686 | 
               writ += 16L;
  | 
        
        
            | 
            | 
           2687 | 
               zfi.flg = zfi.lflg; // if flg modified by inflate, for the central index
  | 
        
        
            | 
            | 
           2688 | 
             }
  | 
        
        
            | 
            | 
           2689 | 
             if (oerr!=ZR_OK) return oerr;
  | 
        
        
            | 
            | 
           2690 | 
              | 
        
        
            | 
            | 
           2691 | 
             // Keep a copy of the zipfileinfo, for our end-of-zip directory
  | 
        
        
            | 
            | 
           2692 | 
             char *cextra = new char[zfi.cext]; memcpy(cextra,zfi.cextra,zfi.cext); zfi.cextra=cextra;
  | 
        
        
            | 
            | 
           2693 | 
             TZipFileInfo *pzfi = new TZipFileInfo; memcpy(pzfi,&zfi,sizeof(zfi));
  | 
        
        
            | 
            | 
           2694 | 
             if (zfis==NULL) zfis=pzfi;
  | 
        
        
            | 
            | 
           2695 | 
             else {TZipFileInfo *z=zfis; while (z->nxt!=NULL) z=z->nxt; z->nxt=pzfi;}
  | 
        
        
            | 
            | 
           2696 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2697 | 
           }
  | 
        
        
            | 
            | 
           2698 | 
              | 
        
        
            | 
            | 
           2699 | 
           ZRESULT TZip::AddCentral()
  | 
        
        
            | 
            | 
           2700 | 
           { // write central directory
  | 
        
        
            | 
            | 
           2701 | 
             int numentries = 0;
  | 
        
        
            | 
            | 
           2702 | 
             ulg pos_at_start_of_central = writ;
  | 
        
        
            | 
            | 
           2703 | 
             //ulg tot_unc_size=0, tot_compressed_size=0;
  | 
        
        
            | 
            | 
           2704 | 
             bool okay=true;
  | 
        
        
            | 
            | 
           2705 | 
             for (TZipFileInfo *zfi=zfis; zfi!=NULL; )
  | 
        
        
            | 
            | 
           2706 | 
             { if (okay)
  | 
        
        
            | 
            | 
           2707 | 
               { int res = putcentral(zfi, swrite,this);
  | 
        
        
            | 
            | 
           2708 | 
                 if (res!=ZE_OK) okay=false;
  | 
        
        
            | 
            | 
           2709 | 
               }
  | 
        
        
            | 
            | 
           2710 | 
               writ += 4 + CENHEAD + (unsigned int)zfi->nam + (unsigned int)zfi->cext + (unsigned int)zfi->com;
  | 
        
        
            | 
            | 
           2711 | 
               //tot_unc_size += zfi->len;
  | 
        
        
            | 
            | 
           2712 | 
               //tot_compressed_size += zfi->siz;
  | 
        
        
            | 
            | 
           2713 | 
               numentries++;
  | 
        
        
            | 
            | 
           2714 | 
               //
  | 
        
        
            | 
            | 
           2715 | 
               TZipFileInfo *zfinext = zfi->nxt;
  | 
        
        
            | 
            | 
           2716 | 
               if (zfi->cextra!=0) delete[] zfi->cextra;
  | 
        
        
            | 
            | 
           2717 | 
               delete zfi;
  | 
        
        
            | 
            | 
           2718 | 
               zfi = zfinext;
  | 
        
        
            | 
            | 
           2719 | 
             }
  | 
        
        
            | 
            | 
           2720 | 
             ulg center_size = writ - pos_at_start_of_central;
  | 
        
        
            | 
            | 
           2721 | 
             if (okay)
  | 
        
        
            | 
            | 
           2722 | 
             { int res = putend(numentries, center_size, pos_at_start_of_central+ooffset, 0, NULL, swrite,this);
  | 
        
        
            | 
            | 
           2723 | 
               if (res!=ZE_OK) okay=false;
  | 
        
        
            | 
            | 
           2724 | 
               writ += 4 + ENDHEAD + 0;
  | 
        
        
            | 
            | 
           2725 | 
             }
  | 
        
        
            | 
            | 
           2726 | 
             if (!okay) return ZR_WRITE;
  | 
        
        
            | 
            | 
           2727 | 
             return ZR_OK;
  | 
        
        
            | 
            | 
           2728 | 
           }
  | 
        
        
            | 
            | 
           2729 | 
              | 
        
        
            | 
            | 
           2730 | 
              | 
        
        
            | 
            | 
           2731 | 
              | 
        
        
            | 
            | 
           2732 | 
              | 
        
        
            | 
            | 
           2733 | 
              | 
        
        
            | 
            | 
           2734 | 
           ZRESULT lasterrorZ=ZR_OK;
  | 
        
        
            | 
            | 
           2735 | 
              | 
        
        
            | 
            | 
           2736 | 
           unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len)
  | 
        
        
            | 
            | 
           2737 | 
           { if (code==ZR_RECENT) code=lasterrorZ;
  | 
        
        
            | 
            | 
           2738 | 
             const char *msg="unknown zip result code";
  | 
        
        
            | 
            | 
           2739 | 
             switch (code)
  | 
        
        
            | 
            | 
           2740 | 
             { case ZR_OK: msg="Success"; break;
  | 
        
        
            | 
            | 
           2741 | 
               case ZR_NODUPH: msg="Culdn't duplicate handle"; break;
  | 
        
        
            | 
            | 
           2742 | 
               case ZR_NOFILE: msg="Couldn't create/open file"; break;
  | 
        
        
            | 
            | 
           2743 | 
               case ZR_NOALLOC: msg="Failed to allocate memory"; break;
  | 
        
        
            | 
            | 
           2744 | 
               case ZR_WRITE: msg="Error writing to file"; break;
  | 
        
        
            | 
            | 
           2745 | 
               case ZR_NOTFOUND: msg="File not found in the zipfile"; break;
  | 
        
        
            | 
            | 
           2746 | 
               case ZR_MORE: msg="Still more data to unzip"; break;
  | 
        
        
            | 
            | 
           2747 | 
               case ZR_CORRUPT: msg="Zipfile is corrupt or not a zipfile"; break;
  | 
        
        
            | 
            | 
           2748 | 
               case ZR_READ: msg="Error reading file"; break;
  | 
        
        
            | 
            | 
           2749 | 
               case ZR_ARGS: msg="Caller: faulty arguments"; break;
  | 
        
        
            | 
            | 
           2750 | 
               case ZR_PARTIALUNZ: msg="Caller: the file had already been partially unzipped"; break;
  | 
        
        
            | 
            | 
           2751 | 
               case ZR_NOTMMAP: msg="Caller: can only get memory of a memory zipfile"; break;
  | 
        
        
            | 
            | 
           2752 | 
               case ZR_MEMSIZE: msg="Caller: not enough space allocated for memory zipfile"; break;
  | 
        
        
            | 
            | 
           2753 | 
               case ZR_FAILED: msg="Caller: there was a previous error"; break;
  | 
        
        
            | 
            | 
           2754 | 
               case ZR_ENDED: msg="Caller: additions to the zip have already been ended"; break;
  | 
        
        
            | 
            | 
           2755 | 
               case ZR_ZMODE: msg="Caller: mixing creation and opening of zip"; break;
  | 
        
        
            | 
            | 
           2756 | 
               case ZR_NOTINITED: msg="Zip-bug: internal initialisation not completed"; break;
  | 
        
        
            | 
            | 
           2757 | 
               case ZR_SEEK: msg="Zip-bug: trying to seek the unseekable"; break;
  | 
        
        
            | 
            | 
           2758 | 
               case ZR_MISSIZE: msg="Zip-bug: the anticipated size turned out wrong"; break;
  | 
        
        
            | 
            | 
           2759 | 
               case ZR_NOCHANGE: msg="Zip-bug: tried to change mind, but not allowed"; break;
  | 
        
        
            | 
            | 
           2760 | 
               case ZR_FLATE: msg="Zip-bug: an internal error during flation"; break;
  | 
        
        
            | 
            | 
           2761 | 
             }
  | 
        
        
            | 
            | 
           2762 | 
             unsigned int mlen=(unsigned int)strlen(msg);
  | 
        
        
            | 
            | 
           2763 | 
             if (buf==0 || len==0) return mlen;
  | 
        
        
            | 
            | 
           2764 | 
             unsigned int n=mlen; if (n+1>len) n=len-1;
  | 
        
        
            | 
            | 
           2765 | 
             strncpy(buf,msg,n); buf[n]=0;
  | 
        
        
            | 
            | 
           2766 | 
             return mlen;
  | 
        
        
            | 
            | 
           2767 | 
           }
  | 
        
        
            | 
            | 
           2768 | 
              | 
        
        
            | 
            | 
           2769 | 
              | 
        
        
            | 
            | 
           2770 | 
              | 
        
        
            | 
            | 
           2771 | 
           typedef struct
  | 
        
        
            | 
            | 
           2772 | 
           { DWORD flag;
  | 
        
        
            | 
            | 
           2773 | 
             TZip *zip;
  | 
        
        
            | 
            | 
           2774 | 
           } TZipHandleData;
  | 
        
        
            | 
            | 
           2775 | 
              | 
        
        
            | 
            | 
           2776 | 
              | 
        
        
            | 
            | 
           2777 | 
           HZIP CreateZipInternal(void *z,unsigned int len,DWORD flags, const char *password)
  | 
        
        
            | 
            | 
           2778 | 
           { TZip *zip = new TZip(password);
  | 
        
        
            | 
            | 
           2779 | 
             lasterrorZ = zip->Create(z,len,flags);
  | 
        
        
            | 
            | 
           2780 | 
             if (lasterrorZ!=ZR_OK) {delete zip; return 0;}
  | 
        
        
            | 
            | 
           2781 | 
             TZipHandleData *han = new TZipHandleData;
  | 
        
        
            | 
            | 
           2782 | 
             han->flag=2; han->zip=zip; return (HZIP)han;
  | 
        
        
            | 
            | 
           2783 | 
           }
  | 
        
        
            | 
            | 
           2784 | 
           HZIP CreateZipHandle(HANDLE h, const char *password) {return CreateZipInternal(h,0,ZIP_HANDLE,password);}
  | 
        
        
            | 
            | 
           2785 | 
           HZIP CreateZip(const TCHAR *fn, const char *password) {return CreateZipInternal((void*)fn,0,ZIP_FILENAME,password);}
  | 
        
        
            | 
            | 
           2786 | 
           HZIP CreateZip(void *z,unsigned int len, const char *password) {return CreateZipInternal(z,len,ZIP_MEMORY,password);}
  | 
        
        
            | 
            | 
           2787 | 
              | 
        
        
            | 
            | 
           2788 | 
              | 
        
        
            | 
            | 
           2789 | 
           ZRESULT ZipAddInternal(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len, DWORD flags)
  | 
        
        
            | 
            | 
           2790 | 
           { if (hz==0) {lasterrorZ=ZR_ARGS;return ZR_ARGS;}
  | 
        
        
            | 
            | 
           2791 | 
             TZipHandleData *han = (TZipHandleData*)hz;
  | 
        
        
            | 
            | 
           2792 | 
             if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;}
  | 
        
        
            | 
            | 
           2793 | 
             TZip *zip = han->zip;
  | 
        
        
            | 
            | 
           2794 | 
             lasterrorZ = zip->Add(dstzn,src,len,flags);
  | 
        
        
            | 
            | 
           2795 | 
             return lasterrorZ;
  | 
        
        
            | 
            | 
           2796 | 
           }
  | 
        
        
            | 
            | 
           2797 | 
           ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, const TCHAR *fn) {return ZipAddInternal(hz,dstzn,(void*)fn,0,ZIP_FILENAME);}
  | 
        
        
            | 
            | 
           2798 | 
           ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len) {return ZipAddInternal(hz,dstzn,src,len,ZIP_MEMORY);}
  | 
        
        
            | 
            | 
           2799 | 
           ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h) {return ZipAddInternal(hz,dstzn,h,0,ZIP_HANDLE);}
  | 
        
        
            | 
            | 
           2800 | 
           ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h, unsigned int len) {return ZipAddInternal(hz,dstzn,h,len,ZIP_HANDLE);}
  | 
        
        
            | 
            | 
           2801 | 
           ZRESULT ZipAddFolder(HZIP hz,const TCHAR *dstzn) {return ZipAddInternal(hz,dstzn,0,0,ZIP_FOLDER);}
  | 
        
        
            | 
            | 
           2802 | 
              | 
        
        
            | 
            | 
           2803 | 
              | 
        
        
            | 
            | 
           2804 | 
              | 
        
        
            | 
            | 
           2805 | 
           ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len)
  | 
        
        
            | 
            | 
           2806 | 
           { if (hz==0) {if (buf!=0) *buf=0; if (len!=0) *len=0; lasterrorZ=ZR_ARGS;return ZR_ARGS;}
  | 
        
        
            | 
            | 
           2807 | 
             TZipHandleData *han = (TZipHandleData*)hz;
  | 
        
        
            | 
            | 
           2808 | 
             if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;}
  | 
        
        
            | 
            | 
           2809 | 
             TZip *zip = han->zip;
  | 
        
        
            | 
            | 
           2810 | 
             lasterrorZ = zip->GetMemory(buf,len);
  | 
        
        
            | 
            | 
           2811 | 
             return lasterrorZ;
  | 
        
        
            | 
            | 
           2812 | 
           }
  | 
        
        
            | 
            | 
           2813 | 
              | 
        
        
            | 
            | 
           2814 | 
           ZRESULT CloseZipZ(HZIP hz)
  | 
        
        
            | 
            | 
           2815 | 
           { if (hz==0) {lasterrorZ=ZR_ARGS;return ZR_ARGS;}
  | 
        
        
            | 
            | 
           2816 | 
             TZipHandleData *han = (TZipHandleData*)hz;
  | 
        
        
            | 
            | 
           2817 | 
             if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;}
  | 
        
        
            | 
            | 
           2818 | 
             TZip *zip = han->zip;
  | 
        
        
            | 
            | 
           2819 | 
             lasterrorZ = zip->Close();
  | 
        
        
            | 
            | 
           2820 | 
             delete zip;
  | 
        
        
            | 
            | 
           2821 | 
             delete han;
  | 
        
        
            | 
            | 
           2822 | 
             return lasterrorZ;
  | 
        
        
            | 
            | 
           2823 | 
           }
  | 
        
        
            | 
            | 
           2824 | 
              | 
        
        
            | 
            | 
           2825 | 
           bool IsZipHandleZ(HZIP hz)
  | 
        
        
            | 
            | 
           2826 | 
           { if (hz==0) return false;
  | 
        
        
            | 
            | 
           2827 | 
             TZipHandleData *han = (TZipHandleData*)hz;
  | 
        
        
            | 
            | 
           2828 | 
             return (han->flag==2);
  | 
        
        
            | 
            | 
           2829 | 
           }
  | 
        
        
            | 
            | 
           2830 | 
              |