See changelog 2002-01-25 22:20 UTC-0300

This commit is contained in:
Luiz Rafael Culik
2002-01-26 00:35:47 +00:00
parent b9475c32c2
commit 4700530106
63 changed files with 15134 additions and 38 deletions

View File

@@ -0,0 +1,49 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int k;
if (buf == Z_NULL) return 1L;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}

View File

@@ -0,0 +1,68 @@
/* compress.c -- compress a memory buffer
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
/* ===========================================================================
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
int level;
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
#endif
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, level);
if (err != Z_OK) return err;
err = deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
deflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = deflateEnd(&stream);
return err;
}
/* ===========================================================================
*/
int ZEXPORT compress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}

View File

@@ -0,0 +1,162 @@
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
#define local static
#ifdef DYNAMIC_CRC_TABLE
local int crc_table_empty = 1;
local uLongf crc_table[256];
local void make_crc_table OF((void));
/*
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
Polynomials over GF(2) are represented in binary, one bit per coefficient,
with the lowest powers in the most significant bit. Then adding polynomials
is just exclusive-or, and multiplying a polynomial by x is a right shift by
one. If we call the above polynomial p, and represent a byte as the
polynomial q, also with the lowest power in the most significant bit (so the
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
where a mod b means the remainder after dividing a by b.
This calculation is done using the shift-register method of multiplying and
taking the remainder. The register is initialized to zero, and for each
incoming bit, x^32 is added mod p to the register if the bit is a one (where
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
x (which is shifting right by one and adding x^32 mod p if the bit shifted
out is a one). We start with the highest power (least significant bit) of
q and repeat for all eight bits of q.
The table is simply the CRC of all possible eight bit values. This is all
the information needed to generate CRC's on data a byte at a time for all
combinations of CRC register values and incoming bytes.
*/
local void make_crc_table()
{
uLong c;
int n, k;
uLong poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320L) */
poly = 0L;
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
poly |= 1L << (31 - p[n]);
for (n = 0; n < 256; n++)
{
c = (uLong)n;
for (k = 0; k < 8; k++)
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[n] = c;
}
crc_table_empty = 0;
}
#else
/* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table)
*/
local const uLongf crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
0x2d02ef8dL
};
#endif
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
const uLongf * ZEXPORT get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table();
#endif
return (const uLongf *)crc_table;
}
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf);
#define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */
uLong ZEXPORT crc32(crc, buf, len)
uLong crc;
const Bytef *buf;
uInt len;
{
if (buf == Z_NULL) return 0L;
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty)
make_crc_table();
#endif
crc = crc ^ 0xffffffffL;
while (len >= 8)
{
DO8(buf);
len -= 8;
}
if (len) do {
DO1(buf);
} while (--len);
return crc ^ 0xffffffffL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,318 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-1998 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef _DEFLATE_H
#define _DEFLATE_H
#include "zutil.h"
/* ===========================================================================
* Internal compression state.
*/
#define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */
#define LITERALS 256
/* number of literal bytes 0..255 */
#define L_CODES (LITERALS+1+LENGTH_CODES)
/* number of Literal or Length codes, including the END_BLOCK code */
#define D_CODES 30
/* number of distance codes */
#define BL_CODES 19
/* number of codes used to transfer the bit lengths */
#define HEAP_SIZE (2*L_CODES+1)
/* maximum heap size */
#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
#define INIT_STATE 42
#define BUSY_STATE 113
#define FINISH_STATE 666
/* Stream status */
/* Data structure describing a single value and its code string. */
typedef struct ct_data_s {
union {
ush freq; /* frequency count */
ush code; /* bit string */
} fc;
union {
ush dad; /* father node in Huffman tree */
ush len; /* length of bit string */
} dl;
} FAR ct_data;
#define Freq fc.freq
#define Code fc.code
#define Dad dl.dad
#define Len dl.len
typedef struct static_tree_desc_s static_tree_desc;
typedef struct tree_desc_s {
ct_data *dyn_tree; /* the dynamic tree */
int max_code; /* largest code with non zero frequency */
static_tree_desc *stat_desc; /* the corresponding static tree */
} FAR tree_desc;
typedef ush Pos;
typedef Pos FAR Posf;
typedef unsigned IPos;
/* A Pos is an index in the character window. We use short instead of int to
* save space in the various tables. IPos is used only for parameter passing.
*/
typedef struct internal_state {
z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */
Bytef *pending_buf; /* output still pending */
ulg pending_buf_size; /* size of pending_buf */
Bytef *pending_out; /* next pending byte to output to the stream */
int pending; /* nb of bytes in the pending buffer */
int noheader; /* suppress zlib header and adler32 */
Byte data_type; /* UNKNOWN, BINARY or ASCII */
Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */
uInt w_size; /* LZ77 window size (32K by default) */
uInt w_bits; /* log2(w_size) (8..16) */
uInt w_mask; /* w_size - 1 */
Bytef *window;
/* Sliding window. Input bytes are read into the second half of the window,
* and move to the first half later to keep a dictionary of at least wSize
* bytes. With this organization, matches are limited to a distance of
* wSize-MAX_MATCH bytes, but this ensures that IO is always
* performed with a length multiple of the block size. Also, it limits
* the window size to 64K, which is quite useful on MSDOS.
* To do: use the user input buffer as sliding window.
*/
ulg window_size;
/* Actual size of window: 2*wSize, except when the user input buffer
* is directly used as sliding window.
*/
Posf *prev;
/* Link to older string with same hash index. To limit the size of this
* array to 64K, this link is maintained only for the last 32K strings.
* An index in this array is thus a window index modulo 32K.
*/
Posf *head; /* Heads of the hash chains or NIL. */
uInt ins_h; /* hash index of string to be inserted */
uInt hash_size; /* number of elements in hash table */
uInt hash_bits; /* log2(hash_size) */
uInt hash_mask; /* hash_size-1 */
uInt hash_shift;
/* Number of bits by which ins_h must be shifted at each input
* step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
* hash_shift * MIN_MATCH >= hash_bits
*/
long block_start;
/* Window position at the beginning of the current output block. Gets
* negative when the window is moved backwards.
*/
uInt match_length; /* length of best match */
IPos prev_match; /* previous match */
int match_available; /* set if previous match exists */
uInt strstart; /* start of string to insert */
uInt match_start; /* start of matching string */
uInt lookahead; /* number of valid bytes ahead in window */
uInt prev_length;
/* Length of the best match at previous step. Matches not greater than this
* are discarded. This is used in the lazy match evaluation.
*/
uInt max_chain_length;
/* To speed up deflation, hash chains are never searched beyond this
* length. A higher limit improves compression ratio but degrades the
* speed.
*/
uInt max_lazy_match;
/* Attempt to find a better match only when the current match is strictly
* smaller than this value. This mechanism is used only for compression
* levels >= 4.
*/
# define max_insert_length max_lazy_match
/* Insert new strings in the hash table only if the match length is not
* greater than this length. This saves time but degrades compression.
* max_insert_length is used only for compression levels <= 3.
*/
int level; /* compression level (1..9) */
int strategy; /* favor or force Huffman coding*/
uInt good_match;
/* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
struct tree_desc_s l_desc; /* desc. for literal tree */
struct tree_desc_s d_desc; /* desc. for distance tree */
struct tree_desc_s bl_desc; /* desc. for bit length tree */
ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
int heap_len; /* number of elements in the heap */
int heap_max; /* element of largest frequency */
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
* The same heap array is used to build all trees.
*/
uch depth[2*L_CODES+1];
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
uchf *l_buf; /* buffer for literals or lengths */
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
* limiting lit_bufsize to 64K:
* - frequencies can be kept in 16 bit counters
* - if compression is not successful for the first block, all input
* data is still in the window so we can still emit a stored block even
* when input comes from standard input. (This can also be done for
* all blocks if lit_bufsize is not greater than 32K.)
* - if compression is not successful for a file smaller than 64K, we can
* even emit a stored file instead of a stored block (saving 5 bytes).
* This is applicable only for zip (not gzip or zlib).
* - creating new Huffman trees less frequently may not provide fast
* adaptation to changes in the input data statistics. (Take for
* example a binary file with poorly compressible code followed by
* a highly compressible string table.) Smaller buffer sizes give
* fast adaptation but have of course the overhead of transmitting
* trees more frequently.
* - I can't count above 4
*/
uInt last_lit; /* running index in l_buf */
ushf *d_buf;
/* Buffer for distances. To simplify the code, d_buf and l_buf have
* the same number of elements. To use different lengths, an extra flag
* array would be necessary.
*/
ulg opt_len; /* bit length of current block with optimal trees */
ulg static_len; /* bit length of current block with static trees */
uInt matches; /* number of string matches in current block */
int last_eob_len; /* bit length of EOB code for last block */
#ifdef DEBUG
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
ush bi_buf;
/* Output buffer. bits are inserted starting at the bottom (least
* significant bits).
*/
int bi_valid;
/* Number of valid bits in bi_buf. All bits above the last valid bit
* are always zero.
*/
} FAR deflate_state;
/* Output a byte on the stream.
* IN assertion: there is enough room in pending_buf.
*/
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
*/
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
/* In order to simplify the code, particularly on 16 bit machines, match
* distances are limited to MAX_DIST instead of WSIZE.
*/
/* in trees.c */
void _tr_init OF((deflate_state *s));
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof));
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
/* Mapping from a distance to a distance code. dist is the distance - 1 and
* must not have side effects. _dist_code[256] and _dist_code[257] are never
* used.
*/
#ifndef DEBUG
/* Inline versions of _tr_tally for speed: */
#if defined(GEN_TREES_H) || !defined(STDC)
extern uch _length_code[];
extern uch _dist_code[];
#else
extern const uch _length_code[];
extern const uch _dist_code[];
#endif
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->last_lit] = 0; \
s->l_buf[s->last_lit++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (length); \
ush dist = (distance); \
s->d_buf[s->last_lit] = dist; \
s->l_buf[s->last_lit++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->last_lit == s->lit_bufsize-1); \
}
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
flush = _tr_tally(s, distance, length)
#endif
#endif

View File

@@ -0,0 +1,209 @@
/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
* Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
* File written by Gilles Vollant, by modifiying the longest_match
* from Jean-loup Gailly in deflate.c
* it prepare all parameters and call the assembly longest_match_gvasm
* longest_match execute standard C code is wmask != 0x7fff
* (assembly code is faster with a fixed wmask)
*
*/
#include "deflate.h"
#undef FAR
//#include <windows.h>
#ifdef ASMV
#define NIL 0
#define UNALIGNED_OK
/* if your C compiler don't add underline before function name,
define ADD_UNDERLINE_ASMFUNC */
#ifdef ADD_UNDERLINE_ASMFUNC
#define longest_match_7fff _longest_match_7fff
#define longest_match_686 _longest_match_686
#define cpudetect32 _cpudetect32
#endif
void match_init()
{
}
unsigned long cpudetect32();
uInt longest_match_c(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match_7fff(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match_686(
deflate_state *s,
IPos cur_match); /* current match */
uInt longest_match(
deflate_state *s,
IPos cur_match) /* current match */
{
static uInt iIsPPro=2;
if ((s->w_mask == 0x7fff) && (iIsPPro==0))
return longest_match_7fff(s,cur_match);
if (iIsPPro==1)
return longest_match_686(s,cur_match);
if (iIsPPro==2)
iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
return longest_match_c(s,cur_match);
}
uInt longest_match_c(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
unsigned chain_length = s->max_chain_length;/* max hash chain length */
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
int best_len = s->prev_length; /* best match length so far */
int nice_match = s->nice_match; /* stop if match long enough */
IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
s->strstart - (IPos)MAX_DIST(s) : NIL;
/* Stop when cur_match becomes <= limit. To simplify the code,
* we prevent matches with the string of window index 0.
*/
Posf *prev = s->prev;
uInt wmask = s->w_mask;
#ifdef UNALIGNED_OK
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
register ush scan_start = *(ushf*)scan;
register ush scan_end = *(ushf*)(scan+best_len-1);
#else
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
register Byte scan_end1 = scan[best_len-1];
register Byte scan_end = scan[best_len];
#endif
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
/* Do not waste too much time if we already have a good match: */
if (s->prev_length >= s->good_match) {
chain_length >>= 2;
}
/* Do not look for matches beyond the end of the input. This is necessary
* to make deflate deterministic.
*/
if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
do {
Assert(cur_match < s->strstart, "no future");
match = s->window + cur_match;
/* Skip to next match if the match length cannot increase
* or if the match length is less than 2:
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
* UNALIGNED_OK if your compiler uses a different size.
*/
if (*(ushf*)(match+best_len-1) != scan_end ||
*(ushf*)match != scan_start) continue;
/* It is not necessary to compare scan[2] and match[2] since they are
* always equal when the other bytes match, given that the hash keys
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
* strstart+3, +5, ... up to strstart+257. We check for insufficient
* lookahead only every 4th comparison; the 128th check will be made
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
* necessary to put more guard bytes at the end of the window, or
* to check more often for insufficient lookahead.
*/
Assert(scan[2] == match[2], "scan[2]?");
scan++, match++;
do {
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
scan < strend);
/* The funny "do {}" generates better code on most compilers */
/* Here, scan <= window+strstart+257 */
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
if (*scan == *match) scan++;
len = (MAX_MATCH - 1) - (int)(strend-scan);
scan = strend - (MAX_MATCH-1);
#else /* UNALIGNED_OK */
if (match[best_len] != scan_end ||
match[best_len-1] != scan_end1 ||
*match != *scan ||
*++match != scan[1]) continue;
/* The check at best_len-1 can be removed because it will be made
* again later. (This heuristic is not always a win.)
* It is not necessary to compare scan[2] and match[2] since they
* are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8.
*/
scan += 2, match++;
Assert(*scan == *match, "match[2]?");
/* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258.
*/
do {
} while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
len = MAX_MATCH - (int)(strend - scan);
scan = strend - MAX_MATCH;
#endif /* UNALIGNED_OK */
if (len > best_len) {
s->match_start = cur_match;
best_len = len;
if (len >= nice_match) break;
#ifdef UNALIGNED_OK
scan_end = *(ushf*)(scan+best_len-1);
#else
scan_end1 = scan[best_len-1];
scan_end = scan[best_len];
#endif
}
} while ((cur_match = prev[cur_match & wmask]) > limit
&& --chain_length != 0);
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead;
}
#endif /* ASMV */

View File

@@ -0,0 +1,875 @@
/* gzio.c -- IO on .gz files
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*
* Compile this file with -DNO_DEFLATE to avoid the compression code.
*/
/* @(#) $Id$ */
#include <stdio.h>
#include "zutil.h"
struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef Z_BUFSIZE
# ifdef MAXSEG_64K
# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
# else
# define Z_BUFSIZE 16384
# endif
#endif
#ifndef Z_PRINTF_BUFSIZE
# define Z_PRINTF_BUFSIZE 4096
#endif
#define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);}
static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xE0 /* bits 5..7: reserved */
typedef struct gz_stream {
z_stream stream;
int z_err; /* error code for last stream operation */
int z_eof; /* set if end of input file */
FILE *file; /* .gz file */
Byte *inbuf; /* input buffer */
Byte *outbuf; /* output buffer */
uLong crc; /* crc32 of uncompressed data */
char *msg; /* error message */
char *path; /* path name for debugging only */
int transparent; /* 1 if input file is not a .gz file */
char mode; /* 'w' or 'r' */
long startpos; /* start of compressed data in file (header skipped) */
} gz_stream;
local gzFile gz_open OF((const char *path, const char *mode, int fd));
local int do_flush OF((gzFile file, int flush));
local int get_byte OF((gz_stream *s));
local void check_header OF((gz_stream *s));
local int destroy OF((gz_stream *s));
local void putLong OF((FILE *file, uLong x));
local uLong getLong OF((gz_stream *s));
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descriptor
or path name (if fd == -1).
gz_open return NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno
can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR).
*/
local gzFile gz_open (path, mode, fd)
const char *path;
const char *mode;
int fd;
{
int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */
int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
char *p = (char*)mode;
gz_stream *s;
char fmode[80]; /* copy of mode, without the compression level */
char *m = fmode;
if (!path || !mode) return Z_NULL;
s = (gz_stream *)ALLOC(sizeof(gz_stream));
if (!s) return Z_NULL;
s->stream.zalloc = (alloc_func)0;
s->stream.zfree = (free_func)0;
s->stream.opaque = (voidpf)0;
s->stream.next_in = s->inbuf = Z_NULL;
s->stream.next_out = s->outbuf = Z_NULL;
s->stream.avail_in = s->stream.avail_out = 0;
s->file = NULL;
s->z_err = Z_OK;
s->z_eof = 0;
s->crc = crc32(0L, Z_NULL, 0);
s->msg = NULL;
s->transparent = 0;
s->path = (char*)ALLOC(strlen(path)+1);
if (s->path == NULL) {
return destroy(s), (gzFile)Z_NULL;
}
strcpy(s->path, path); /* do this early for debugging */
s->mode = '\0';
do {
if (*p == 'r') s->mode = 'r';
if (*p == 'w' || *p == 'a') s->mode = 'w';
if (*p >= '0' && *p <= '9') {
level = *p - '0';
} else if (*p == 'f') {
strategy = Z_FILTERED;
} else if (*p == 'h') {
strategy = Z_HUFFMAN_ONLY;
} else {
*m++ = *p; /* copy the mode */
}
} while (*p++ && m != fmode + sizeof(fmode));
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') {
#ifdef NO_DEFLATE
err = Z_STREAM_ERROR;
#else
err = deflateInit2(&(s->stream), level,
Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
/* windowBits is passed < 0 to suppress zlib header */
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
#endif
if (err != Z_OK || s->outbuf == Z_NULL) {
return destroy(s), (gzFile)Z_NULL;
}
} else {
s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
err = inflateInit2(&(s->stream), -MAX_WBITS);
/* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and
* return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
* present after the compressed stream.
*/
if (err != Z_OK || s->inbuf == Z_NULL) {
return destroy(s), (gzFile)Z_NULL;
}
}
s->stream.avail_out = Z_BUFSIZE;
errno = 0;
s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
if (s->file == NULL) {
return destroy(s), (gzFile)Z_NULL;
}
if (s->mode == 'w') {
/* Write a very simple .gz header:
*/
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
s->startpos = 10L;
/* We use 10L instead of ftell(s->file) to because ftell causes an
* fflush on some systems. This version of the library doesn't use
* startpos anyway in write mode, so this initialization is not
* necessary.
*/
} else {
check_header(s); /* skip the .gz header */
s->startpos = (ftell(s->file) - s->stream.avail_in);
}
return (gzFile)s;
}
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing.
*/
gzFile ZEXPORT gzopen (path, mode)
const char *path;
const char *mode;
{
return gz_open (path, mode, -1);
}
/* ===========================================================================
Associate a gzFile with the file descriptor fd. fd is not dup'ed here
to mimic the behavio(u)r of fdopen.
*/
gzFile ZEXPORT gzdopen (fd, mode)
int fd;
const char *mode;
{
char name[20];
if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */
return gz_open (name, mode, fd);
}
/* ===========================================================================
* Update the compression level and strategy
*/
int ZEXPORT gzsetparams (file, level, strategy)
gzFile file;
int level;
int strategy;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
/* Make room to allow flushing */
if (s->stream.avail_out == 0) {
s->stream.next_out = s->outbuf;
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
s->z_err = Z_ERRNO;
}
s->stream.avail_out = Z_BUFSIZE;
}
return deflateParams (&(s->stream), level, strategy);
}
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
IN assertion: the stream s has been sucessfully opened for reading.
*/
local int get_byte(s)
gz_stream *s;
{
if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) {
errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) s->z_err = Z_ERRNO;
return EOF;
}
s->stream.next_in = s->inbuf;
}
s->stream.avail_in--;
return *(s->stream.next_in)++;
}
/* ===========================================================================
Check the gzip header of a gz_stream opened for reading. Set the stream
mode to transparent if the gzip magic header is not present; set s->err
to Z_DATA_ERROR if the magic header is present but the rest of the header
is incorrect.
IN assertion: the stream s has already been created sucessfully;
s->stream.avail_in is zero for the first time, but may be non-zero
for concatenated .gz files.
*/
local void check_header(s)
gz_stream *s;
{
int method; /* method byte */
int flags; /* flags byte */
uInt len;
int c;
/* Check the gzip magic header */
for (len = 0; len < 2; len++) {
c = get_byte(s);
if (c != gz_magic[len]) {
if (len != 0) s->stream.avail_in++, s->stream.next_in--;
if (c != EOF) {
s->stream.avail_in++, s->stream.next_in--;
s->transparent = 1;
}
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
return;
}
}
method = get_byte(s);
flags = get_byte(s);
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
s->z_err = Z_DATA_ERROR;
return;
}
/* Discard time, xflags and OS code: */
for (len = 0; len < 6; len++) (void)get_byte(s);
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
len = (uInt)get_byte(s);
len += ((uInt)get_byte(s))<<8;
/* len is garbage if EOF but the loop below will quit anyway */
while (len-- != 0 && get_byte(s) != EOF) ;
}
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
while ((c = get_byte(s)) != 0 && c != EOF) ;
}
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
while ((c = get_byte(s)) != 0 && c != EOF) ;
}
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
for (len = 0; len < 2; len++) (void)get_byte(s);
}
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
}
/* ===========================================================================
* Cleanup then free the given gz_stream. Return a zlib error code.
Try freeing in the reverse order of allocations.
*/
local int destroy (s)
gz_stream *s;
{
int err = Z_OK;
if (!s) return Z_STREAM_ERROR;
TRYFREE(s->msg);
if (s->stream.state != NULL) {
if (s->mode == 'w') {
#ifdef NO_DEFLATE
err = Z_STREAM_ERROR;
#else
err = deflateEnd(&(s->stream));
#endif
} else if (s->mode == 'r') {
err = inflateEnd(&(s->stream));
}
}
if (s->file != NULL && fclose(s->file)) {
#ifdef ESPIPE
if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
#endif
err = Z_ERRNO;
}
if (s->z_err < 0) err = s->z_err;
TRYFREE(s->inbuf);
TRYFREE(s->outbuf);
TRYFREE(s->path);
TRYFREE(s);
return err;
}
/* ===========================================================================
Reads the given number of uncompressed bytes from the compressed file.
gzread returns the number of bytes actually read (0 for end of file).
*/
int ZEXPORT gzread (file, buf, len)
gzFile file;
voidp buf;
unsigned len;
{
gz_stream *s = (gz_stream*)file;
Bytef *start = (Bytef*)buf; /* starting point for crc computation */
Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
if (s->z_err == Z_STREAM_END) return 0; /* EOF */
next_out = (Byte*)buf;
s->stream.next_out = (Bytef*)buf;
s->stream.avail_out = len;
while (s->stream.avail_out != 0) {
if (s->transparent) {
/* Copy first the lookahead bytes: */
uInt n = s->stream.avail_in;
if (n > s->stream.avail_out) n = s->stream.avail_out;
if (n > 0) {
zmemcpy(s->stream.next_out, s->stream.next_in, n);
next_out += n;
s->stream.next_out = next_out;
s->stream.next_in += n;
s->stream.avail_out -= n;
s->stream.avail_in -= n;
}
if (s->stream.avail_out > 0) {
s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
s->file);
}
len -= s->stream.avail_out;
s->stream.total_in += (uLong)len;
s->stream.total_out += (uLong)len;
if (len == 0) s->z_eof = 1;
return (int)len;
}
if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) {
s->z_err = Z_ERRNO;
break;
}
}
s->stream.next_in = s->inbuf;
}
s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err == Z_STREAM_END) {
/* Check CRC and original size */
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
start = s->stream.next_out;
if (getLong(s) != s->crc) {
s->z_err = Z_DATA_ERROR;
} else {
(void)getLong(s);
/* The uncompressed length returned by above getlong() may
* be different from s->stream.total_out) in case of
* concatenated .gz files. Check for such files:
*/
check_header(s);
if (s->z_err == Z_OK) {
uLong total_in = s->stream.total_in;
uLong total_out = s->stream.total_out;
inflateReset(&(s->stream));
s->stream.total_in = total_in;
s->stream.total_out = total_out;
s->crc = crc32(0L, Z_NULL, 0);
}
}
}
if (s->z_err != Z_OK || s->z_eof) break;
}
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
return (int)(len - s->stream.avail_out);
}
/* ===========================================================================
Reads one byte from the compressed file. gzgetc returns this byte
or -1 in case of end of file or error.
*/
int ZEXPORT gzgetc(file)
gzFile file;
{
unsigned char c;
return gzread(file, &c, 1) == 1 ? c : -1;
}
/* ===========================================================================
Reads bytes from the compressed file until len-1 characters are
read, or a newline character is read and transferred to buf, or an
end-of-file condition is encountered. The string is then terminated
with a null character.
gzgets returns buf, or Z_NULL in case of error.
The current implementation is not optimized at all.
*/
char * ZEXPORT gzgets(file, buf, len)
gzFile file;
char *buf;
int len;
{
char *b = buf;
if (buf == Z_NULL || len <= 0) return Z_NULL;
while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
*buf = '\0';
return b == buf && len > 0 ? Z_NULL : b;
}
#ifndef NO_DEFLATE
/* ===========================================================================
Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of bytes actually written (0 in case of error).
*/
int ZEXPORT gzwrite (file, buf, len)
gzFile file;
const voidp buf;
unsigned len;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
s->stream.next_in = (Bytef*)buf;
s->stream.avail_in = len;
while (s->stream.avail_in != 0) {
if (s->stream.avail_out == 0) {
s->stream.next_out = s->outbuf;
if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
s->z_err = Z_ERRNO;
break;
}
s->stream.avail_out = Z_BUFSIZE;
}
s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err != Z_OK) break;
}
s->crc = crc32(s->crc, (const Bytef *)buf, len);
return (int)(len - s->stream.avail_in);
}
/* ===========================================================================
Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written (0 in case of error).
*/
#ifdef STDC
#include <stdarg.h>
int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
{
char buf[Z_PRINTF_BUFSIZE];
va_list va;
int len;
va_start(va, format);
#ifdef HAS_vsnprintf
(void)vsnprintf(buf, sizeof(buf), format, va);
#else
(void)vsprintf(buf, format, va);
#endif
va_end(va);
len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
if (len <= 0) return 0;
return gzwrite(file, buf, (unsigned)len);
}
#else /* not ANSI C */
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
gzFile file;
const char *format;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{
char buf[Z_PRINTF_BUFSIZE];
int len;
#ifdef HAS_snprintf
snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
#else
sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
#endif
len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
if (len <= 0) return 0;
return gzwrite(file, buf, len);
}
#endif
/* ===========================================================================
Writes c, converted to an unsigned char, into the compressed file.
gzputc returns the value that was written, or -1 in case of error.
*/
int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
unsigned char cc = (unsigned char) c; /* required for big endian systems */
return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
}
/* ===========================================================================
Writes the given null-terminated string to the compressed file, excluding
the terminating null character.
gzputs returns the number of characters written, or -1 in case of error.
*/
int ZEXPORT gzputs(file, s)
gzFile file;
const char *s;
{
return gzwrite(file, (char*)s, (unsigned)strlen(s));
}
/* ===========================================================================
Flushes all pending output into the compressed file. The parameter
flush is as in the deflate() function.
*/
local int do_flush (file, flush)
gzFile file;
int flush;
{
uInt len;
int done = 0;
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
s->stream.avail_in = 0; /* should be zero already anyway */
for (;;) {
len = Z_BUFSIZE - s->stream.avail_out;
if (len != 0) {
if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
s->z_err = Z_ERRNO;
return Z_ERRNO;
}
s->stream.next_out = s->outbuf;
s->stream.avail_out = Z_BUFSIZE;
}
if (done) break;
s->z_err = deflate(&(s->stream), flush);
/* Ignore the second of two consecutive flushes: */
if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
/* deflate has finished flushing only when it hasn't used up
* all the available space in the output buffer:
*/
done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
}
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
}
int ZEXPORT gzflush (file, flush)
gzFile file;
int flush;
{
gz_stream *s = (gz_stream*)file;
int err = do_flush (file, flush);
if (err) return err;
fflush(s->file);
return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
}
#endif /* NO_DEFLATE */
/* ===========================================================================
Sets the starting position for the next gzread or gzwrite on the given
compressed file. The offset represents a number of bytes in the
gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error.
SEEK_END is not implemented, returns error.
In this version of the library, gzseek can be extremely slow.
*/
z_off_t ZEXPORT gzseek (file, offset, whence)
gzFile file;
z_off_t offset;
int whence;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || whence == SEEK_END ||
s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
return -1L;
}
if (s->mode == 'w') {
#ifdef NO_DEFLATE
return -1L;
#else
if (whence == SEEK_SET) {
offset -= s->stream.total_in;
}
if (offset < 0) return -1L;
/* At this point, offset is the number of zero bytes to write. */
if (s->inbuf == Z_NULL) {
s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
zmemzero(s->inbuf, Z_BUFSIZE);
}
while (offset > 0) {
uInt size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (uInt)offset;
size = gzwrite(file, s->inbuf, size);
if (size == 0) return -1L;
offset -= size;
}
return (z_off_t)s->stream.total_in;
#endif
}
/* Rest of function is for reading only */
/* compute absolute position */
if (whence == SEEK_CUR) {
offset += s->stream.total_out;
}
if (offset < 0) return -1L;
if (s->transparent) {
/* map to fseek */
s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
s->stream.total_in = s->stream.total_out = (uLong)offset;
return offset;
}
/* For a negative seek, rewind and use positive seek */
if ((uLong)offset >= s->stream.total_out) {
offset -= s->stream.total_out;
} else if (gzrewind(file) < 0) {
return -1L;
}
/* offset is now the number of bytes to skip. */
if (offset != 0 && s->outbuf == Z_NULL) {
s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
}
while (offset > 0) {
int size = Z_BUFSIZE;
if (offset < Z_BUFSIZE) size = (int)offset;
size = gzread(file, s->outbuf, (uInt)size);
if (size <= 0) return -1L;
offset -= size;
}
return (z_off_t)s->stream.total_out;
}
/* ===========================================================================
Rewinds input file.
*/
int ZEXPORT gzrewind (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
if (s == NULL || s->mode != 'r') return -1;
s->z_err = Z_OK;
s->z_eof = 0;
s->stream.avail_in = 0;
s->stream.next_in = s->inbuf;
s->crc = crc32(0L, Z_NULL, 0);
if (s->startpos == 0) { /* not a compressed file */
rewind(s->file);
return 0;
}
(void) inflateReset(&s->stream);
return fseek(s->file, s->startpos, SEEK_SET);
}
/* ===========================================================================
Returns the starting position for the next gzread or gzwrite on the
given compressed file. This position represents a number of bytes in the
uncompressed data stream.
*/
z_off_t ZEXPORT gztell (file)
gzFile file;
{
return gzseek(file, 0L, SEEK_CUR);
}
/* ===========================================================================
Returns 1 when EOF has previously been detected reading the given
input stream, otherwise zero.
*/
int ZEXPORT gzeof (file)
gzFile file;
{
gz_stream *s = (gz_stream*)file;
return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
}
/* ===========================================================================
Outputs a long in LSB order to the given file
*/
local void putLong (file, x)
FILE *file;
uLong x;
{
int n;
for (n = 0; n < 4; n++) {
fputc((int)(x & 0xff), file);
x >>= 8;
}
}
/* ===========================================================================
Reads a long in LSB order from the given gz_stream. Sets z_err in case
of error.
*/
local uLong getLong (s)
gz_stream *s;
{
uLong x = (uLong)get_byte(s);
int c;
x += ((uLong)get_byte(s))<<8;
x += ((uLong)get_byte(s))<<16;
c = get_byte(s);
if (c == EOF) s->z_err = Z_DATA_ERROR;
x += ((uLong)c)<<24;
return x;
}
/* ===========================================================================
Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state.
*/
int ZEXPORT gzclose (file)
gzFile file;
{
int err;
gz_stream *s = (gz_stream*)file;
if (s == NULL) return Z_STREAM_ERROR;
if (s->mode == 'w') {
#ifdef NO_DEFLATE
return Z_STREAM_ERROR;
#else
err = do_flush (file, Z_FINISH);
if (err != Z_OK) return destroy((gz_stream*)file);
putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in);
#endif
}
return destroy((gz_stream*)file);
}
/* ===========================================================================
Returns the error message for the last error which occured on the
given compressed file. errnum is set to zlib error number. If an
error occured in the file system and not in the compression library,
errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code.
*/
const char* ZEXPORT gzerror (file, errnum)
gzFile file;
int *errnum;
{
char *m;
gz_stream *s = (gz_stream*)file;
if (s == NULL) {
*errnum = Z_STREAM_ERROR;
return (const char*)ERR_MSG(Z_STREAM_ERROR);
}
*errnum = s->z_err;
if (*errnum == Z_OK) return (const char*)"";
m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
TRYFREE(s->msg);
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
strcpy(s->msg, s->path);
strcat(s->msg, ": ");
strcat(s->msg, m);
return (const char*)s->msg;
}

View File

@@ -0,0 +1,398 @@
/* infblock.c -- interpret and process block types to last block
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
#include "inftrees.h"
#include "infcodes.h"
#include "infutil.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
/* Table for deflate from PKZIP's appnote.txt. */
local const uInt border[] = { /* Order of the bit length code lengths */
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/*
Notes beyond the 1.93a appnote.txt:
1. Distance pointers never point before the beginning of the output
stream.
2. Distance pointers can point back across blocks, up to 32k away.
3. There is an implied maximum of 7 bits for the bit length table and
15 bits for the actual data.
4. If only one code exists, then it is encoded using one bit. (Zero
would be more efficient, but perhaps a little confusing.) If two
codes exist, they are coded using one bit each (0 and 1).
5. There is no way of sending zero distance codes--a dummy must be
sent if there are none. (History: a pre 2.0 version of PKZIP would
store blocks with no distance codes, but this was discovered to be
too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
zero distance codes, which is sent as one code of zero bits in
length.
6. There are up to 286 literal/length codes. Code 256 represents the
end-of-block. Note however that the static length tree defines
288 codes just to fill out the Huffman codes. Codes 286 and 287
cannot be used though, since there is no length base or extra bits
defined for them. Similarily, there are up to 30 distance codes.
However, static trees define 32 codes (all 5 bits) to fill out the
Huffman codes, but the last two had better not show up in the data.
7. Unzip can check dynamic Huffman blocks for complete code sets.
The exception is that a single code would not be complete (see #4).
8. The five bits following the block type is really the number of
literal codes sent minus 257.
9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
(1+6+6). Therefore, to output three times the length, you output
three codes (1+1+1), whereas to output four times the same length,
you only need two codes (1+3). Hmm.
10. In the tree reconstruction algorithm, Code = Code + Increment
only if BitLength(i) is not zero. (Pretty obvious.)
11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
12. Note: length code 284 can represent 227-258, but length code 285
really is 258. The last length deserves its own, short code
since it gets used a lot in very redundant files. The length
258 is special since 258 - 3 (the min match length) is 255.
13. The literal/length and distance code bit lengths are read as a
single stream of lengths. It is possible (and advantageous) for
a repeat code (16, 17, or 18) to go across the boundary between
the two sets of lengths.
*/
void inflate_blocks_reset(s, z, c)
inflate_blocks_statef *s;
z_streamp z;
uLongf *c;
{
if (c != Z_NULL)
*c = s->check;
if (s->mode == BTREE || s->mode == DTREE)
ZFREE(z, s->sub.trees.blens);
if (s->mode == CODES)
inflate_codes_free(s->sub.decode.codes, z);
s->mode = TYPE;
s->bitk = 0;
s->bitb = 0;
s->read = s->write = s->window;
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
Tracev((stderr, "inflate: blocks reset\n"));
}
inflate_blocks_statef *inflate_blocks_new(z, c, w)
z_streamp z;
check_func c;
uInt w;
{
inflate_blocks_statef *s;
if ((s = (inflate_blocks_statef *)ZALLOC
(z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
return s;
if ((s->hufts =
(inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
{
ZFREE(z, s);
return Z_NULL;
}
if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
{
ZFREE(z, s->hufts);
ZFREE(z, s);
return Z_NULL;
}
s->end = s->window + w;
s->checkfn = c;
s->mode = TYPE;
Tracev((stderr, "inflate: blocks allocated\n"));
inflate_blocks_reset(s, z, Z_NULL);
return s;
}
int inflate_blocks(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt t; /* temporary storage */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input based on current state */
while (1) switch (s->mode)
{
case TYPE:
NEEDBITS(3)
t = (uInt)b & 7;
s->last = t & 1;
switch (t >> 1)
{
case 0: /* stored */
Tracev((stderr, "inflate: stored block%s\n",
s->last ? " (last)" : ""));
DUMPBITS(3)
t = k & 7; /* go to byte boundary */
DUMPBITS(t)
s->mode = LENS; /* get length of stored block */
break;
case 1: /* fixed */
Tracev((stderr, "inflate: fixed codes block%s\n",
s->last ? " (last)" : ""));
{
uInt bl, bd;
inflate_huft *tl, *td;
inflate_trees_fixed(&bl, &bd, &tl, &td, z);
s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
if (s->sub.decode.codes == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
}
DUMPBITS(3)
s->mode = CODES;
break;
case 2: /* dynamic */
Tracev((stderr, "inflate: dynamic codes block%s\n",
s->last ? " (last)" : ""));
DUMPBITS(3)
s->mode = TABLE;
break;
case 3: /* illegal */
DUMPBITS(3)
s->mode = BAD;
z->msg = (char*)"invalid block type";
r = Z_DATA_ERROR;
LEAVE
}
break;
case LENS:
NEEDBITS(32)
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{
s->mode = BAD;
z->msg = (char*)"invalid stored block lengths";
r = Z_DATA_ERROR;
LEAVE
}
s->sub.left = (uInt)b & 0xffff;
b = k = 0; /* dump bits */
Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
break;
case STORED:
if (n == 0)
LEAVE
NEEDOUT
t = s->sub.left;
if (t > n) t = n;
if (t > m) t = m;
zmemcpy(q, p, t);
p += t; n -= t;
q += t; m -= t;
if ((s->sub.left -= t) != 0)
break;
Tracev((stderr, "inflate: stored end, %lu total out\n",
z->total_out + (q >= s->read ? q - s->read :
(s->end - s->read) + (q - s->window))));
s->mode = s->last ? DRY : TYPE;
break;
case TABLE:
NEEDBITS(14)
s->sub.trees.table = t = (uInt)b & 0x3fff;
#ifndef PKZIP_BUG_WORKAROUND
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{
s->mode = BAD;
z->msg = (char*)"too many length or distance symbols";
r = Z_DATA_ERROR;
LEAVE
}
#endif
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
DUMPBITS(14)
s->sub.trees.index = 0;
Tracev((stderr, "inflate: table sizes ok\n"));
s->mode = BTREE;
case BTREE:
while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
{
NEEDBITS(3)
s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
DUMPBITS(3)
}
while (s->sub.trees.index < 19)
s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
s->sub.trees.bb = 7;
t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
&s->sub.trees.tb, s->hufts, z);
if (t != Z_OK)
{
ZFREE(z, s->sub.trees.blens);
r = t;
if (r == Z_DATA_ERROR)
s->mode = BAD;
LEAVE
}
s->sub.trees.index = 0;
Tracev((stderr, "inflate: bits tree ok\n"));
s->mode = DTREE;
case DTREE:
while (t = s->sub.trees.table,
s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
{
inflate_huft *h;
uInt i, j, c;
t = s->sub.trees.bb;
NEEDBITS(t)
h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
t = h->bits;
c = h->base;
if (c < 16)
{
DUMPBITS(t)
s->sub.trees.blens[s->sub.trees.index++] = c;
}
else /* c == 16..18 */
{
i = c == 18 ? 7 : c - 14;
j = c == 18 ? 11 : 3;
NEEDBITS(t + i)
DUMPBITS(t)
j += (uInt)b & inflate_mask[i];
DUMPBITS(i)
i = s->sub.trees.index;
t = s->sub.trees.table;
if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
(c == 16 && i < 1))
{
ZFREE(z, s->sub.trees.blens);
s->mode = BAD;
z->msg = (char*)"invalid bit length repeat";
r = Z_DATA_ERROR;
LEAVE
}
c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
do {
s->sub.trees.blens[i++] = c;
} while (--j);
s->sub.trees.index = i;
}
}
s->sub.trees.tb = Z_NULL;
{
uInt bl, bd;
inflate_huft *tl, *td;
inflate_codes_statef *c;
bl = 9; /* must be <= 9 for lookahead assumptions */
bd = 6; /* must be <= 9 for lookahead assumptions */
t = s->sub.trees.table;
t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
s->sub.trees.blens, &bl, &bd, &tl, &td,
s->hufts, z);
ZFREE(z, s->sub.trees.blens);
if (t != Z_OK)
{
if (t == (uInt)Z_DATA_ERROR)
s->mode = BAD;
r = t;
LEAVE
}
Tracev((stderr, "inflate: trees ok\n"));
if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
{
r = Z_MEM_ERROR;
LEAVE
}
s->sub.decode.codes = c;
}
s->mode = CODES;
case CODES:
UPDATE
if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
return inflate_flush(s, z, r);
r = Z_OK;
inflate_codes_free(s->sub.decode.codes, z);
LOAD
Tracev((stderr, "inflate: codes end, %lu total out\n",
z->total_out + (q >= s->read ? q - s->read :
(s->end - s->read) + (q - s->window))));
if (!s->last)
{
s->mode = TYPE;
break;
}
s->mode = DRY;
case DRY:
FLUSH
if (s->read != s->write)
LEAVE
s->mode = DONE;
case DONE:
r = Z_STREAM_END;
LEAVE
case BAD:
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
}
int inflate_blocks_free(s, z)
inflate_blocks_statef *s;
z_streamp z;
{
inflate_blocks_reset(s, z, Z_NULL);
ZFREE(z, s->window);
ZFREE(z, s->hufts);
ZFREE(z, s);
Tracev((stderr, "inflate: blocks freed\n"));
return Z_OK;
}
void inflate_set_dictionary(s, d, n)
inflate_blocks_statef *s;
const Bytef *d;
uInt n;
{
zmemcpy(s->window, d, n);
s->read = s->write = s->window + n;
}
/* Returns true if inflate is currently at the end of a block generated
* by Z_SYNC_FLUSH or Z_FULL_FLUSH.
* IN assertion: s != Z_NULL
*/
int inflate_blocks_sync_point(s)
inflate_blocks_statef *s;
{
return s->mode == LENS;
}

View File

@@ -0,0 +1,39 @@
/* infblock.h -- header to use infblock.c
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
struct inflate_blocks_state;
typedef struct inflate_blocks_state FAR inflate_blocks_statef;
extern inflate_blocks_statef * inflate_blocks_new OF((
z_streamp z,
check_func c, /* check function */
uInt w)); /* window size */
extern int inflate_blocks OF((
inflate_blocks_statef *,
z_streamp ,
int)); /* initial return code */
extern void inflate_blocks_reset OF((
inflate_blocks_statef *,
z_streamp ,
uLongf *)); /* check value on output */
extern int inflate_blocks_free OF((
inflate_blocks_statef *,
z_streamp));
extern void inflate_set_dictionary OF((
inflate_blocks_statef *s,
const Bytef *d, /* dictionary */
uInt n)); /* dictionary length */
extern int inflate_blocks_sync_point OF((
inflate_blocks_statef *s));

View File

@@ -0,0 +1,257 @@
/* infcodes.c -- process literals and length/distance pairs
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "infblock.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h"
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
START, /* x: set up for LEN */
LEN, /* i: get length/literal/eob next */
LENEXT, /* i: getting length extra (have base) */
DIST, /* i: get distance next */
DISTEXT, /* i: getting distance extra */
COPY, /* o: copying bytes in window, waiting for space */
LIT, /* o: got literal, waiting for output space */
WASH, /* o: got eob, possibly still output waiting */
END, /* x: got eob and all data flushed */
BADCODE} /* x: got error */
inflate_codes_mode;
/* inflate codes private state */
struct inflate_codes_state {
/* mode */
inflate_codes_mode mode; /* current inflate_codes mode */
/* mode dependent information */
uInt len;
union {
struct {
inflate_huft *tree; /* pointer into tree */
uInt need; /* bits needed */
} code; /* if LEN or DIST, where in tree */
uInt lit; /* if LIT, literal */
struct {
uInt get; /* bits to get for extra */
uInt dist; /* distance back to copy from */
} copy; /* if EXT or COPY, where and how much */
} sub; /* submode */
/* mode independent information */
Byte lbits; /* ltree bits decoded per branch */
Byte dbits; /* dtree bits decoder per branch */
inflate_huft *ltree; /* literal/length/eob tree */
inflate_huft *dtree; /* distance tree */
};
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
uInt bl, bd;
inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
z_streamp z;
{
inflate_codes_statef *c;
if ((c = (inflate_codes_statef *)
ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
{
c->mode = START;
c->lbits = (Byte)bl;
c->dbits = (Byte)bd;
c->ltree = tl;
c->dtree = td;
Tracev((stderr, "inflate: codes new\n"));
}
return c;
}
int inflate_codes(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt j; /* temporary storage */
inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
Bytef *f; /* pointer to copy strings from */
inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input and output based on current state */
while (1) switch (c->mode)
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
case START: /* x: set up for LEN */
#ifndef SLOW
if (m >= 258 && n >= 10)
{
UPDATE
r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
LOAD
if (r != Z_OK)
{
c->mode = r == Z_STREAM_END ? WASH : BADCODE;
break;
}
}
#endif /* !SLOW */
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
case LEN: /* i: get length/literal/eob next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e == 0) /* literal */
{
c->sub.lit = t->base;
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", t->base));
c->mode = LIT;
break;
}
if (e & 16) /* length */
{
c->sub.copy.get = e & 15;
c->len = t->base;
c->mode = LENEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
if (e & 32) /* end of block */
{
Tracevv((stderr, "inflate: end of block\n"));
c->mode = WASH;
break;
}
c->mode = BADCODE; /* invalid code */
z->msg = (char*)"invalid literal/length code";
r = Z_DATA_ERROR;
LEAVE
case LENEXT: /* i: getting length extra (have base) */
j = c->sub.copy.get;
NEEDBITS(j)
c->len += (uInt)b & inflate_mask[j];
DUMPBITS(j)
c->sub.code.need = c->dbits;
c->sub.code.tree = c->dtree;
Tracevv((stderr, "inflate: length %u\n", c->len));
c->mode = DIST;
case DIST: /* i: get distance next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e & 16) /* distance */
{
c->sub.copy.get = e & 15;
c->sub.copy.dist = t->base;
c->mode = DISTEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
c->mode = BADCODE; /* invalid code */
z->msg = (char*)"invalid distance code";
r = Z_DATA_ERROR;
LEAVE
case DISTEXT: /* i: getting distance extra */
j = c->sub.copy.get;
NEEDBITS(j)
c->sub.copy.dist += (uInt)b & inflate_mask[j];
DUMPBITS(j)
Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
c->mode = COPY;
case COPY: /* o: copying bytes in window, waiting for space */
#ifndef __TURBOC__ /* Turbo C bug for following expression */
f = (uInt)(q - s->window) < c->sub.copy.dist ?
s->end - (c->sub.copy.dist - (q - s->window)) :
q - c->sub.copy.dist;
#else
f = q - c->sub.copy.dist;
if ((uInt)(q - s->window) < c->sub.copy.dist)
f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
#endif
while (c->len)
{
NEEDOUT
OUTBYTE(*f++)
if (f == s->end)
f = s->window;
c->len--;
}
c->mode = START;
break;
case LIT: /* o: got literal, waiting for output space */
NEEDOUT
OUTBYTE(c->sub.lit)
c->mode = START;
break;
case WASH: /* o: got eob, possibly more output */
if (k > 7) /* return unused byte, if any */
{
Assert(k < 16, "inflate_codes grabbed too many bytes")
k -= 8;
n++;
p--; /* can always return one */
}
FLUSH
if (s->read != s->write)
LEAVE
c->mode = END;
case END:
r = Z_STREAM_END;
LEAVE
case BADCODE: /* x: got error */
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
#ifdef NEED_DUMMY_RETURN
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
#endif
}
void inflate_codes_free(c, z)
inflate_codes_statef *c;
z_streamp z;
{
ZFREE(z, c);
Tracev((stderr, "inflate: codes free\n"));
}

View File

@@ -0,0 +1,27 @@
/* infcodes.h -- header to use infcodes.c
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
struct inflate_codes_state;
typedef struct inflate_codes_state FAR inflate_codes_statef;
extern inflate_codes_statef *inflate_codes_new OF((
uInt, uInt,
inflate_huft *, inflate_huft *,
z_streamp ));
extern int inflate_codes OF((
inflate_blocks_statef *,
z_streamp ,
int));
extern void inflate_codes_free OF((
inflate_codes_statef *,
z_streamp ));

View File

@@ -0,0 +1,170 @@
/* inffast.c -- process literals and length/distance pairs fast
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "infblock.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
/* macros for bit input with no checking and for returning unused bytes */
#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
/* Called with number of bytes left to write in window at least 258
(the maximum string length) and number of input bytes available
at least ten. The ten bytes are six bytes for the longest length/
distance pair plus four bytes for overloading the bit buffer. */
int inflate_fast(bl, bd, tl, td, s, z)
uInt bl, bd;
inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
inflate_blocks_statef *s;
z_streamp z;
{
inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
uInt ml; /* mask for literal/length tree */
uInt md; /* mask for distance tree */
uInt c; /* bytes to copy */
uInt d; /* distance back to copy from */
Bytef *r; /* copy source pointer */
/* load input, output, bit values */
LOAD
/* initialize masks */
ml = inflate_mask[bl];
md = inflate_mask[bd];
/* do until not enough input or output space for fast loop */
do { /* assume called with m >= 258 && n >= 10 */
/* get literal/length code */
GRABBITS(20) /* max bits for literal/length code */
if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
continue;
}
do {
DUMPBITS(t->bits)
if (e & 16)
{
/* get extra bits for length */
e &= 15;
c = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * length %u\n", c));
/* decode distance base of block to copy */
GRABBITS(15); /* max bits for distance code */
e = (t = td + ((uInt)b & md))->exop;
do {
DUMPBITS(t->bits)
if (e & 16)
{
/* get extra bits to add to distance base */
e &= 15;
GRABBITS(e) /* get extra bits (up to 13) */
d = t->base + ((uInt)b & inflate_mask[e]);
DUMPBITS(e)
Tracevv((stderr, "inflate: * distance %u\n", d));
/* do the copy */
m -= c;
if ((uInt)(q - s->window) >= d) /* offset before dest */
{ /* just copy */
r = q - d;
*q++ = *r++; c--; /* minimum count is three, */
*q++ = *r++; c--; /* so unroll loop a little */
}
else /* else offset after destination */
{
e = d - (uInt)(q - s->window); /* bytes from offset to end */
r = s->end - e; /* pointer to offset */
if (c > e) /* if source crosses, */
{
c -= e; /* copy to end of window */
do {
*q++ = *r++;
} while (--e);
r = s->window; /* copy rest from start of window */
}
}
do { /* copy all or what's left */
*q++ = *r++;
} while (--c);
break;
}
else if ((e & 64) == 0)
{
t += t->base;
e = (t += ((uInt)b & inflate_mask[e]))->exop;
}
else
{
z->msg = (char*)"invalid distance code";
UNGRAB
UPDATE
return Z_DATA_ERROR;
}
} while (1);
break;
}
if ((e & 64) == 0)
{
t += t->base;
if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
{
DUMPBITS(t->bits)
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
"inflate: * literal '%c'\n" :
"inflate: * literal 0x%02x\n", t->base));
*q++ = (Byte)t->base;
m--;
break;
}
}
else if (e & 32)
{
Tracevv((stderr, "inflate: * end of block\n"));
UNGRAB
UPDATE
return Z_STREAM_END;
}
else
{
z->msg = (char*)"invalid literal/length code";
UNGRAB
UPDATE
return Z_DATA_ERROR;
}
} while (1);
} while (m >= 258 && n >= 10);
/* not enough input or output--restore pointers and return */
UNGRAB
UPDATE
return Z_OK;
}

View File

@@ -0,0 +1,17 @@
/* inffast.h -- header to use inffast.c
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
extern int inflate_fast OF((
uInt,
uInt,
inflate_huft *,
inflate_huft *,
inflate_blocks_statef *,
z_streamp ));

View File

@@ -0,0 +1,151 @@
/* inffixed.h -- table for decoding fixed codes
* Generated automatically by the maketree.c program
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
local uInt fixed_bl = 9;
local uInt fixed_bd = 5;
local inflate_huft fixed_tl[] = {
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
{{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
{{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
{{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
{{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
{{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
{{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
{{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
{{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
{{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
{{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
{{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
{{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
{{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
{{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
{{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
{{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
{{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
{{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
{{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
{{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
{{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
{{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
{{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
{{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
{{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
{{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
{{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
{{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
{{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
{{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
{{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
{{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
{{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
{{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
{{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
{{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
{{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
{{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
{{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
{{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
{{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
{{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
{{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
{{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
{{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
{{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
{{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
{{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
{{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
{{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
{{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
{{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
{{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
{{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
{{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
{{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
{{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
{{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
{{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
{{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
{{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
{{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
{{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
};
local inflate_huft fixed_td[] = {
{{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
{{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
{{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
{{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
{{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
{{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
{{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
{{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
};

View File

@@ -0,0 +1,366 @@
/* inflate.c -- zlib interface to inflate modules
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
typedef enum {
METHOD, /* waiting for method byte */
FLAG, /* waiting for flag byte */
DICT4, /* four dictionary check bytes to go */
DICT3, /* three dictionary check bytes to go */
DICT2, /* two dictionary check bytes to go */
DICT1, /* one dictionary check byte to go */
DICT0, /* waiting for inflateSetDictionary */
BLOCKS, /* decompressing blocks */
CHECK4, /* four check bytes to go */
CHECK3, /* three check bytes to go */
CHECK2, /* two check bytes to go */
CHECK1, /* one check byte to go */
DONE, /* finished check, done */
BAD} /* got an error--stay here */
inflate_mode;
/* inflate private state */
struct internal_state {
/* mode */
inflate_mode mode; /* current inflate mode */
/* mode dependent information */
union {
uInt method; /* if FLAGS, method byte */
struct {
uLong was; /* computed check value */
uLong need; /* stream check value */
} check; /* if CHECK, check values to compare */
uInt marker; /* if BAD, inflateSync's marker bytes count */
} sub; /* submode */
/* mode independent information */
int nowrap; /* flag for no wrapper */
uInt wbits; /* log2(window size) (8..15, defaults to 15) */
inflate_blocks_statef
*blocks; /* current inflate_blocks state */
};
int ZEXPORT inflateReset(z)
z_streamp z;
{
if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR;
z->total_in = z->total_out = 0;
z->msg = Z_NULL;
z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
inflate_blocks_reset(z->state->blocks, z, Z_NULL);
Tracev((stderr, "inflate: reset\n"));
return Z_OK;
}
int ZEXPORT inflateEnd(z)
z_streamp z;
{
if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
return Z_STREAM_ERROR;
if (z->state->blocks != Z_NULL)
inflate_blocks_free(z->state->blocks, z);
ZFREE(z, z->state);
z->state = Z_NULL;
Tracev((stderr, "inflate: end\n"));
return Z_OK;
}
int ZEXPORT inflateInit2_(z, w, version, stream_size)
z_streamp z;
int w;
const char *version;
int stream_size;
{
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != sizeof(z_stream))
return Z_VERSION_ERROR;
/* initialize state */
if (z == Z_NULL)
return Z_STREAM_ERROR;
z->msg = Z_NULL;
if (z->zalloc == Z_NULL)
{
z->zalloc = zcalloc;
z->opaque = (voidpf)0;
}
if (z->zfree == Z_NULL) z->zfree = zcfree;
if ((z->state = (struct internal_state FAR *)
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
return Z_MEM_ERROR;
z->state->blocks = Z_NULL;
/* handle undocumented nowrap option (no zlib header or check) */
z->state->nowrap = 0;
if (w < 0)
{
w = - w;
z->state->nowrap = 1;
}
/* set window size */
if (w < 8 || w > 15)
{
inflateEnd(z);
return Z_STREAM_ERROR;
}
z->state->wbits = (uInt)w;
/* create inflate_blocks state */
if ((z->state->blocks =
inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
== Z_NULL)
{
inflateEnd(z);
return Z_MEM_ERROR;
}
Tracev((stderr, "inflate: allocated\n"));
/* reset state */
inflateReset(z);
return Z_OK;
}
int ZEXPORT inflateInit_(z, version, stream_size)
z_streamp z;
const char *version;
int stream_size;
{
return inflateInit2_(z, DEF_WBITS, version, stream_size);
}
#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
int ZEXPORT inflate(z, f)
z_streamp z;
int f;
{
int r;
uInt b;
if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
return Z_STREAM_ERROR;
f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
r = Z_BUF_ERROR;
while (1) switch (z->state->mode)
{
case METHOD:
NEEDBYTE
if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
{
z->state->mode = BAD;
z->msg = (char*)"unknown compression method";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
{
z->state->mode = BAD;
z->msg = (char*)"invalid window size";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
z->state->mode = FLAG;
case FLAG:
NEEDBYTE
b = NEXTBYTE;
if (((z->state->sub.method << 8) + b) % 31)
{
z->state->mode = BAD;
z->msg = (char*)"incorrect header check";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
Tracev((stderr, "inflate: zlib header ok\n"));
if (!(b & PRESET_DICT))
{
z->state->mode = BLOCKS;
break;
}
z->state->mode = DICT4;
case DICT4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = DICT3;
case DICT3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = DICT2;
case DICT2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = DICT1;
case DICT1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
z->adler = z->state->sub.check.need;
z->state->mode = DICT0;
return Z_NEED_DICT;
case DICT0:
z->state->mode = BAD;
z->msg = (char*)"need dictionary";
z->state->sub.marker = 0; /* can try inflateSync */
return Z_STREAM_ERROR;
case BLOCKS:
r = inflate_blocks(z->state->blocks, z, r);
if (r == Z_DATA_ERROR)
{
z->state->mode = BAD;
z->state->sub.marker = 0; /* can try inflateSync */
break;
}
if (r == Z_OK)
r = f;
if (r != Z_STREAM_END)
return r;
r = f;
inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
if (z->state->nowrap)
{
z->state->mode = DONE;
break;
}
z->state->mode = CHECK4;
case CHECK4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = CHECK3;
case CHECK3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = CHECK2;
case CHECK2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = CHECK1;
case CHECK1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
if (z->state->sub.check.was != z->state->sub.check.need)
{
z->state->mode = BAD;
z->msg = (char*)"incorrect data check";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
Tracev((stderr, "inflate: zlib check ok\n"));
z->state->mode = DONE;
case DONE:
return Z_STREAM_END;
case BAD:
return Z_DATA_ERROR;
default:
return Z_STREAM_ERROR;
}
#ifdef NEED_DUMMY_RETURN
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
#endif
}
int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
z_streamp z;
const Bytef *dictionary;
uInt dictLength;
{
uInt length = dictLength;
if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
return Z_STREAM_ERROR;
if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
z->adler = 1L;
if (length >= ((uInt)1<<z->state->wbits))
{
length = (1<<z->state->wbits)-1;
dictionary += dictLength - length;
}
inflate_set_dictionary(z->state->blocks, dictionary, length);
z->state->mode = BLOCKS;
return Z_OK;
}
int ZEXPORT inflateSync(z)
z_streamp z;
{
uInt n; /* number of bytes to look at */
Bytef *p; /* pointer to bytes */
uInt m; /* number of marker bytes found in a row */
uLong r, w; /* temporaries to save total_in and total_out */
/* set up */
if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR;
if (z->state->mode != BAD)
{
z->state->mode = BAD;
z->state->sub.marker = 0;
}
if ((n = z->avail_in) == 0)
return Z_BUF_ERROR;
p = z->next_in;
m = z->state->sub.marker;
/* search */
while (n && m < 4)
{
static const Byte mark[4] = {0, 0, 0xff, 0xff};
if (*p == mark[m])
m++;
else if (*p)
m = 0;
else
m = 4 - m;
p++, n--;
}
/* restore */
z->total_in += p - z->next_in;
z->next_in = p;
z->avail_in = n;
z->state->sub.marker = m;
/* return no joy or set up to restart on a new block */
if (m != 4)
return Z_DATA_ERROR;
r = z->total_in; w = z->total_out;
inflateReset(z);
z->total_in = r; z->total_out = w;
z->state->mode = BLOCKS;
return Z_OK;
}
/* Returns true if inflate is currently at the end of a block generated
* by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
* implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
* but removes the length bytes of the resulting empty stored block. When
* decompressing, PPP checks that at the end of input packet, inflate is
* waiting for these length bytes.
*/
int ZEXPORT inflateSyncPoint(z)
z_streamp z;
{
if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
return Z_STREAM_ERROR;
return inflate_blocks_sync_point(z->state->blocks);
}

View File

@@ -0,0 +1,455 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#if !defined(BUILDFIXED) && !defined(STDC)
# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
#endif
const char inflate_copyright[] =
" inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
struct internal_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
local int huft_build OF((
uIntf *, /* code lengths in bits */
uInt, /* number of codes */
uInt, /* number of "simple" codes */
const uIntf *, /* list of base values for non-simple codes */
const uIntf *, /* list of extra bits for non-simple codes */
inflate_huft * FAR*,/* result: starting table */
uIntf *, /* maximum lookup bits (returns actual) */
inflate_huft *, /* space for trees */
uInt *, /* hufts used in space */
uIntf * )); /* space for values */
/* Tables for deflate from PKZIP's appnote.txt. */
local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
/* see note #13 above about 258 */
local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
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, 112, 112}; /* 112==invalid */
local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
local const uInt cpdext[30] = { /* Extra bits for distance codes */
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};
/*
Huffman code decoding is performed using a multi-level table lookup.
The fastest way to decode is to simply build a lookup table whose
size is determined by the longest code. However, the time it takes
to build this table can also be a factor if the data being decoded
is not very long. The most common codes are necessarily the
shortest codes, so those codes dominate the decoding time, and hence
the speed. The idea is you can have a shorter table that decodes the
shorter, more probable codes, and then point to subsidiary tables for
the longer codes. The time it costs to decode the longer codes is
then traded against the time it takes to make longer tables.
This results of this trade are in the variables lbits and dbits
below. lbits is the number of bits the first level table for literal/
length codes can decode in one step, and dbits is the same thing for
the distance codes. Subsequent tables are also less than or equal to
those sizes. These values may be adjusted either when all of the
codes are shorter than that, in which case the longest code length in
bits is used, or when the shortest code is *longer* than the requested
table size, in which case the length of the shortest code in bits is
used.
There are two different values for the two tables, since they code a
different number of possibilities each. The literal/length table
codes 286 possible values, or in a flat code, a little over eight
bits. The distance table codes 30 possible values, or a little less
than five bits, flat. The optimum values for speed end up being
about one bit more than those, so lbits is 8+1 and dbits is 5+1.
The optimum values may differ though from machine to machine, and
possibly even between compilers. Your mileage may vary.
*/
/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
#define BMAX 15 /* maximum bit length of any code */
local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
uInt n; /* number of codes (assumed <= 288) */
uInt s; /* number of simple-valued codes (0..s-1) */
const uIntf *d; /* list of base values for non-simple codes */
const uIntf *e; /* list of extra bits for non-simple codes */
inflate_huft * FAR *t; /* result: starting table */
uIntf *m; /* maximum lookup bits, returns actual */
inflate_huft *hp; /* space for trees */
uInt *hn; /* hufts used in space */
uIntf *v; /* working area: values in order of bit length */
/* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
if the given code set is incomplete (the tables are still built in this
case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
lengths), or Z_MEM_ERROR if not enough memory. */
{
uInt a; /* counter for codes of length k */
uInt c[BMAX+1]; /* bit length count table */
uInt f; /* i repeats in table every f entries */
int g; /* maximum code length */
int h; /* table level */
register uInt i; /* counter, current code */
register uInt j; /* counter */
register int k; /* number of bits in current code */
int l; /* bits per table (returned in m) */
uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
register uIntf *p; /* pointer into c[], b[], or v[] */
inflate_huft *q; /* points to current table */
struct inflate_huft_s r; /* table entry for structure assignment */
inflate_huft *u[BMAX]; /* table stack */
register int w; /* bits before this table == (l * h) */
uInt x[BMAX+1]; /* bit offsets, then code stack */
uIntf *xp; /* pointer into x */
int y; /* number of dummy codes added */
uInt z; /* number of entries in current table */
/* Generate counts for each bit length */
p = c;
#define C0 *p++ = 0;
#define C2 C0 C0 C0 C0
#define C4 C2 C2 C2 C2
C4 /* clear c[]--assume BMAX+1 is 16 */
p = b; i = n;
do {
c[*p++]++; /* assume all entries <= BMAX */
} while (--i);
if (c[0] == n) /* null input--all zero length codes */
{
*t = (inflate_huft *)Z_NULL;
*m = 0;
return Z_OK;
}
/* Find minimum and maximum length, bound *m by those */
l = *m;
for (j = 1; j <= BMAX; j++)
if (c[j])
break;
k = j; /* minimum code length */
if ((uInt)l < j)
l = j;
for (i = BMAX; i; i--)
if (c[i])
break;
g = i; /* maximum code length */
if ((uInt)l > i)
l = i;
*m = l;
/* Adjust last length count to fill out codes, if needed */
for (y = 1 << j; j < i; j++, y <<= 1)
if ((y -= c[j]) < 0)
return Z_DATA_ERROR;
if ((y -= c[i]) < 0)
return Z_DATA_ERROR;
c[i] += y;
/* Generate starting offsets into the value table for each length */
x[1] = j = 0;
p = c + 1; xp = x + 2;
while (--i) { /* note that i == g from above */
*xp++ = (j += *p++);
}
/* Make a table of values in order of bit lengths */
p = b; i = 0;
do {
if ((j = *p++) != 0)
v[x[j]++] = i;
} while (++i < n);
n = x[g]; /* set n to length of v */
/* Generate the Huffman codes and for each, make the table entries */
x[0] = i = 0; /* first Huffman code is zero */
p = v; /* grab values in bit order */
h = -1; /* no tables yet--level -1 */
w = -l; /* bits decoded == (l * h) */
u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
q = (inflate_huft *)Z_NULL; /* ditto */
z = 0; /* ditto */
/* go through the bit lengths (k already is bits in shortest code) */
for (; k <= g; k++)
{
a = c[k];
while (a--)
{
/* here i is the Huffman code of length k bits for value *p */
/* make tables up to required level */
while (k > w + l)
{
h++;
w += l; /* previous table always l bits */
/* compute minimum size table less than or equal to l bits */
z = g - w;
z = z > (uInt)l ? l : z; /* table size upper limit */
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */
xp = c + k;
if (j < z)
while (++j < z) /* try smaller tables up to z bits */
{
if ((f <<= 1) <= *++xp)
break; /* enough codes to use up j bits */
f -= *xp; /* else deduct codes from patterns */
}
}
z = 1 << j; /* table entries for j-bit table */
/* allocate new table */
if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
return Z_MEM_ERROR; /* not enough memory */
u[h] = q = hp + *hn;
*hn += z;
/* connect to last table, if there is one */
if (h)
{
x[h] = i; /* save pattern for backing up */
r.bits = (Byte)l; /* bits to dump before this table */
r.exop = (Byte)j; /* bits in this table */
j = i >> (w - l);
r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
u[h-1][j] = r; /* connect to last table */
}
else
*t = q; /* first table is returned result */
}
/* set up table entry in r */
r.bits = (Byte)(k - w);
if (p >= v + n)
r.exop = 128 + 64; /* out of values--invalid code */
else if (*p < s)
{
r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
r.base = *p++; /* simple code is just the value */
}
else
{
r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
r.base = d[*p++ - s];
}
/* fill code-like entries with r */
f = 1 << (k - w);
for (j = i >> w; j < z; j += f)
q[j] = r;
/* backwards increment the k-bit code i */
for (j = 1 << (k - 1); i & j; j >>= 1)
i ^= j;
i ^= j;
/* backup over finished tables */
mask = (1 << w) - 1; /* needed on HP, cc -O bug */
while ((i & mask) != x[h])
{
h--; /* don't need to update q */
w -= l;
mask = (1 << w) - 1;
}
}
}
/* Return Z_BUF_ERROR if we were given an incomplete table */
return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
}
int inflate_trees_bits(c, bb, tb, hp, z)
uIntf *c; /* 19 code lengths */
uIntf *bb; /* bits tree desired/actual depth */
inflate_huft * FAR *tb; /* bits tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
tb, bb, hp, &hn, v);
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed dynamic bit lengths tree";
else if (r == Z_BUF_ERROR || *bb == 0)
{
z->msg = (char*)"incomplete dynamic bit lengths tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
uInt nl; /* number of literal/length codes */
uInt nd; /* number of distance codes */
uIntf *c; /* that many (total) code lengths */
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
inflate_huft *hp; /* space for trees */
z_streamp z; /* for messages */
{
int r;
uInt hn = 0; /* hufts used in space */
uIntf *v; /* work area for huft_build */
/* allocate work area */
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
/* build literal/length tree */
r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
if (r != Z_OK || *bl == 0)
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed literal/length tree";
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
}
/* build distance tree */
r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
if (r != Z_OK || (*bd == 0 && nl > 257))
{
if (r == Z_DATA_ERROR)
z->msg = (char*)"oversubscribed distance tree";
else if (r == Z_BUF_ERROR) {
#ifdef PKZIP_BUG_WORKAROUND
r = Z_OK;
}
#else
z->msg = (char*)"incomplete distance tree";
r = Z_DATA_ERROR;
}
else if (r != Z_MEM_ERROR)
{
z->msg = (char*)"empty distance tree with lengths";
r = Z_DATA_ERROR;
}
ZFREE(z, v);
return r;
#endif
}
/* done */
ZFREE(z, v);
return Z_OK;
}
/* build fixed tables only once--keep them here */
#ifdef BUILDFIXED
local int fixed_built = 0;
#define FIXEDH 544 /* number of hufts used by fixed tables */
local inflate_huft fixed_mem[FIXEDH];
local uInt fixed_bl;
local uInt fixed_bd;
local inflate_huft *fixed_tl;
local inflate_huft *fixed_td;
#else
#include "inffixed.h"
#endif
int inflate_trees_fixed(bl, bd, tl, td, z)
uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */
z_streamp z; /* for memory allocation */
{
#ifdef BUILDFIXED
/* build fixed tables if not already */
if (!fixed_built)
{
int k; /* temporary variable */
uInt f = 0; /* number of hufts used in fixed_mem */
uIntf *c; /* length list for huft_build */
uIntf *v; /* work area for huft_build */
/* allocate memory */
if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
return Z_MEM_ERROR;
if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
{
ZFREE(z, c);
return Z_MEM_ERROR;
}
/* literal table */
for (k = 0; k < 144; k++)
c[k] = 8;
for (; k < 256; k++)
c[k] = 9;
for (; k < 280; k++)
c[k] = 7;
for (; k < 288; k++)
c[k] = 8;
fixed_bl = 9;
huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
fixed_mem, &f, v);
/* distance table */
for (k = 0; k < 30; k++)
c[k] = 5;
fixed_bd = 5;
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
fixed_mem, &f, v);
/* done */
ZFREE(z, v);
ZFREE(z, c);
fixed_built = 1;
}
#endif
*bl = fixed_bl;
*bd = fixed_bd;
*tl = fixed_tl;
*td = fixed_td;
return Z_OK;
}

View File

@@ -0,0 +1,58 @@
/* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* Huffman code lookup table entry--this entry is four bytes for machines
that have 16-bit pointers (e.g. PC's in the small or medium model). */
typedef struct inflate_huft_s FAR inflate_huft;
struct inflate_huft_s {
union {
struct {
Byte Exop; /* number of extra bits or operation */
Byte Bits; /* number of bits in this code or subcode */
} what;
uInt pad; /* pad structure to a power of 2 (4 bytes for */
} word; /* 16-bit, 8 bytes for 32-bit int's) */
uInt base; /* literal, length base, distance base,
or table offset */
};
/* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1004 huft structures (850 for length/literals
and 154 for distances, the latter actually the result of an
exhaustive search). The actual maximum is not known, but the
value below is more than safe. */
#define MANY 1440
extern int inflate_trees_bits OF((
uIntf *, /* 19 code lengths */
uIntf *, /* bits tree desired/actual depth */
inflate_huft * FAR *, /* bits tree result */
inflate_huft *, /* space for trees */
z_streamp)); /* for messages */
extern int inflate_trees_dynamic OF((
uInt, /* number of literal/length codes */
uInt, /* number of distance codes */
uIntf *, /* that many (total) code lengths */
uIntf *, /* literal desired/actual bit depth */
uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */
inflate_huft *, /* space for trees */
z_streamp)); /* for messages */
extern int inflate_trees_fixed OF((
uIntf *, /* literal desired/actual bit depth */
uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */
z_streamp)); /* for memory allocation */

View File

@@ -0,0 +1,87 @@
/* inflate_util.c -- data and routines common to blocks and codes
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "infblock.h"
#include "inftrees.h"
#include "infcodes.h"
#include "infutil.h"
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* And'ing with mask[n] masks the lower n bits */
uInt inflate_mask[17] = {
0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
};
/* copy as much as possible from the sliding window to the output area */
int inflate_flush(s, z, r)
inflate_blocks_statef *s;
z_streamp z;
int r;
{
uInt n;
Bytef *p;
Bytef *q;
/* local copies of source and destination pointers */
p = z->next_out;
q = s->read;
/* compute number of bytes to copy as far as end of window */
n = (uInt)((q <= s->write ? s->write : s->end) - q);
if (n > z->avail_out) n = z->avail_out;
if (n && r == Z_BUF_ERROR) r = Z_OK;
/* update counters */
z->avail_out -= n;
z->total_out += n;
/* update check information */
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy as far as end of window */
zmemcpy(p, q, n);
p += n;
q += n;
/* see if more to copy at beginning of window */
if (q == s->end)
{
/* wrap pointers */
q = s->window;
if (s->write == s->end)
s->write = s->window;
/* compute bytes to copy */
n = (uInt)(s->write - q);
if (n > z->avail_out) n = z->avail_out;
if (n && r == Z_BUF_ERROR) r = Z_OK;
/* update counters */
z->avail_out -= n;
z->total_out += n;
/* update check information */
if (s->checkfn != Z_NULL)
z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy */
zmemcpy(p, q, n);
p += n;
q += n;
}
/* update pointers */
z->next_out = p;
s->read = q;
/* done */
return r;
}

View File

@@ -0,0 +1,98 @@
/* infutil.h -- types and macros common to blocks and codes
* Copyright (C) 1995-1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
#ifndef _INFUTIL_H
#define _INFUTIL_H
typedef enum {
TYPE, /* get type bits (3, including end bit) */
LENS, /* get lengths for stored */
STORED, /* processing stored block */
TABLE, /* get table lengths */
BTREE, /* get bit lengths tree for a dynamic block */
DTREE, /* get length, distance trees for a dynamic block */
CODES, /* processing fixed or dynamic block */
DRY, /* output remaining window bytes */
DONE, /* finished last block, done */
BAD} /* got a data error--stuck here */
inflate_block_mode;
/* inflate blocks semi-private state */
struct inflate_blocks_state {
/* mode */
inflate_block_mode mode; /* current inflate_block mode */
/* mode dependent information */
union {
uInt left; /* if STORED, bytes left to copy */
struct {
uInt table; /* table lengths (14 bits) */
uInt index; /* index into blens (or border) */
uIntf *blens; /* bit lengths of codes */
uInt bb; /* bit length tree depth */
inflate_huft *tb; /* bit length decoding tree */
} trees; /* if DTREE, decoding info for trees */
struct {
inflate_codes_statef
*codes;
} decode; /* if CODES, current state */
} sub; /* submode */
uInt last; /* true if this block is the last block */
/* mode independent information */
uInt bitk; /* bits in bit buffer */
uLong bitb; /* bit buffer */
inflate_huft *hufts; /* single malloc for tree space */
Bytef *window; /* sliding window */
Bytef *end; /* one byte after sliding window */
Bytef *read; /* window read pointer */
Bytef *write; /* window write pointer */
check_func checkfn; /* check function */
uLong check; /* check on output */
};
/* defines for inflate input/output */
/* update pointers and return */
#define UPDBITS {s->bitb=b;s->bitk=k;}
#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
#define UPDOUT {s->write=q;}
#define UPDATE {UPDBITS UPDIN UPDOUT}
#define LEAVE {UPDATE return inflate_flush(s,z,r);}
/* get bytes and bits */
#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
#define NEXTBYTE (n--,*p++)
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define DUMPBITS(j) {b>>=(j);k-=(j);}
/* output bytes */
#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
/* load local pointers */
#define LOAD {LOADIN LOADOUT}
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
extern uInt inflate_mask[17];
/* copy as much as possible from the sliding window to the output area */
extern int inflate_flush OF((
inflate_blocks_statef *,
z_streamp ,
int));
struct internal_state {int dummy;}; /* for buggy compilers */
#endif

View File

@@ -0,0 +1,85 @@
/* maketree.c -- make inffixed.h table for decoding fixed codes
* Copyright (C) 1998 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* This program is included in the distribution for completeness.
You do not need to compile or run this program since inffixed.h
is already included in the distribution. To use this program
you need to compile zlib with BUILDFIXED defined and then compile
and link this program with the zlib library. Then the output of
this program can be piped to inffixed.h. */
#include <stdio.h>
#include <stdlib.h>
#include "zutil.h"
#include "inftrees.h"
/* simplify the use of the inflate_huft type with some defines */
#define exop word.what.Exop
#define bits word.what.Bits
/* generate initialization table for an inflate_huft structure array */
void maketree(uInt b, inflate_huft *t)
{
int i, e;
i = 0;
while (1)
{
e = t[i].exop;
if (e && (e & (16+64)) == 0) /* table pointer */
{
fprintf(stderr, "maketree: cannot initialize sub-tables!\n");
exit(1);
}
if (i % 4 == 0)
printf("\n ");
printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base);
if (++i == (1<<b))
break;
putchar(',');
}
puts("");
}
/* create the fixed tables in C initialization syntax */
void main(void)
{
int r;
uInt bl, bd;
inflate_huft *tl, *td;
z_stream z;
z.zalloc = zcalloc;
z.opaque = (voidpf)0;
z.zfree = zcfree;
r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z);
if (r)
{
fprintf(stderr, "inflate_trees_fixed error %d\n", r);
return;
}
puts("/* inffixed.h -- table for decoding fixed codes");
puts(" * Generated automatically by the maketree.c program");
puts(" */");
puts("");
puts("/* WARNING: this file should *not* be used by applications. It is");
puts(" part of the implementation of the compression library and is");
puts(" subject to change. Applications should only use zlib.h.");
puts(" */");
puts("");
printf("local uInt fixed_bl = %d;\n", bl);
printf("local uInt fixed_bd = %d;\n", bd);
printf("local inflate_huft fixed_tl[] = {");
maketree(bl, tl);
puts(" };");
printf("local inflate_huft fixed_td[] = {");
maketree(bd, td);
puts(" };");
}

View File

@@ -0,0 +1,17 @@
// stdafx.cpp : source file that includes just the standard includes
// Zip.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"

View File

@@ -0,0 +1,109 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_)
#define AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_
#ifdef __BORLANDC__
#define ZIPINLINE
#else
#define ZIPINLINE inline
#endif
#define ZIP_ARCHIVE_STL
#if _MSC_VER > 1000
#pragma once
//because of STL
#pragma warning (disable : 4710) // 'function' : function not inlined
#pragma warning (disable : 4514) // unreferenced inline/local function has been removed
#endif // _MSC_VER > 1000
// some Windows typical definitions
#if defined (_UNICODE) && !defined (UNICODE)
#define UNICODE
#endif
#if defined (UNICODE) && !defined (_UNICODE)
#define _UNICODE
#endif
#ifndef _WIN32
#ifndef NULL
#define NULL 0
#endif
#include <ctype.h>
typedef int HFILE;
typedef void* HANDLE;
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int UINT;
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
typedef const WCHAR *LPCWSTR;
typedef const char *LPCSTR;
typedef WCHAR *LPWSTR;
typedef char *LPSTR;
#ifdef _UNICODE
typedef wchar_t TCHAR;
typedef LPCWSTR LPCTSTR;
typedef LPWSTR LPTSTR;
#define _T(x) L ## x
#else /* _UNICODE */ // r_winnt
typedef char TCHAR;
typedef LPCSTR LPCTSTR;
typedef LPSTR LPTSTR;
#define _T(x) x
#endif /* _UNICODE */ // r_winnt
#else
#include <tchar.h>
#include <windows.h>
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>
# define ZEXPORT __declspec(dllexport) WINAPI
# define ZEXPORTRVA __declspec(dllexport) WINAPIV
#endif // #ifndef _WIN32
#ifndef ASSERT
#include <assert.h>
#define ASSERT(f) assert((f))
#endif
#ifndef VERIFY
#ifdef _DEBUG
#define VERIFY(x) ASSERT((x))
#else
#define VERIFY(x) x
#endif
#endif
#ifndef TRACE
#define TRACE
#endif
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
/* header created automatically with -DGEN_TREES_H */
local const ct_data static_ltree[L_CODES+2] = {
{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
};
local const ct_data static_dtree[D_CODES] = {
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
};
const uch _dist_code[DIST_CODE_LEN] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
};
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
};
local const int base_length[LENGTH_CODES] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
64, 80, 96, 112, 128, 160, 192, 224, 0
};
local const int base_dist[D_CODES] = {
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
};

View File

@@ -0,0 +1,58 @@
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zlib.h"
/* ===========================================================================
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
err = inflateInit(&stream);
if (err != Z_OK) return err;
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = inflateEnd(&stream);
return err;
}

View File

@@ -49,7 +49,7 @@
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
#define WIN32
# define WIN32
#endif
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
# ifndef __32BIT__
@@ -175,14 +175,14 @@
# endif
# endif
# if defined (__BORLANDC__)
# if (__BORLANDC__<= 1280) && defined (WIN32)
#include <windows.h>
#define ZEXPORT __declspec(dllexport) WINAPI
#define ZEXPORTRVA __declspec(dllexport) WINAPIV
# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
# include <windows.h>
# define ZEXPORT __declspec(dllexport) WINAPI
# define ZEXPORTRVA __declspec(dllexport) WINAPIV
# else
# if defined (_Windows) && defined (__DLL__)
#define ZEXPORT _export
#define ZEXPORTVA _export
# define ZEXPORT _export
# define ZEXPORTVA _export
# endif
# endif
# endif
@@ -196,12 +196,6 @@
# endif
#endif
# if defined (__BORLANDC__)
# if defined (WIN32) && !defined(ZLIB_DLL)
#include <windows.h>
# endif
# endif
#ifndef ZEXPORT
# define ZEXPORT
#endif

View File

@@ -0,0 +1,47 @@
// ZipAbstractFile.h: interface for the ZipAbstractFile class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPABSTRACTFILE_H__46F247DE_21A6_4D12_AF64_B5A6B3CF4D57__INCLUDED_)
#define AFX_ZIPABSTRACTFILE_H__46F247DE_21A6_4D12_AF64_B5A6B3CF4D57__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipstring.h"
class CZipAbstractFile
{
public:
enum { begin = SEEK_SET,
end = SEEK_END,
current = SEEK_CUR
};
CZipAbstractFile(){}
virtual bool Open(LPCTSTR lpszFileName, UINT openFlags, bool bThrow) = 0;
virtual void Close() = 0;
virtual void Flush() = 0;
virtual long GetPosition() = 0;
virtual void SeekToBegin(){Seek(0, begin);}
virtual void SeekToEnd(){Seek(0, end);}
virtual CZipString GetFilePath() = 0;
virtual void SetLength(long nNewLen) = 0;
virtual UINT Read(void *lpBuf, UINT nCount) = 0;
virtual void Write(const void* lpBuf, UINT nCount) = 0;
virtual long Seek(long lOff, int nFrom) = 0;
virtual bool IsClosed() = 0;
virtual DWORD GetLength() = 0;
virtual ~CZipAbstractFile(){};
};
#endif // !defined(AFX_ZIPABSTRACTFILE_H__46F247DE_21A6_4D12_AF64_B5A6B3CF4D57__INCLUDED_)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
#
# Borland C++ IDE generated makefile
# Generated 11/04/01 at 19:22:16
#
.AUTODEPEND
#
# Borland C++ tools
#
!ifndef BCB
BCB = $(MAKEDIR)\..
!endif
IMPLIB = Implib
BCC32 = Bcc32 +BccW32.cfg
TLINK32 = TLink32
TLIB = TLib
BRC32 = Brc32
TASM32 = Tasm32
#
# IDE macros
#
#
# Options
#
IDE_LinkFLAGS32 = -L$(BCB)\LIB
LinkerLocalOptsAtC32_ziparddll = -L$(BCB)\LIB -Tpe -ap -c
ResLocalOptsAtC32_ziparddll =
BLocalOptsAtC32_ziparddll =
CompInheritOptsAt_ziparddll = -I.;$(BCB)\INCLUDE -DNDEBUG;_MBCS;WIN32;_WINDOWS;ZLIB_DLL;_NO_VCL;_ASSERTE;NO_STRICT
LinkerInheritOptsAt_ziparddll = -x
LinkerOptsAt_ziparddll = $(LinkerLocalOptsAtC32_ziparddll)
ResOptsAt_ziparddll = $(ResLocalOptsAtC32_ziparddll)
BOptsAt_ziparddll = $(BLocalOptsAtC32_ziparddll)
#
# Dependency List
#
Dep_zipar = \
ziparchive.lib
ziparchive : BccW32.cfg $(Dep_zipar)
echo MakeNode
Dep_ziparddll = \
zutil.obj\
uncompr.obj\
adler32.obj\
infutil.obj\
inftrees.obj\
inflate.obj\
inffast.obj\
infcodes.obj\
infblock.obj\
gzio.obj\
trees.obj\
deflate.obj\
crc32.obj\
compress.obj\
zipplatform.obj\
zipstorage.obj\
zipplatformcomm.obj\
zippathcomponent.obj\
zipmemfile.obj\
zipinternalinfo.obj\
zipfileheader.obj\
zipfile.obj\
zipexception.obj\
zipcompatibility.obj\
zipcollections.obj\
zipcentraldir.obj\
zipautobuffer.obj\
ziparchive.obj\
stdafx.obj
ziparchive.lib : $(Dep_ziparddll)
$(TLIB) $< $(IDE_BFLAGS) /P32 $(BOptsAt_ziparddll) @&&|
-+zutil.obj &
-+uncompr.obj &
-+adler32.obj &
-+trees.obj &
-+infutil.obj &
-+inftrees.obj &
-+inflate.obj &
-+inffast.obj &
-+infcodes.obj &
-+infblock.obj &
-+gzio.obj &
-+deflate.obj &
-+crc32.obj &
-+compress.obj &
-+makebcdll.obj &
-+zipstorage.obj &
-+zipplatformcomm.obj &
-+zipplatform.obj &
-+zippathcomponent.obj &
-+zipmemfile.obj &
-+zipinternalinfo.obj &
-+zipfileheader.obj &
-+zipfile.obj &
-+zipexception.obj &
-+zipcompatibility.obj &
-+zipcollections.obj &
-+zipcentraldir.obj &
-+zipautobuffer.obj &
-+ziparchive.obj &
-+stdafx.obj
|
zutil.obj : zutil.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zutil.c
|
uncompr.obj : uncompr.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ uncompr.c
|
adler32.obj : adler32.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ adler32.c
|
trees.obj : trees.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ trees.c
|
infutil.obj : infutil.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ infutil.c
|
inftrees.obj : inftrees.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ inftrees.c
|
inflate.obj : inflate.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ inflate.c
|
inffast.obj : inffast.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ inffast.c
|
infcodes.obj : infcodes.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ infcodes.c
|
infblock.obj : infblock.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ infblock.c
|
gzio.obj : gzio.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ gzio.c
|
deflate.obj : deflate.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ deflate.c
|
crc32.obj : crc32.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ crc32.c
|
compress.obj : compress.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ compress.c
|
makebcdll.obj : makebcdll.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ makebcdll.cpp
|
zipstorage.obj : zipstorage.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipstorage.cpp
|
zipplatformcomm.obj : zipplatformcomm.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipplatformcomm.cpp
|
zipplatform.obj : zipplatform.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipplatform.cpp
|
zippathcomponent.obj : zippathcomponent.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zippathcomponent.cpp
|
zipmemfile.obj : zipmemfile.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipmemfile.cpp
|
zipinternalinfo.obj : zipinternalinfo.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipinternalinfo.cpp
|
zipfileheader.obj : zipfileheader.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipfileheader.cpp
|
zipfile.obj : zipfile.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipfile.cpp
|
zipexception.obj : zipexception.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipexception.cpp
|
zipcompatibility.obj : zipcompatibility.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipcompatibility.cpp
|
zipcollections.obj : zipcollections.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipcollections.cpp
|
zipcentraldir.obj : zipcentraldir.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipcentraldir.cpp
|
zipautobuffer.obj : zipautobuffer.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipautobuffer.cpp
|
ziparchive.obj : ziparchive.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ ziparchive.cpp
|
stdafx.obj : stdafx.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ stdafx.cpp
|
# Compiler configuration file
BccW32.cfg :
Copy &&|
-vi
-Ve
-R-
-H-
-5
-6
-OS
-w-
-O2 -X- -a8 -b -k-
| $@

View File

@@ -0,0 +1,271 @@
#
# Borland C++ IDE generated makefile
# Generated 11/04/01 at 19:22:16
#
.AUTODEPEND
#
# Borland C++ tools
#
!ifndef BCB
BCB = $(MAKEDIR)\..
!endif
IMPLIB = Implib
BCC32 = Bcc32 +BccW32.cfg
TLINK32 = TLink32
TLIB = TLib
BRC32 = Brc32
TASM32 = Tasm32
#
# IDE macros
#
#
# Options
#
IDE_LinkFLAGS32 = -L$(BCB)\LIB
LinkerLocalOptsAtC32_ziparddll = -L$(BCB)\LIB -Tpe -ap -c
ResLocalOptsAtC32_ziparddll =
BLocalOptsAtC32_ziparddll =
CompInheritOptsAt_ziparddll = -I$(BCB)\INCLUDE -DWIN32;ZLIB_DLL -u $(CFLAGS)
LinkerInheritOptsAt_ziparddll = -x
LinkerOptsAt_ziparddll = $(LinkerLocalOptsAtC32_ziparddll)
ResOptsAt_ziparddll = $(ResLocalOptsAtC32_ziparddll)
BOptsAt_ziparddll = $(BLocalOptsAtC32_ziparddll)
#
# Dependency List
#
Dep_zipar = \
ziparchivemt.lib
ziparchive : BccW32.cfg $(Dep_zipar)
echo MakeNode
Dep_ziparddll = \
ziparchive.obj\
zutil.obj\
uncompr.obj\
adler32.obj\
infutil.obj\
inftrees.obj\
inflate.obj\
inffast.obj\
infcodes.obj\
infblock.obj\
gzio.obj\
trees.obj\
deflate.obj\
crc32.obj\
compress.obj\
zipplatform.obj\
zipstorage.obj\
zipplatformcomm.obj\
zippathcomponent.obj\
zipmemfile.obj\
zipinternalinfo.obj\
zipfileheader.obj\
zipfile.obj\
zipexception.obj\
zipcompatibility.obj\
zipcollections.obj\
zipcentraldir.obj\
zipautobuffer.obj\
stdafx.obj
ziparchivemt.lib : $(Dep_ziparddll)
$(TLIB) $< $(IDE_BFLAGS) /P32 $(BOptsAt_ziparddll) @&&|
-+zutil.obj &
-+uncompr.obj &
-+adler32.obj &
-+trees.obj &
-+infutil.obj &
-+inftrees.obj &
-+inflate.obj &
-+inffast.obj &
-+infcodes.obj &
-+infblock.obj &
-+gzio.obj &
-+deflate.obj &
-+crc32.obj &
-+compress.obj &
-+makebcdll.obj &
-+zipstorage.obj &
-+zipplatformcomm.obj &
-+zipplatform.obj &
-+zippathcomponent.obj &
-+zipmemfile.obj &
-+zipinternalinfo.obj &
-+zipfileheader.obj &
-+zipfile.obj &
-+zipexception.obj &
-+zipcompatibility.obj &
-+zipcollections.obj &
-+zipcentraldir.obj &
-+zipautobuffer.obj &
-+ziparchive.obj &
-+stdafx.obj
|
zutil.obj : zutil.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ zutil.c
|
uncompr.obj : uncompr.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ uncompr.c
|
adler32.obj : adler32.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ adler32.c
|
trees.obj : trees.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ trees.c
|
infutil.obj : infutil.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ infutil.c
|
inftrees.obj : inftrees.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ inftrees.c
|
inflate.obj : inflate.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ inflate.c
|
inffast.obj : inffast.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ inffast.c
|
infcodes.obj : infcodes.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ infcodes.c
|
infblock.obj : infblock.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ infblock.c
|
gzio.obj : gzio.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ gzio.c
|
deflate.obj : deflate.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ deflate.c
|
crc32.obj : crc32.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ crc32.c
|
compress.obj : compress.c
$(BCC32) -P- -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -DZLIB_DLL -o$@ compress.c
|
zipstorage.obj : zipstorage.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipstorage.cpp
|
zipplatformcomm.obj : zipplatformcomm.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipplatformcomm.cpp
|
zipplatform.obj : zipplatform.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipplatform.cpp
|
zippathcomponent.obj : zippathcomponent.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zippathcomponent.cpp
|
zipmemfile.obj : zipmemfile.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipmemfile.cpp
|
zipinternalinfo.obj : zipinternalinfo.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipinternalinfo.cpp
|
zipfileheader.obj : zipfileheader.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipfileheader.cpp
|
zipfile.obj : zipfile.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipfile.cpp
|
zipexception.obj : zipexception.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipexception.cpp
|
zipcompatibility.obj : zipcompatibility.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipcompatibility.cpp
|
zipcollections.obj : zipcollections.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipcollections.cpp
|
zipcentraldir.obj : zipcentraldir.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipcentraldir.cpp
|
zipautobuffer.obj : zipautobuffer.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ zipautobuffer.cpp
|
ziparchive.obj : ziparchive.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ ziparchive.cpp
|
stdafx.obj : stdafx.cpp
$(BCC32) -c @&&|
$(CompOptsAt_ziparddll) $(CompInheritOptsAt_ziparddll) -o$@ stdafx.cpp
|
# Compiler configuration file
BccW32.cfg :
Copy &&|
-vi
-Ve
-R-
-H-
-5
-OS
-w-
-O2 -X- -a8 -b -k-
| $@

View File

@@ -0,0 +1,104 @@
// ZipAutoBuffer.cpp: implementation of the CZipAutoBuffer class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipautobuffer.h"
#include <memory.h>
// #ifdef _DEBUG
// #undef THIS_FILE
// static char THIS_FILE[]=__FILE__;
// #define new DEBUG_NEW
// #endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CZipAutoBuffer::CZipAutoBuffer()
{
m_iSize = 0;
m_pBuffer = NULL;
}
CZipAutoBuffer::CZipAutoBuffer(DWORD iSize, bool bZeroMemory)
{
m_iSize = 0;
m_pBuffer = NULL;
Allocate(iSize, bZeroMemory);
}
CZipAutoBuffer::~CZipAutoBuffer()
{
Release();
}
void CZipAutoBuffer::Release()
{
if (m_pBuffer)
{
delete [] m_pBuffer;
m_iSize = 0;
m_pBuffer = NULL;
}
}
char* CZipAutoBuffer::Allocate(DWORD iSize, bool bZeroMemory)
{
if (iSize != m_iSize)
Release();
else
{
if (bZeroMemory)
memset(m_pBuffer, 0, iSize); // zerowanie bufora
return m_pBuffer;
}
if (iSize > 0)
{
m_pBuffer = new char [iSize];
if (bZeroMemory)
memset(m_pBuffer, 0, iSize); // zerowanie bufora
m_iSize = iSize;
}
else
m_pBuffer = NULL;
return m_pBuffer;
}
CZipAutoBuffer::CZipAutoBuffer(const CZipAutoBuffer& buffer)
{
m_pBuffer = NULL;
m_iSize = 0;
if (buffer.m_pBuffer)
{
Allocate(buffer.m_iSize);
memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize);
}
}
CZipAutoBuffer& CZipAutoBuffer::operator=(const CZipAutoBuffer& buffer)
{
if (this == &buffer)
return *this;
Release();
if (buffer.m_pBuffer)
{
Allocate(buffer.m_iSize);
memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize);
}
return *this;
}

View File

@@ -0,0 +1,63 @@
/**
* \file ZipAutoBuffer.h
* Interface for the CZipAutoBuffer class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
#define AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/**
A smart buffer freeing its contents on destruction.
*/
ZEXPORT class CZipAutoBuffer
{
public:
operator char*()
{
return m_pBuffer;
}
// may produce ambiguity on some compilers
// operator const char*() const
// {
// return m_pBuffer;
// }
const char* GetBuffer() const {return m_pBuffer;}
char* Allocate(DWORD iSize, bool bZeroMemory = false);
void Release();
DWORD GetSize() const
{
return m_iSize;
}
bool IsAllocated() const
{
return (m_pBuffer != NULL);
}
CZipAutoBuffer(DWORD iSize, bool bZeroMemory = false);
CZipAutoBuffer();
CZipAutoBuffer(const CZipAutoBuffer& buffer);
virtual ~CZipAutoBuffer();
CZipAutoBuffer& operator=(const CZipAutoBuffer& buffer);
protected:
char* m_pBuffer;
DWORD m_iSize;
};
#endif // !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)

View File

@@ -0,0 +1,6 @@
#ifndef __ZIPBASEEXCEPTION_H__
#define __ZIPBASEEXCEPTION_H__
typedef std::exception CZipBaseException;
#endif //__ZIPBASEEXCEPTION_H__

View File

@@ -0,0 +1,676 @@
// ZipCentralDir.cpp: implementation of the CZipCentralDir class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipcentraldir.h"
#include "ziparchive.h"
#include "zipfilemapping.h"
#define CENTRALDIRSIZE 22
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
char CZipCentralDir::m_gszSignature[] = {0x50, 0x4b, 0x05, 0x06};
CZipCentralDir::CZipCentralDir()
{
m_bConvertAfterOpen = true;
m_bFindFastEnabled = false;
m_pStorage = NULL;
m_pOpenedFile = NULL;
m_iBufferSize = 32768;
}
void CZipCentralDir::Init()
{
m_bOnDisk = false;
m_uBytesBeforeZip = m_uCentrDirPos = 0;
m_pOpenedFile = NULL;
m_pszComment.Release();
}
CZipCentralDir::~CZipCentralDir()
{
Clear();
}
void CZipCentralDir::Read()
{
ASSERT(m_pStorage);
WORD uCommentSize;
m_uCentrDirPos = Locate();
m_pStorage->m_pFile->Seek(m_uCentrDirPos, CZipAbstractFile::begin);
CZipAutoBuffer buf(CENTRALDIRSIZE);
int uRead = m_pStorage->m_pFile->Read(buf, CENTRALDIRSIZE);
if (uRead != CENTRALDIRSIZE)
ThrowError(CZipException::badZipFile);
memcpy(&m_szSignature, buf, 4);
memcpy(&m_uThisDisk, buf + 4, 2);
memcpy(&m_uDiskWithCD, buf + 6, 2);
memcpy(&m_uDiskEntriesNo, buf + 8, 2);
memcpy(&m_uEntriesNumber, buf + 10, 2);
memcpy(&m_uSize, buf + 12, 4);
memcpy(&m_uOffset, buf + 16, 4);
memcpy(&uCommentSize, buf + 20, 2);
buf.Release();
m_pStorage->UpdateSpanMode(m_uThisDisk);
// if m_uThisDisk is not zero, it is enough to say that it is a multi disk archive
ASSERT((!m_uThisDisk && (m_uEntriesNumber == m_uDiskEntriesNo) && !m_uDiskWithCD) || m_uThisDisk);
if (!m_pStorage->IsSpanMode() && ((DWORD)m_uCentrDirPos < m_uOffset + m_uSize))
ThrowError(CZipException::badZipFile);
if (uCommentSize)
{
m_pszComment.Allocate(uCommentSize);
uRead = m_pStorage->m_pFile->Read(m_pszComment, uCommentSize);
if (uRead != uCommentSize)
ThrowError(CZipException::badZipFile);
}
m_uBytesBeforeZip = m_pStorage->IsSpanMode() ? 0 : m_uCentrDirPos - m_uSize - m_uOffset;
if ((!m_uSize && m_uEntriesNumber) || (!m_uEntriesNumber && m_uSize))
ThrowError(CZipException::badZipFile);
m_bOnDisk = true;
m_pStorage->ChangeDisk(m_uDiskWithCD);
if (!m_uSize)
return;
ReadHeaders();
}
DWORD CZipCentralDir::Locate()
{
// maximum size of end of central dir record
long uMaxRecordSize = 0xffff + CENTRALDIRSIZE;
DWORD uFileSize = m_pStorage->m_pFile->GetLength();
if ((DWORD)uMaxRecordSize > uFileSize)
uMaxRecordSize = uFileSize;
CZipAutoBuffer buf(m_iBufferSize);
long uPosInFile = 0;
int uRead = 0;
// backward reading
while (uPosInFile < uMaxRecordSize)
{
uPosInFile = uRead + m_iBufferSize;
if (uPosInFile > uMaxRecordSize)
uPosInFile = uMaxRecordSize;
int iToRead = uPosInFile - uRead;
m_pStorage->m_pFile->Seek(-uPosInFile, CZipAbstractFile::end);
int iActuallyRead = m_pStorage->m_pFile->Read(buf, iToRead);
if (iActuallyRead != iToRead)
ThrowError(CZipException::badZipFile);
// search from the very last bytes to prevent an error if inside archive
// there are packed other arhives
for (int i = iToRead - 4; i >=0 ; i--)
if (!memcmp((char*)buf + i, m_gszSignature, 4))
return uFileSize - (uPosInFile - i);
uRead += iToRead - 3;
}
ThrowError(CZipException::cdirNotFound);
return 0;
}
void CZipCentralDir::ThrowError(int err)
{
CZipException::Throw(err, m_pStorage->m_pFile->GetFilePath());
}
void CZipCentralDir::ReadHeaders()
{
m_pStorage->m_pFile->Seek(m_uOffset + m_uBytesBeforeZip, CZipAbstractFile::begin);
RemoveHeaders(); //just in case
for (int i = 0; i < m_uEntriesNumber; i++)
{
CZipFileHeader* pHeader = new CZipFileHeader;
m_headers.AddTail(pHeader); // bezpoœrednio nastêpuje w razie wyj¹tku
if (!pHeader->Read(m_pStorage))
ThrowError(CZipException::badZipFile);
ConvertFileName(true, true, pHeader);
}
if (m_bFindFastEnabled)
BuildFindFastArray();
}
void CZipCentralDir::Clear(bool bEverything)
{
m_pOpenedFile = NULL;
m_pLocalExtraField.Release();
if (bEverything)
{
RemoveHeaders();
m_findarray.RemoveAll();
m_pszComment.Release();
}
}
bool CZipCentralDir::IsValidIndex(int uIndex)
{
bool ret = uIndex < m_headers.GetCount();
#ifdef _DEBUG
if (!ret)
TRACE(_T("Not a valid index.\n"));
#endif
return ret;
}
void CZipCentralDir::OpenFile(WORD uIndex)
{
WORD uLocalExtraFieldSize;
m_pOpenedFile = (*this)[uIndex];
m_pStorage->ChangeDisk(m_pOpenedFile->m_uDiskStart);
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + m_uBytesBeforeZip, CZipAbstractFile::begin);
if (!m_pOpenedFile->ReadLocal(m_pStorage, uLocalExtraFieldSize))
ThrowError(CZipException::badZipFile);
m_pLocalExtraField.Release(); // just in case
if (uLocalExtraFieldSize)
{
int iCurrDsk = m_pStorage->GetCurrentDisk();
m_pLocalExtraField.Allocate(uLocalExtraFieldSize);
m_pStorage->Read(m_pLocalExtraField, uLocalExtraFieldSize, true);
if (m_pStorage->GetCurrentDisk() != iCurrDsk)
ThrowError(CZipException::badZipFile);
}
}
void CZipCentralDir::CloseFile()
{
if (!m_pOpenedFile)
return;
m_pLocalExtraField.Release();
if (m_pOpenedFile->IsDataDescr())
{
CZipAutoBuffer buf(12);
m_pStorage->Read(buf, 4, false);
// in span mode, files that are divided between disks have bit 3 of flag set
// which tell about the presence of the data descriptor after the compressed data
// This signature may be in the disk spanning archive that is one volume only
// (it is detected as a non disk spanning archive)
if (memcmp(buf, CZipStorage::m_gszExtHeaderSignat, 4) != 0) // there is no signature
m_pStorage->m_pFile->Seek(-4, CZipAbstractFile::current);
m_pStorage->Read(buf, 12, false);
if (!m_pOpenedFile->CheckCrcAndSizes(buf))
ThrowError(CZipException::badZipFile);
}
m_pOpenedFile = NULL;
}
// add new header using the argument as a template
void CZipCentralDir::AddNewFile(const CZipFileHeader & header)
{
CZipFileHeader* pHeader = new CZipFileHeader(header);
m_pOpenedFile = pHeader;
m_headers.AddTail(pHeader);
if (m_bFindFastEnabled)
InsertFindFastElement(pHeader, WORD(m_headers.GetCount() - 1)); // GetCount > 0, 'cos we've just added a header
RemoveFromDisk();
m_pStorage->m_pFile->SeekToEnd();
}
void CZipCentralDir::RemoveFromDisk()
{
if (m_bOnDisk)
{
ASSERT(!m_pStorage->IsSpanMode()); // you can't add files to the existing disk span archive or to delete them from it
m_pStorage->m_pFile->SetLength(m_uBytesBeforeZip + m_uOffset);
m_bOnDisk = false;
}
}
void CZipCentralDir::CloseNewFile()
{
CZipAutoBuffer buf(12 + 4);
short iToWrite = 0;
bool bIsSpan = m_pStorage->IsSpanMode() != 0;
bool bEncrypted = m_pOpenedFile->IsEncrypted();
if (m_pOpenedFile->IsDataDescr())
{
if (bIsSpan || bEncrypted)
{
memcpy(buf, m_pStorage->m_gszExtHeaderSignat, 4);
iToWrite += 4;
}
}
else /*if (!IsSpan)*/
{
ASSERT(!bIsSpan && !bEncrypted);
m_pStorage->Flush();
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + 14, CZipAbstractFile::begin);
// we don't have to restore the pointer, because before adding a new file,
// the pointer is moved to the end
}
m_pOpenedFile->GetCrcAndSizes(buf + iToWrite);
iToWrite += 12;
// offset set during writing the local header
m_pOpenedFile->m_uOffset -= m_uBytesBeforeZip;
// write the data descriptor and a disk spanning signature at once
m_pStorage->Write(buf, iToWrite, true);
if (!bIsSpan && bEncrypted)
{
// write the information to the local header too
m_pStorage->Flush();
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + 14, CZipAbstractFile::begin);
m_pStorage->Write(buf + 4, 12, true);
}
if (!bIsSpan)
m_pStorage->Flush();
m_pOpenedFile = NULL;
}
void CZipCentralDir::Write()
{
if (m_bOnDisk)
return;
if (!m_pStorage->IsSpanMode())
{
m_pStorage->Flush();
m_pStorage->m_pFile->SeekToEnd();
}
m_uEntriesNumber = (WORD)m_headers.GetCount();
m_uSize = 0;
bool bDontAllowDiskChange = false;
// if there is a disk spanning archive in creation and it is only one-volume,
// (current disk is 0 so far, no bytes has been written so we know they are
// all in the buffer) make sure that it will be after writing central dir
// and make it a non disk spanning archive
if (m_pStorage->IsSpanMode() && m_pStorage->GetCurrentDisk() == 0)
{
DWORD uVolumeFree = m_pStorage->VolumeLeft();
// calculate the size of data descriptors already in the buffer or on the disk
// (they will be removed in the non disk spanning archive):
// multi span signature at the beginnig (4 bytes) + the size of the data
// descr. for each file (multi span signature + 12 bytes data)
// the count of bytes to add: central dir size - total to remove;
DWORD uToGrow = GetSize(true) - (4 + m_uEntriesNumber * (4 + 12));
if (uVolumeFree >= uToGrow)
// lets make sure it will be one-disk archive
{
// can the operation be done only in the buffer?
if (!m_pStorage->m_iBytesWritten && // no bytes on the disk yet
(m_pStorage->GetFreeInBuffer() >= uToGrow)) // is the buffer big enough?
{
RemoveDataDescr(true);
bDontAllowDiskChange = true; // if the disk change occurs somehow, we'll throw an error later
}
else
{
m_pStorage->Flush();
m_pStorage->m_pFile->Flush();
if (RemoveDataDescr(false))
bDontAllowDiskChange = true; // if the disk change occurs somehow, we'll throw an error later
}
}
}
WriteHeaders();
m_uThisDisk = (WORD)m_pStorage->GetCurrentDisk();
DWORD uSize = WriteCentralEnd();
if (bDontAllowDiskChange && (m_pStorage->GetCurrentDisk() != 0))
ThrowError(CZipException::badZipFile);
// if after adding a central directory there is a disk change,
// update the information and write it again
if (m_uThisDisk != m_pStorage->GetCurrentDisk())
{
m_uThisDisk = (WORD)m_pStorage->GetCurrentDisk();
if (m_uEntriesNumber)
{
m_uDiskEntriesNo = 0;
}
else
{
m_uDiskWithCD = m_uThisDisk;
m_uOffset = 0;
}
if (m_pStorage->m_uBytesInWriteBuffer >= uSize)
// if the data is still in the buffer, simply remove it
m_pStorage->m_uBytesInWriteBuffer -= uSize;
else
{
m_pStorage->Flush();
m_pStorage->m_iBytesWritten -= uSize;
m_pStorage->m_pFile->SeekToBegin();
}
WriteCentralEnd();
}
}
void CZipCentralDir::WriteHeaders()
{
m_uDiskEntriesNo = 0;
m_uDiskWithCD = (WORD)m_pStorage->GetCurrentDisk();
m_uOffset = m_pStorage->GetPosition() - m_uBytesBeforeZip;
if (!m_uEntriesNumber)
return;
WORD iDisk = m_uDiskWithCD;
for (int i = 0; i < m_uEntriesNumber; i++)
{
CZipFileHeader* pHeader = (*this)[i];
ConvertFileName(false, true, pHeader);
m_uSize += pHeader->Write(m_pStorage);
if (m_pStorage->GetCurrentDisk() != iDisk)
{
m_uDiskEntriesNo = 1;
iDisk = (WORD)m_pStorage->GetCurrentDisk();
// update the information about the offset and starting disk if the
// first header was written on the new disk
if (i == 0)
{
m_uOffset = 0;
m_uDiskWithCD = iDisk;
}
}
else
m_uDiskEntriesNo++;
}
}
DWORD CZipCentralDir::WriteCentralEnd()
{
DWORD uSize = GetSize();
CZipAutoBuffer buf(uSize);
WORD uCommentSize = (WORD)m_pszComment.GetSize();
memcpy(buf, m_gszSignature, 4);
memcpy(buf + 4, &m_uThisDisk, 2);
memcpy(buf + 6, &m_uDiskWithCD, 2);
memcpy(buf + 8, &m_uDiskEntriesNo, 2);
memcpy(buf + 10, &m_uEntriesNumber, 2);
memcpy(buf + 12, &m_uSize, 4);
memcpy(buf + 16, &m_uOffset, 4);
memcpy(buf + 20, &uCommentSize, 2);
memcpy(buf + 22, m_pszComment, uCommentSize);
m_pStorage->Write(buf, uSize, true);
return uSize;
}
void CZipCentralDir::RemoveFile(WORD uIndex)
{
CZipFileHdrLstIter iterator = GetIterator(uIndex);
CZipFileHeader* pHeader = GetFileHeader(iterator);
if (m_bFindFastEnabled)
{
int i = FindFileNameIndex(pHeader->GetFileName(), true);
ASSERT(i != -1);
int uIndex = m_findarray[i].m_uIndex;
m_findarray.RemoveAt(i);
// shift down the indexes
for (int j = 0; j < m_findarray.GetSize(); j++)
{
if (m_findarray[j].m_uIndex > uIndex)
m_findarray[j].m_uIndex--;
}
}
delete pHeader;
m_headers.RemoveAt(iterator);
}
DWORD CZipCentralDir::GetSize(bool bWhole)
{
DWORD uHeaders = 0;
if (bWhole)
{
for (CZipFileHdrLstIter iter = m_headers.GetHeadPosition(); m_headers.IteratorValid(iter); )
{
CZipFileHeader* pHeader = m_headers.GetNext(iter);
uHeaders += pHeader->GetSize();
}
}
return CENTRALDIRSIZE + m_pszComment.GetSize() + uHeaders;
}
bool CZipCentralDir::RemoveDataDescr(bool bFromBuffer)
{
ziparchv::CZipFileMapping fm;
char* pFile = NULL;
DWORD uSize;
if (bFromBuffer)
{
uSize = m_pStorage->m_uBytesInWriteBuffer;
pFile = m_pStorage->m_pWriteBuffer;
}
else
{
uSize = m_pStorage->m_pFile->GetLength();
// we cannot use CZipMemFile in multidisk archive
// so it MUST be CZipFile
if (!fm.CreateMapping((HANDLE)static_cast<CZipFile*>(m_pStorage->m_pFile)->operator HFILE()))
return false;
pFile = fm.GetMappedMemory();
}
DWORD uOffsetToChange = 4;
DWORD uToCopy = 0;
DWORD uPosInBuffer = 0;
DWORD uExtraHeaderLen;
// this will work providing the order in the m_headers is the same as
// in the archive
int i = 0;
for (CZipFileHdrLstIter iter = m_headers.GetHeadPosition(); m_headers.IteratorValid(iter); i++)
{
// update the flag value in the local and central header
// int uDataDescr = (m_headers[i]->m_uFlag & 8) ? (4 + 12) : 0;
CZipFileHeader* pHeader = m_headers.GetNext(iter);
char* pSour = pFile + pHeader->m_uOffset;
if (!pHeader->IsEncrypted())
{
// removing data descriptor
pHeader->m_uFlag &= ~8;
// update local header:
// write modified flag in the local header
memcpy(pSour + 6, &pHeader->m_uFlag, 2);
uExtraHeaderLen = 4/*ext. header signature*/ + 12/*data descriptor*/;
}
else
// do not remove data descriptors from encrypted files
uExtraHeaderLen = 0;
// update crc32 and sizes' values
pHeader->GetCrcAndSizes(pSour+ 14);
uToCopy = (i == (m_headers.GetCount() - 1) ? uSize : (*this)[i + 1]->m_uOffset)
- pHeader->m_uOffset - uExtraHeaderLen;
memmove(pFile + uPosInBuffer, pSour, uToCopy);
uPosInBuffer += uToCopy;
pHeader->m_uOffset -= uOffsetToChange;
uOffsetToChange += uExtraHeaderLen;
}
if (bFromBuffer)
m_pStorage->m_uBytesInWriteBuffer = uPosInBuffer;
else
{
m_pStorage->m_iBytesWritten = uPosInBuffer;
fm.RemoveMapping();
m_pStorage->m_pFile->SetLength(uPosInBuffer);
}
return true;
}
CZipFileHeader* CZipCentralDir::operator[](int iIndex)
{
return GetFileHeader(GetIterator(iIndex));
}
void CZipCentralDir::RemoveHeaders()
{
for (CZipFileHdrLstIter iter = m_headers.GetHeadPosition(); m_headers.IteratorValid(iter); )
delete m_headers.GetNext(iter);
m_headers.RemoveAll();
}
CZipCentralDir::CZipFileHdrLstIter CZipCentralDir::GetIterator(int iIndex)
{
if (!IsValidIndex(iIndex))
CZipException::Throw(CZipException::internal);
return m_headers.FindIndex(iIndex);
}
CZipFileHeader* CZipCentralDir::GetFileHeader(const CZipFileHdrLstIter &iterator)
{
CZipFileHeader* pHeader = m_headers.GetAt(iterator);
ASSERT(pHeader);
if (!pHeader)
CZipException::Throw(CZipException::internal);
return pHeader;
}
void CZipCentralDir::ConvertAll()
{
ASSERT(!m_bConvertAfterOpen);
for (CZipFileHdrLstIter iter = m_headers.GetHeadPosition(); m_headers.IteratorValid(iter); )
ConvertFileName(true, false, m_headers.GetNext(iter));
m_bConvertAfterOpen = true;
}
void CZipCentralDir::BuildFindFastArray()
{
m_findarray.RemoveAll();// just in case
WORD iIndex = 0;
for (CZipFileHdrLstIter iter = m_headers.GetHeadPosition(); m_headers.IteratorValid(iter); iIndex++)
InsertFindFastElement(m_headers.GetNext(iter), iIndex);
}
void CZipCentralDir::InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex)
{
CZipString fileName = pHeader->GetFileName();
int iSize = m_findarray.GetSize();
// Our initial binary search range encompasses the entire array of filenames:
int start = 0;
int end = iSize;
// Keep halving our search range until we find the right place
// to insert the new element:
while ( start < end )
{
// Find the midpoint of the search range:
int midpoint = ( start + end ) / 2;
// Compare the filename with the filename at the midpoint of the current search range:
int result = CompareElement(fileName, (WORD)midpoint, true);
// If our filename is larger, it must fall in the first half of the search range:
if ( result > 0 )
{
end = midpoint;
}
// If it's smaller, it must fall in the last half:
else if ( result < 0 )
{
start = midpoint + 1;
}
// If they're equal, we can go ahead and insert here:
else
{
start = midpoint; break;
}
}
m_findarray.InsertAt(start, CZipFindFast(pHeader, WORD(uIndex == -1 ? iSize : uIndex /* just in case */)));
}
int CZipCentralDir::FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive)
{
int start = 0;
int end = m_findarray.GetUpperBound();
// Keep halving our search range until we find the given element:
while ( start <= end )
{
// Find the midpoint of the search range:
int midpoint = ( start + end ) / 2;
// Compare the given filename with the filename at the midpoint of the search range:
int result = CompareElement(lpszFileName, (WORD)midpoint, bCaseSensitive);
// If our filename is smaller, it must fall in the first half of the search range:
if ( result > 0 )
{
end = midpoint - 1;
}
// If it's larger, it must fall in the last half:
else if ( result < 0 )
{
start = midpoint + 1;
}
// If they're equal, return the result:
else
{
return midpoint;
}
}
// Signal failure:
return -1;
}
ZIPINLINE int CZipCentralDir::CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSensitive)
{
return bCaseSensitive ? m_findarray[uIndex].m_pHeader->GetFileName().Collate(lpszFileName)
: m_findarray[uIndex].m_pHeader->GetFileName().CollateNoCase(lpszFileName);
}

View File

@@ -0,0 +1,378 @@
/**
* \file ZipCentralDir.h
* Interface for the CZipCentralDir class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_CENTRALDIR_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)
#define AFX_CENTRALDIR_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipexception.h"
#include "zipfileheader.h"
#include "zipautobuffer.h"
#include "zipcollections.h"
#include "zipcompatibility.h"
/**
Used in fast finding files by the filename.
\see CZipCentralDir::m_findarray
\see CZipArchive::FindFile
*/
ZEXPORT struct CZipFindFast
{
CZipFindFast()
{
m_uIndex = 0;
m_pHeader= NULL;
}
CZipFindFast(CZipFileHeader* pHeader, WORD uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
/**
We extract a name from it.
*/
CZipFileHeader* m_pHeader;
/**
The index in the central directory of the \e m_pHeader.
*/
WORD m_uIndex;
};
/**
A class representing the central directory record in the archive.
*/
ZEXPORT class CZipCentralDir
{
public:
CZipCentralDir();
virtual ~CZipCentralDir();
static char m_gszSignature[]; ///< central dir signature
char m_szSignature[4]; ///< end of central dir signature (must be 0x06054b50)
WORD m_uThisDisk; ///< number of this disk
WORD m_uDiskWithCD; ///< number of the disk with the start of the central directory
WORD m_uDiskEntriesNo; ///< total number of entries in the central dir on this disk
WORD m_uEntriesNumber; ///< total number of entries in the central dir
DWORD m_uSize; ///< size of the central directory
DWORD m_uOffset; ///< offset of start of central directory with respect to the starting disk number
CZipAutoBuffer m_pszComment; ///< the archive comment
CZipAutoBuffer m_pLocalExtraField; ///< a local extra field
CZipFileHeader* m_pOpenedFile; ///< points to a currently opened file or NULL if no file is opened
/**
Called by CZipArchive::OpenInternal.
*/
void Init();
/**
Read the central directory from the archive.
\note Throws exceptions.
*/
void Read();
/**
Open the file.
\param uIndex
zero-based index of the file to open
\note Throws exceptions.
*/
void OpenFile(WORD uIndex);
/**
Test if the given file header index is valid.
\param uIndex
a zero-based index
\return \c true if the file with the given index exists inside the archive; otherwise \c false;
*/
bool IsValidIndex(int uIndex);
/**
Remove the file header from the central directory.
\param uIndex
a zero-based index of the file header to remove
\note Throws exceptions.
*/
void RemoveFile(WORD uIndex);
/**
Cleanup the structure.
\param bEverything
- \c true - clear some attributes and remove all the file headers from memory
- \c false - do not remove the file headers. It is called in that manner
from CZipArchive::CloseFileAfterTestFailed so that the
next file can be tested for the integrity
\see CZipArchive::CloseFileAfterTestFailed
*/
void Clear(bool bEverything = true);
/**
Add a new file to the central directory.
\param header
copy data from it to the new file header
\note Throws exceptions.
*/
void AddNewFile(const CZipFileHeader & header);
/**
Remove physically the central directory from the archive.
Called during adding or deleting files.
\note Throws exceptions.
*/
void RemoveFromDisk();
/**
Get the central directory size.
\param bWhole
if \c true, include the size of the file headers
\return the size of the central directory
*/
DWORD GetSize(bool bWhole = false);
/**
Close a file inside archive opened for reading.
\note Throws exceptions.
*/
void CloseFile();
/**
Close a file inside archive opened for reading.
\note Throws exceptions.
*/
void CloseNewFile();
/**
Write the central directory to the archive.
\note Throws exceptions.
*/
void Write();
/**
Points to CZipArchive::m_storage.
*/
CZipStorage* m_pStorage;
DWORD m_uCentrDirPos; ///< the position of the beginning of the central directory
/**
The count of bytes before the actual zip archive in a file.
It is non-zero for self-extracting archives.
*/
DWORD m_uBytesBeforeZip;
/**
The size of the buffer used in searching for the central dir.
Set before opening the archive.
It is usually set with CZipArchive::SetAdvanced
(specify this value as the third argument).
\see CZipArchive::SetAdvanced
*/
int m_iBufferSize;
/**
Used in fast finding files by the filename.
\see CZipFindFast
\see m_bFindFastEnabled
\see CZipArchive::FindFile
*/
CZipFindFastArray m_findarray;
typedef CZipPtrList<CZipFindFast*>::iterator CZipFindFastLstIter;
/**
If \c true, the there is an additional array build, to speed up the
finding process
CZipArchive::FindFile uses this array to perform a
binary search.
\b Default: \c false
\see CZipArchive::EnableFindFast
\see CZipArchive::FindFile
\see CZipCentralDir::m_findarray
*/
bool m_bFindFastEnabled;
/**
Clear #m_findarray contents and free memory.
*/
/**
Build #m_findarray.
*/
void BuildFindFastArray();
/**
Holds all the files inside archive info.
\see CZipFileHeader
*/
CZipPtrList<CZipFileHeader*> m_headers;
typedef CZipPtrList<CZipFileHeader*>::iterator CZipFileHdrLstIter;
/**
\name Helpers
Helper methods to operate on the CZipPtrList
*/
//@{
CZipFileHeader* operator[](int iIndex);
CZipFileHdrLstIter GetIterator(int iIndex);
CZipFileHeader* GetFileHeader(const CZipFileHdrLstIter &iterator);
//@}
/**
- If \c true, the conversion of the filenames takes
place after opening the archive (after reading the central directory
from the file), and before writing the central directory back to
the archive.
- If \c false, the conversion takes place on each call to CZipArchive::GetFileInfo
Set it to \c true when you plan to use CZipArchive::FindFile or get the stored files information. <BR>
Set it to \c false when you plan mostly to only modify the archive.
\b Default: \c true
\note Set it before opening the archive.
\see ConvertFileName
*/
bool m_bConvertAfterOpen;
/**
Convert the filename of the CZipFileHeader depending on the current system
and the system the zip file was created on (change slash to backslash or
vice versa, perform ANSI-OEM conversion if necessary).
\param bFromZip
if \c true, convert from archive format
\param bAfterOpen
if \c true, called after opening the archive or before closing
\param pHeader
the header to have filename converted; if \c NULL convert the currently
opened file
\see ZipCompatibility::FileNameUpdate
\see m_bConvertAfterOpen
*/
void ConvertFileName(bool bFromZip, bool bAfterOpen, CZipFileHeader* pHeader = NULL)
{
if (bAfterOpen != m_bConvertAfterOpen)
return;
if (!pHeader)
{
pHeader = m_pOpenedFile;
ASSERT(pHeader);
}
ZipCompatibility::FileNameUpdate(*pHeader, bFromZip);
}
/**
Convert all the filenames to the system form.
Called by CZipArchive::FindFile
\see CZipArchive::FindFile
*/
void ConvertAll();
/**
\param lpszFileName
the name of the file to find, must be exactly the same (apart from case)
as it appears in the archive
\param bCaseSensitive
\c true if perform a case sensitive search
\return the index in #m_findarray with the appropriate CZipFindFast structure
or \c -1 if there is no file with the given name
\see CZipArchive::FindFile
*/
int FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive);
protected:
/**
The \e lpszFileName and \e bCaseSensitive arguments
are the same as in the #FindFileNameIndex. The function get CZipFindFast
structure pointed by \e uIndex and compares the filename of CZipFileHeader
class stored in this structure with \e lpszFileName.
\param lpszFileName
\param uIndex
the index from #m_findarray
\param bCaseSensitive
\return
- 0 if the filenames are the same
- < 0 if the filename stored in the array is less than \e lpszFileName
- > 0 if the filename stored in the array is greater than \e lpszFileName
*/
ZIPINLINE int CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSensitive);
/**
Insert a new CZipFindFast element to the #m_findarray.
Initialize CZipFindFast object with \e pHeader and \e uIndex values.
\param pHeader
\param uIndex
*/
void InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex);
/**
\c true if the central directory is in physically present in the archive
*/
bool m_bOnDisk;
/**
\return the location of the beginning of the central dir end record in the archive
\note Throws exceptions.
*/
DWORD Locate();
/**
Read the file headers from the file.
\note Throws exceptions.
*/
void ReadHeaders();
/**
Free the memory allocated for the CZipFileHeader structures.
*/
void RemoveHeaders();
/**
Remove data descriptors from the write buffer in the disk spanning volume
that turned out to be one-disk only.
We do not remove them from password encrypted files.
\param bFromBuffer
if \c true, remove from the buffer in memory otherwise from the file on a disk
\return \c false if the file mapping to memory was not successful
Can happen only when \e bFormBuffer is \c false.
\note Throws exceptions.
*/
bool RemoveDataDescr(bool bFromBuffer);
/**
Write the file headers to the archive.
\note Throws exceptions.
*/
void WriteHeaders();
/**
Write the central directory end record.
\return the size of the record
\note Throws exceptions.
*/
DWORD WriteCentralEnd();
/**
Throw an exception with the given code.
\param err
\see CZipException::Throw
*/
void ThrowError(int err);
};
#endif // !defined(AFX_CENTRALDIR_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)

View File

@@ -0,0 +1,26 @@
// ZipCollections.cpp:
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipcollections.h"
//************************* CZipWordArray ****************************
void CZipWordArray::Sort(bool bAscending)
{
if (bAscending)
std::sort (begin (), end (), std::less<WORD> ());
else
std::sort (begin (), end (), std::greater<WORD> ());
}

View File

@@ -0,0 +1,107 @@
// ZipCollections.h: various platform-dependent definitions to try to make
// sanity of cross platform datatyping.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#ifndef ZIPCOLLECTIONS_DOT_H
#define ZIPCOLLECTIONS_DOT_H
#if _MSC_VER > 1000
#pragma warning( push, 3 ) // STL requrements
#pragma warning (disable : 4284)
#pragma warning (disable : 4018)
#endif
#include <vector>
#include <list>
#include <algorithm>
#include<functional>
struct CZipFindFast;
#include "zipstring.h"
template<class TYPE>
class CZipArray : public std::vector<TYPE>
{
public:
typedef std::vector<TYPE>::iterator iterator;
protected:
iterator GetIterFromIndex(int uIndex)
{
iterator iter = begin();
int t = 0; while (t != uIndex) {iter++;t++;}
return iter;
}
public:
int GetSize() const{return size(); }
int GetUpperBound() const {return size() - 1;}
void Add(const TYPE& x) {push_back(x);}
void RemoveAll() {clear();}
void RemoveAt(int uIndex) { erase(GetIterFromIndex(uIndex));}
void InsertAt(int uIndex, const TYPE& x){insert(GetIterFromIndex(uIndex), x);}
};
typedef CZipArray<CZipString> CZipStringArray;
typedef CZipArray<CZipFindFast> CZipFindFastArray;
ZEXPORT class CZipWordArray : public CZipArray<WORD>
{
public:
void Sort(bool bAscending);
};
template<class TYPE>
class CZipPtrList : public std::list<TYPE>
{
public:
typedef std::list<TYPE>::iterator iterator;
int GetCount() const {return size();}
void AddTail(const TYPE& x){push_back(x);}
void AddHead(const TYPE& x){push_front(x);}
void RemoveHead() {pop_front();}
void RemoveTail() {pop_back();}
void RemoveAll() {clear();}
TYPE& GetHead() {return front();}
TYPE GetHead() const {return front();}
TYPE& GetTail() {return back();}
TYPE GetTail() const {return back();}
iterator GetHeadPosition() { return begin();}
iterator GetTailPosition() { return back();}
TYPE& GetNext(iterator& pos) { return *pos++;}
TYPE GetNext(iterator& pos) const{ return *pos++;}
TYPE& GetPrev(iterator& pos) { return *pos--;}
TYPE GetPrev(iterator& pos) const{ return *pos--;}
iterator Find(TYPE& x) { return std::find(begin(), end(), x);}
void RemoveAt(iterator& pos) { erase(pos);}
bool IteratorValid(const iterator &iter)
{
return iter != end();
}
iterator FindIndex(int iIndex)
{
iterator iter = begin();
int t = 0; while (t != iIndex) {iter++;t++;}
return iter;
}
TYPE& GetAt(const iterator& pos) { return *pos;}
TYPE GetAt(const iterator& pos) const{ return *pos;}
};
#if defined(_MSC_VER) && (_MSC_VER > 1100)
#pragma warning( pop)
#endif
#endif /* ZIPCOLLECTIONS_DOT_H */

View File

@@ -69,11 +69,11 @@ int hb_CompressFile(char *szFile,PHB_ITEM pArray,int iCompLevel,PHB_ITEM pBloc
uLong uiCount;
uLong uiPos;
char szNewFile[MAXFILENAME];
int iCause=0;
int iCause;
BOOL bFileExist=hb_fsFile((BYTE*)szFile);
CZipArchive szZip;
BOOL bReturn = true;
DWORD dwSize=0;
DWORD dwSize;
if (szPassWord != NULL){
szZip.SetPassword(szPassWord);
}
@@ -174,11 +174,11 @@ int hb_CompressFile(char *szFile,PHB_ITEM pArray,int iCompLevel,PHB_ITEM pBloc
uLong uiCount;
char szNewFile[MAXFILENAME];
CZipArchive szZip;
int iCause=0;
int iCause;
BOOL bReturn=true;
uLong uiPos;
BOOL bFileExist=hb_fsFile((BYTE*)szFile);
DWORD dwSize=0;
DWORD dwSize;
if (pDiskBlock !=NULL){
pDiskStatus=pDiskBlock;
}
@@ -321,10 +321,10 @@ int hb_CompressFileStd(char *szFile,char *szFiletoCompress,int iCompLevel,PHB_
{
uLong uiCount;
char szNewFile[MAXFILENAME];
int iCause=0;
int iCause;
BOOL bFileExist=hb_fsFile((BYTE*)szFile);
BOOL bReturn=true;
DWORD dwSize=0;
DWORD dwSize;
CZipArchive szZip;
if (szPassWord != NULL){
szZip.SetPassword(szPassWord);
@@ -414,15 +414,15 @@ int hb_CompressFileStd(char *szFile,char *szFiletoCompress,int iCompLevel,PHB_
return bReturn; /* to avoid warning */
}
int hb_CmpTdSpanStd(char *szFile,char * szFiletoCompress,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,PHB_ITEM pDiskBlock,int iSpanSize,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress)
int hb_CmpTdSpanStd(char *szFile,char * szFiletoCompress,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,PHB_ITEM pDiskBlock,int iSpanSize,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress)
{
uLong uiCount;
char szNewFile[MAXFILENAME];
CZipArchive szZip;
int iCause=0;
int iCause;
BOOL bReturn=true;
DWORD dwSize=0;
DWORD dwSize;
BOOL bFileExist=hb_fsFile((BYTE*)szFile);
if (pDiskBlock !=NULL){
pDiskStatus=pDiskBlock;
@@ -513,7 +513,7 @@ int hb_CompressFileStd(char *szFile,char *szFiletoCompress,int iCompLevel,PHB_
if (pProgressInfo)
hb_itemRelease(pProgressInfo );
return true; /* to avoid warning */
return bReturn; /* to avoid warning */
}
BOOL hb_CreateZipInMemory(char *szFileToCompress,char *szFile)
{
@@ -560,7 +560,7 @@ return bReturn;
#if defined(HB_OS_WIN_32) || defined(__MINGW32__)
DWORD GetCurrentFileSize( LPCTSTR szFile)
{
DWORD dwFileSize=0;
DWORD dwFlags=FILE_ATTRIBUTE_ARCHIVE;
HANDLE hFind;
WIN32_FIND_DATA hFilesFind;

View File

@@ -0,0 +1,207 @@
// ZipCompatibility.cpp: implementation of the ZipCompatibility class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipcompatibility.h"
#include "zipplatform.h"
#include "zipexception.h"
#include "zipautobuffer.h"
#include "zipfileheader.h"
enum iInternalAttr
{
attROnly = 0x01,
attHidd = 0x02,
attSys = 0x04,
attDir = 0x10,
attArch = 0x20
};
// *********************** WINDOWS **************************
#ifndef _WIN32
#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
#endif
// *********************** UINX **************************
#define USER_PERMISSIONS_MASK 0x01C00000
#define EXTRACT_USER_PERMISSIONS(x) ((x & USER_PERMISSIONS_MASK) >> 22)
#define CREATE_USER_PERMISSIONS(x) ((x & 0x0007) << 22)
#define GROUP_PERMISSIONS_MASK 0x00380000
#define EXTRACT_GROUP_PERMISSIONS ((x & GROUP_PERMISSIONS_MASK) >> 19)
#define CREATE_GROUP_PERMISSIONS(x) ((x & 0x0007) << 19)
#define OTHER_PERMISSIONS_MASK 0x00070000
#define EXTRACT_OTHER_PERMISSIONS ((x & OTHER_PERMISSIONS_MASK) >> 16)
#define CREATE_OTHER_PERMISSIONS(x) ((x & 0x0007) << 16)
#define UNIX_DIRECTORY_ATTRIBUTE 0x40000000
#define UNIX_FILE_ATTRIBUTE 0x80000000
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace ZipCompatibility;
typedef DWORD(*conv_func)(DWORD , bool );
DWORD AttrDos(DWORD , bool );
DWORD AttrUnix(DWORD, bool);
DWORD AttrMac(DWORD , bool );
// more to come...
conv_func conv_funcs[11] = {AttrDos,
NULL,
NULL,
AttrUnix,
NULL,
NULL,
AttrDos,
AttrMac,
NULL,
NULL,
AttrDos
};
DWORD ZipCompatibility::ConvertToSystem(DWORD uAttr, int iFromSystem, int iToSystem)
{
if (iToSystem != iFromSystem && iFromSystem < 11 && iToSystem < 11)
{
conv_func p = conv_funcs[iFromSystem], q = conv_funcs[iToSystem];
if (p && q)
uAttr = q( p(uAttr, true), false);
else
CZipException::Throw(CZipException::platfNotSupp);
}
return uAttr;
}
DWORD AttrDos(DWORD uAttr, bool )
{
return uAttr;
}
DWORD AttrUnix(DWORD uAttr, bool bFrom)
{
DWORD uNewAttr = 0;
if (bFrom)
{
if (uAttr & UNIX_DIRECTORY_ATTRIBUTE)
uNewAttr = attDir;
uAttr = EXTRACT_USER_PERMISSIONS (uAttr);
// we may set archive attribute if the file hasn't the execute permissions
//
if (!(uAttr & 1))
uNewAttr |= attArch ;
if (!(uAttr & 2))
uNewAttr |= attROnly;
if (!(uAttr & 4))
uNewAttr |= attHidd;
}
else
{
uNewAttr = 0; // we cannot assume that if the file hasn't the archive attribute set
//then it is executable and set execute permissions
if (!(uAttr & attHidd))
uNewAttr |= (CREATE_OTHER_PERMISSIONS (4) |
CREATE_GROUP_PERMISSIONS (4))
| CREATE_USER_PERMISSIONS (4);
if (!(uAttr & attROnly))
uNewAttr |= (CREATE_GROUP_PERMISSIONS (2) |
CREATE_USER_PERMISSIONS (2));
if (uAttr & attDir)
uNewAttr |= UNIX_DIRECTORY_ATTRIBUTE | attDir /*necessary for other archivers (such as Info-Zip)*/;
}
return uNewAttr;
}
DWORD AttrMac(DWORD uAttr, bool )
{
DWORD uNewAttr = uAttr & (attDir | attROnly);
// if (bFrom)
// {
//
// }
// else
// {
//
// }
return uNewAttr;
}
// ************************************************************************
ZIPINLINE bool ZipCompatibility::IsPlatformSupported(int iCode)
{
return iCode == zcDosFat || iCode == zcUnix || iCode == zcMacintosh
|| iCode == zcNtfs || iCode == zcOs2Hpfs || iCode >= 11;
}
void ZipCompatibility::FileNameUpdate(CZipFileHeader& header, bool bFromZip)
{
int iSysHeader = header.GetSystemCompatibility();
int iCurSystem = ZipPlatform::GetSystemID();
if (bFromZip)
{
if (iCurSystem == zcDosFat)
SlashBackslashChg(header.m_pszFileName, true);
if (iSysHeader == zcDosFat)
ZipPlatform::AnsiOem(header.m_pszFileName, false);
}
else
{
if (iSysHeader == zcDosFat)
{
ZipPlatform::AnsiOem(header.m_pszFileName, true);
}
SlashBackslashChg(header.m_pszFileName, false);
}
}
void ZipCompatibility::SlashBackslashChg(CZipAutoBuffer& buffer, bool bReplaceSlash)
{
char t1 = '\\' /*backslash*/, t2 = '/', c1, c2;
if (bReplaceSlash)
{
c1 = t1;
c2 = t2;
}
else
{
c1 = t2;
c2 = t1;
}
for (DWORD i = 0; i < buffer.GetSize(); i++)
{
if (buffer[i] == c2)
buffer[i] = c1;
}
}

View File

@@ -0,0 +1,101 @@
/**
* \file ZipCompatibility.h
* ZipCompatibility namespace declaration.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPCOMPATIBILITY_H__8E8B9904_84C7_4B22_B364_A10ED0E7DAD6__INCLUDED_)
#define AFX_ZIPCOMPATIBILITY_H__8E8B9904_84C7_4B22_B364_A10ED0E7DAD6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CZipAutoBuffer;
class CZipFileHeader;
/**
Functions that provides the proper conversion of attrubutes
and filename strings between different system platforms.
*/
namespace ZipCompatibility
{
/**
The codes of the compatibility of the file attribute information.
\see CZipArchive::GetSystemCompatibility
\see CZipFileHeader::GetSystemCompatibility
\see ZipPlatform::GetSystemID
*/
enum ZipPlatforms
{
zcDosFat, ///< MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)
zcAmiga, ///< Amiga
zcVaxVms, ///< VAX/VMS
zcUnix, ///< Unix / Linux
zcVmCms, ///< VM/CMS
zcAtari, ///< Atari ST
zcOs2Hpfs, ///< OS/2 H.P.F.S.
zcMacintosh, ///< Macintosh
zcZsystem, ///< Z-System
zcCpm, ///< CP/M
zcNtfs ///< Windows NTFS
};
/**
Check whether the system with the given code is supported by the ZipArchive library.
\param iCode
\link #ZipPlatforms the system code \endlink
\return \c true if supported
*/
ZIPINLINE bool IsPlatformSupported(int iCode);
/**
Convert the system attributes between different system platforms.
It calls one of the converting functions.
\param uAttr
attributes to convert
\param iFromSystem
system code to convert from
\param iToSystem
system code to convert to
\return the converted attributes
\note Throws exceptions.
\see ZipPlatforms
*/
DWORD ConvertToSystem(DWORD uAttr, int iFromSystem, int iToSystem);
/**
Convert the filename of the file inside archive.
This conversion may not change the size of the filename, otherwise an
error may occur in #ReadLocal while comparing the filename sizes.
\param header
the file header to have the filename converted
\param bFromZip
if \c true convert the path from the from it is stored in the archive
to the current system compatible form; otherwise vice-versa.
\see CZipCentralDir::ConvertFileName
*/ void FileNameUpdate(CZipFileHeader& header, bool bFromZip);
/**
Change the slash to backslash or vice-versa in \e buffer.
\param buffer
\param bReplaceSlash
if \c true, change slash to backslash
*/
void SlashBackslashChg(CZipAutoBuffer& buffer, bool bReplaceSlash);
};
#endif // !defined(AFX_ZIPCOMPATIBILITY_H__8E8B9904_84C7_4B22_B364_A10ED0E7DAD6__INCLUDED_)

View File

@@ -0,0 +1,73 @@
// ZipException.cpp: implementation of the CZipException class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipexception.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#ifdef _MFC_VER
IMPLEMENT_DYNAMIC( CZipException, CException)
#endif
CZipException::CZipException(int iCause, LPCTSTR lpszZipName)
#ifdef _MFC_VER
:CException(TRUE)
#endif
{
m_iCause = iCause;
if (lpszZipName)
m_szFileName = lpszZipName;
}
CZipException::~CZipException()
{
}
void CZipException::Throw(int iZipError, LPCTSTR lpszZipName)
{
#ifdef _MFC_VER
throw new CZipException(iZipError, lpszZipName);
#else
CZipException e(iZipError, lpszZipName);
throw e;
#endif
}
int CZipException::ZlibErrToZip(int iZlibError)
{
switch (iZlibError)
{
case 2://Z_NEED_DICT:
return CZipException::needDict;
case 1://Z_STREAM_END:
return CZipException::streamEnd;
case -1://Z_ERRNO:
return CZipException::errNo;
case -2://Z_STREAM_ERROR:
return CZipException::streamError;
case -3://Z_DATA_ERROR:
return CZipException::dataError;
case -4://Z_MEM_ERROR:
return CZipException::memError;
case -5://Z_BUF_ERROR:
return CZipException::bufError;
case -6://Z_VERSION_ERROR:
return CZipException::versionError;
default:
return CZipException::generic;
}
}

View File

@@ -0,0 +1,126 @@
/**
* \file ZipException.h
* Interface for the CZipException class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_)
#define AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipstring.h"
#include "zipbaseexception.h"
/**
A class representing exceptions specific to the ZipArchive library.
Library exception class derived in the MFC version from CException
and in non-MFC version from std::exception.
*/
ZEXPORT class CZipException : public CZipBaseException
{
public:
CZipException(int iCause = generic, LPCTSTR lpszZipName = NULL);
CZipException::CZipException(CZipException& e)
{
m_szFileName = e.m_szFileName;
m_iCause = e.m_iCause;
}
/**
Throw an exception.
Throw CZipException* in the MFC version of the library
(the object must be deleted with Delete() method)
and CZipException in other versions.
The arguments are the same as in CZipException().
\param iZipError
\param lpszZipName
\see CZipException()
*/
static void Throw(int iZipError = CZipException::generic, LPCTSTR lpszZipName = NULL);
/**
Convert a zlib library error code to a \link #ZipErrors CZipException error code \endlink
\param iZlibError
zlib library error code
\return \link #ZipErrors CZipException error code \endlink
*/
static int ZlibErrToZip(int iZlibError);
/**
The name of the zip file where the error occurred.
*/
CZipString m_szFileName;
/**
The codes of errors thrown by the ZipArchive library
*/
enum ZipErrors
{
noError, ///< no error
// 1 - 42 reserved for errno (from STL) values - used only in non-MFC versions
// 43 - 99 reserved
generic = 100, ///< unknown error
badZipFile, ///< damaged or not a zip file
badCrc, ///< crc mismatched
noCallback, ///< no callback function set
aborted, ///< disk change callback function returned \c false
nonRemovable, ///< the disk selected for pkzipSpan archive is non removable
tooManyVolumes, ///< limit of the maximum volumes reached (999)
tooLongFileName, ///< the filename of the file added to the archive is too long
badPassword, ///< incorrect password set for the file being decrypted
dirWithSize, ///< during testing: found the directory with the size greater than 0
internal, ///< internal error
notRemoved, ///< error while removing a file (under Windows call GetLastError() to find out more)
notRenamed, ///< error while renaming a file (under Windows call GetLastError() to find out more)
platfNotSupp, ///< the platform that the zip file was created under is not supported
cdirNotFound, ///< the central directory was not found in the archive (it is thrown also when the last disk of multi-disk archive is not in the drive when opening the archive)
streamEnd = 500, ///< zlib library error
needDict, ///< zlib library error
errNo, ///< zlib library error
streamError, ///< zlib library error
dataError, ///< zlib library error
memError, ///< zlib library error thrown by CZipMemFile as well
bufError, ///< zlib library error
versionError, ///< zlib library error
};
/**
A cause of the error - takes one of the #ZipErrors enumeration codes.
*/
int m_iCause;
/**
\param iCause
error cause (takes one of the #ZipErrors enumeration codes)
\param lpszZipName
the name of the file where the error occurred (if applicable)
*/
virtual ~CZipException();
#ifdef _MFC_VER
DECLARE_DYNAMIC(CZipException)
#endif
};
#endif // !defined(AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_)

View File

@@ -0,0 +1,101 @@
// ZipFile.cpp: implementation of the ZipFiles class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipfile.h"
#include "zipexception.h"
#include "zipplatform.h"
#include <fcntl.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CZipFile::CZipFile()
{
m_hFile = -1;
}
void CZipFile::ThrowError()
{
CZipException::Throw(errno, m_szFileName);
}
DWORD CZipFile::GetLength()
{
DWORD dwLen, dwCur;
dwCur = Seek(0L, current);
dwLen = Seek(0L, end);
Seek(dwCur, begin);
return dwLen;
}
bool CZipFile::Open(LPCTSTR lpszFileName, UINT openFlags, bool bThrow)
{
if (!IsClosed())
Close();
UINT iNewFlags = O_BINARY;
bool bReadOnly = false;
if (openFlags & CZipFile::modeCreate)
iNewFlags |= O_CREAT;
if ((openFlags & CZipFile::modeReadWrite) == CZipFile::modeReadWrite)
iNewFlags |= O_RDWR;
else if (openFlags & CZipFile::modeRead)
{
// O_RDONLY is defined as 0
bReadOnly = true;
iNewFlags |= O_RDONLY;
}
else if (openFlags & CZipFile::modeWrite)
iNewFlags |= O_WRONLY;
if (!(openFlags & CZipFile::modeNoTruncate) && !bReadOnly)
iNewFlags |= O_TRUNC;
m_hFile = ZipPlatform::OpenFile(lpszFileName, iNewFlags, openFlags & 0x1C);
if (m_hFile == -1)
if (bThrow)
ThrowError();
else
return false;
m_szFileName = lpszFileName;
return true;
}
void CZipFile::SetLength(long nNewLen)
{
ZipPlatform::TruncateFile(m_hFile, nNewLen);
}
void CZipFile::Flush()
{
if (!ZipPlatform::FlushFile(m_hFile))
ThrowError();
}
CZipFile::operator HFILE()
{
HFILE hf = ZipPlatform::GetFileSystemHandle(m_hFile);
if (hf == -1)
ThrowError();
return hf;
}

View File

@@ -0,0 +1,99 @@
// ZipFile.h: interface for the ZipFiles class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPFILE_H__80609DE0_2C6D_4C94_A90C_0BE34A50C769__INCLUDED_)
#define AFX_ZIPFILE_H__80609DE0_2C6D_4C94_A90C_0BE34A50C769__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipabstractfile.h"
#include "zipstring.h"
#include <io.h>
ZEXPORT class CZipFile :public CZipAbstractFile
{
void ThrowError();
public:
int m_hFile;
operator HFILE();
enum OpenModes
{
modeRead = 0x0001,
modeWrite = 0x0002,
modeReadWrite = modeRead | modeWrite,
shareDenyWrite = 0x0004,
shareDenyRead = 0x0008,
shareDenyNone = 0x0010,
modeCreate = 0x0020,
modeNoTruncate = 0x0040,
};
CZipFile(LPCTSTR lpszFileName, UINT openFlags)
{
m_hFile = -1;
Open(lpszFileName, openFlags, true);
}
void Flush();
DWORD GetLength();
CZipString GetFilePath(){return m_szFileName;}
bool IsClosed(){ return m_hFile == -1;}
bool Open(LPCTSTR lpszFileName, UINT openFlags, bool bThrow);
void Close()
{
if (IsClosed())
return;
if (close(m_hFile) != 0)
ThrowError();
else
{
m_szFileName.empty();
m_hFile = -1;
}
}
void Write(const void* lpBuf, UINT nCount)
{
if (write(m_hFile, lpBuf, nCount) != (int) nCount)
ThrowError();
}
long GetPosition()
{
long ret = tell(m_hFile);
if (ret == -1L)
ThrowError();
return ret;
}
void SetLength(long nNewLen);
UINT Read(void *lpBuf, UINT nCount)
{
errno = 0;
int ret = read(m_hFile, lpBuf, nCount);
if (ret < (int) nCount && errno != 0)
ThrowError();
return ret;
}
long Seek(long dOff, int nFrom)
{
long ret = lseek(m_hFile, dOff, nFrom);
if (ret == -1)
ThrowError();
return ret;
}
CZipFile ();
virtual ~CZipFile (){Close();};
protected:
CZipString m_szFileName;
};
#endif // !defined(AFX_ZIPFILE_H__80609DE0_2C6D_4C94_A90C_0BE34A50C769__INCLUDED_)

View File

@@ -0,0 +1,330 @@
// ZipFileHeader.cpp: implementation of the CZipFileHeader class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zlib.h"
#include "zipfileheader.h"
#include "zipautobuffer.h"
#include "ziparchive.h"
#include "zipplatform.h"
#include "zipcompatibility.h"
#include <time.h>
#define FILEHEADERSIZE 46
#define LOCALFILEHEADERSIZE 30
#define ENCR_HEADER_LEN 12
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
char CZipFileHeader::m_gszSignature[] = {0x50, 0x4b, 0x01, 0x02};
char CZipFileHeader::m_gszLocalSignature[] = {0x50, 0x4b, 0x03, 0x04};
CZipFileHeader::CZipFileHeader()
{
m_uExternalAttr = 0;//ZipPlatform::GetDefaultAttributes();
m_uModDate = m_uModTime = 0;
m_uMethod = Z_DEFLATED;
// SetSystemCompatibility(ZipPlatform::m_sSystemID);
}
CZipFileHeader::~CZipFileHeader()
{
}
// read the header from the central dir
bool CZipFileHeader::Read(CZipStorage *pStorage)
{
// // just in case
// m_pszComment.Release();
// m_pszFileName.Release();
WORD uFileNameSize, uCommentSize, uExtraFieldSize;
CZipAutoBuffer buf(FILEHEADERSIZE);
pStorage->Read(buf, FILEHEADERSIZE, true);
memcpy(&m_szSignature, buf, 4);
memcpy(&m_uVersionMadeBy, buf + 4, 2);
memcpy(&m_uVersionNeeded, buf + 6, 2);
memcpy(&m_uFlag, buf + 8, 2);
memcpy(&m_uMethod, buf + 10, 2);
memcpy(&m_uModTime, buf + 12, 2);
memcpy(&m_uModDate, buf + 14, 2);
memcpy(&m_uCrc32, buf + 16, 4);
memcpy(&m_uComprSize, buf + 20, 4);
memcpy(&m_uUncomprSize, buf + 24, 4);
memcpy(&uFileNameSize, buf + 28, 2);
memcpy(&uExtraFieldSize, buf + 30, 2);
memcpy(&uCommentSize, buf + 32, 2);
memcpy(&m_uDiskStart, buf + 34, 2);
memcpy(&m_uInternalAttr, buf + 36, 2);
memcpy(&m_uExternalAttr, buf + 38, 4);
memcpy(&m_uOffset, buf + 42, 4);
buf.Release();
if (memcmp(m_szSignature, m_gszSignature, 4) != 0)
return false;
int iCurDsk = pStorage->GetCurrentDisk();
m_pszFileName.Allocate(uFileNameSize); // don't add NULL at the end
pStorage->Read(m_pszFileName, uFileNameSize, true);
if (uExtraFieldSize)
{
ASSERT(!m_pExtraField.IsAllocated());
m_pExtraField.Allocate(uExtraFieldSize);
pStorage->Read(m_pExtraField, uExtraFieldSize, true);
}
if (uCommentSize)
{
m_pszComment.Allocate(uCommentSize);
pStorage->Read(m_pszComment, uCommentSize, true);
}
return pStorage->GetCurrentDisk() == iCurDsk; // check that the whole header is on the one disk
}
time_t CZipFileHeader::GetTime()
{
struct tm atm;
atm.tm_sec = (m_uModTime & ~0xFFE0) << 1;
atm.tm_min = (m_uModTime & ~0xF800) >> 5;
atm.tm_hour = m_uModTime >> 11;
atm.tm_mday = m_uModDate & ~0xFFE0;
atm.tm_mon = ((m_uModDate & ~0xFE00) >> 5) - 1;
atm.tm_year = (m_uModDate >> 9) + 80;
atm.tm_isdst = -1;
return mktime(&atm);
}
// write the header to the central dir
DWORD CZipFileHeader::Write(CZipStorage *pStorage)
{
WORD uFileNameSize = GetFileNameSize(), uCommentSize = GetCommentSize(),
uExtraFieldSize = GetExtraFieldSize();
DWORD iSize = GetSize();
CZipAutoBuffer buf(iSize);
memcpy(buf, &m_szSignature, 4);
memcpy(buf + 4, &m_uVersionMadeBy, 2);
memcpy(buf + 6, &m_uVersionNeeded, 2);
memcpy(buf + 8, &m_uFlag, 2);
memcpy(buf + 10, &m_uMethod, 2);
memcpy(buf + 12, &m_uModTime, 2);
memcpy(buf + 14, &m_uModDate, 2);
memcpy(buf + 16, &m_uCrc32, 4);
memcpy(buf + 20, &m_uComprSize, 4);
memcpy(buf + 24, &m_uUncomprSize, 4);
memcpy(buf + 28, &uFileNameSize, 2);
memcpy(buf + 30, &uExtraFieldSize, 2);
memcpy(buf + 32, &uCommentSize, 2);
memcpy(buf + 34, &m_uDiskStart, 2);
memcpy(buf + 36, &m_uInternalAttr, 2);
memcpy(buf + 38, &m_uExternalAttr, 4);
memcpy(buf + 42, &m_uOffset, 4);
memcpy(buf + 46, m_pszFileName, uFileNameSize);
if (uExtraFieldSize)
memcpy(buf + 46 + uFileNameSize, m_pExtraField, uExtraFieldSize);
if (uCommentSize)
memcpy(buf + 46 + uFileNameSize + uExtraFieldSize, m_pszComment, uCommentSize);
pStorage->Write(buf, iSize, true);
return iSize;
}
bool CZipFileHeader::ReadLocal(CZipStorage *pStorage, WORD& iLocExtrFieldSize)
{
char buf[LOCALFILEHEADERSIZE];
pStorage->Read(buf, LOCALFILEHEADERSIZE, true);
if (memcmp(buf, m_gszLocalSignature, 4) != 0)
return false;
bool bIsDataDescr = (((WORD)*(buf + 6)) & 8) != 0;
WORD uFileNameSize = GetFileNameSize();
if ((memcmp(buf + 6, &m_uFlag, 2) != 0)
||(memcmp(buf + 8, &m_uMethod, 2) != 0)
|| (m_uMethod && (m_uMethod != Z_DEFLATED))
|| (memcmp(buf + 26, &uFileNameSize, 2) != 0))
return false;
// jeszcze mo¿naby porównaæ nazwy plików
if (!bIsDataDescr/* || !pStorage->IsSpanMode()*/)
if (!CheckCrcAndSizes(buf + 14))
return false;
memcpy(&iLocExtrFieldSize, buf + 28, 2);
pStorage->m_pFile->Seek(uFileNameSize, CZipAbstractFile::current);
return true;
}
void CZipFileHeader::SetTime(const time_t & ttime)
{
tm* gt = localtime(&ttime);
WORD year = (WORD)(gt->tm_year + 1900);
if (year <= 1980)
year = 0;
else
year -= 1980;
m_uModDate = (WORD) (gt->tm_mday + ((gt->tm_mon + 1)<< 5) + (year << 9));
m_uModTime = (WORD) ((gt->tm_sec >> 1) + (gt->tm_min << 5) +
(gt->tm_hour << 11));
}
// the buffer contains crc32, compressed and uncompressed sizes to be compared
// with the actual values
bool CZipFileHeader::CheckCrcAndSizes(char *pBuf)
{
return (memcmp(pBuf, &m_uCrc32, 4) == 0) && (memcmp(pBuf + 4, &m_uComprSize, 4) == 0)
&& (memcmp(pBuf + 8, &m_uUncomprSize, 4) == 0);
}
// write the local header
void CZipFileHeader::WriteLocal(CZipStorage& storage)
{
// extra field is local by now
WORD uFileNameSize = GetFileNameSize(), uExtraFieldSize = GetExtraFieldSize();
DWORD iLocalSize = LOCALFILEHEADERSIZE + uExtraFieldSize + uFileNameSize;
CZipAutoBuffer buf(iLocalSize);
memcpy(buf, m_gszLocalSignature, 4);
memcpy(buf + 4, &m_uVersionNeeded, 2);
memcpy(buf + 6, &m_uFlag, 2);
memcpy(buf + 8, &m_uMethod, 2);
memcpy(buf + 10, &m_uModTime, 2);
memcpy(buf + 12, &m_uModDate, 2);
memcpy(buf + 14, &m_uCrc32, 4);
memcpy(buf + 18, &m_uComprSize, 4);
memcpy(buf + 22, &m_uUncomprSize, 4);
memcpy(buf + 26, &uFileNameSize, 2);
memcpy(buf + 28, &uExtraFieldSize, 2);
memcpy(buf + 30, m_pszFileName, uFileNameSize);
memcpy(buf + 30 + uFileNameSize, m_pExtraField, uExtraFieldSize);
// possible disk change before writing to the file in the disk spanning mode
// so write the local header first
storage.Write(buf, iLocalSize, true);
// it was only local information, use CZipArchive::SetExtraField to set the file extra field in the central directory
m_pExtraField.Release();
m_uDiskStart = (WORD)storage.GetCurrentDisk();
m_uOffset = storage.GetPosition() - iLocalSize;
}
// prepare the data before adding a new file
bool CZipFileHeader::PrepareData(int iLevel, bool bExtraHeader, bool bEncrypted)
{
memcpy(m_szSignature, m_gszSignature, 4);
m_uInternalAttr = 0;
m_uVersionNeeded = 0x14; // 20
SetVersion(0x14);
m_uCrc32 = 0;
m_uComprSize = 0;
m_uUncomprSize = 0;
if (iLevel == 0)
m_uMethod = 0;
if ((m_uMethod != Z_DEFLATED) && (m_uMethod != 0))
m_uMethod = Z_DEFLATED;
m_uFlag = 0;
if (m_uMethod == Z_DEFLATED)
switch (iLevel)
{
case 1:
m_uFlag |= 6;
break;
case 2:
m_uFlag |= 4;
break;
case 8:
case 9:
m_uFlag |= 2;
break;
}
if (bExtraHeader)
m_uFlag |= 8; // data descriptor present
if (bEncrypted)
{
m_uComprSize = ENCR_HEADER_LEN; // encrypted header
m_uFlag |= 9; // encrypted file
}
return !(m_pszComment.GetSize() > USHRT_MAX || m_pszFileName.GetSize() > USHRT_MAX
|| m_pExtraField.GetSize() > USHRT_MAX);
}
void CZipFileHeader::GetCrcAndSizes(char * pBuffer)
{
memcpy(pBuffer, &m_uCrc32, 4);
memcpy(pBuffer + 4, &m_uComprSize, 4);
memcpy(pBuffer + 8, &m_uUncomprSize, 4);
}
DWORD CZipFileHeader::GetSize()
{
return FILEHEADERSIZE + GetExtraFieldSize() + GetFileNameSize() + GetCommentSize();
}
bool CZipFileHeader::IsEncrypted()
{
return (m_uFlag & (WORD) 1) != 0;
}
bool CZipFileHeader::IsDataDescr()
{
return (m_uFlag & (WORD) 8) != 0;
}
bool CZipFileHeader::SetComment(LPCTSTR lpszComment)
{
return CZipArchive::WideToSingle(lpszComment, m_pszComment) != -1;
}
CZipString CZipFileHeader::GetComment()
{
CZipString temp;
CZipArchive::SingleToWide(m_pszComment, temp);
return temp;
}
bool CZipFileHeader::SetFileName(LPCTSTR lpszFileName)
{
return CZipArchive::WideToSingle(lpszFileName, m_pszFileName) != -1;
}
CZipString CZipFileHeader::GetFileName()
{
CZipString temp;
CZipArchive::SingleToWide(m_pszFileName, temp);
return temp;
}
bool CZipFileHeader::IsDirectory()
{
return ZipPlatform::IsDirectory(GetSystemAttr());
}
DWORD CZipFileHeader::GetSystemAttr()
{
return ZipCompatibility::ConvertToSystem(m_uExternalAttr, GetSystemCompatibility(), ZipPlatform::GetSystemID());
}
void CZipFileHeader::SetSystemAttr(DWORD uAttr)
{
m_uExternalAttr = ZipCompatibility::ConvertToSystem(uAttr, ZipPlatform::GetSystemID(), GetSystemCompatibility());
}

View File

@@ -0,0 +1,305 @@
/**
* \file ZipFileHeader.h
* Interface for the CZipFileHeader class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_FILEHEADER_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_)
#define AFX_FILEHEADER_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipstorage.h"
#include "zipautobuffer.h"
#include "sys\types.h"
#include "zipcompatibility.h"
/**
Representation of a single file stored in the zip archive.
Modify all the class attributes BEFORE adding a file to and archive
( using CZipArchive::OpenNewFile ).
It is not possible to modify the data of the existing files in the archive
(it would mean updating all the information in the local headers
and the offsets would be changed as well when the filename would changed its size)
*/
ZEXPORT class CZipFileHeader
{
friend class CZipCentralDir;
friend class CZipArchive;
friend void ZipCompatibility::FileNameUpdate(CZipFileHeader&, bool);
public:
CZipFileHeader();
virtual ~CZipFileHeader();
//
/**
Change slash to backslash or vice-versa in #m_pszFileName.
\param bWindowsStyle
if \c true, change slash to backslash; otherwise vice versa;
*/
/**
\return the filename size in characters (without NULL)
*/
WORD GetFileNameSize(){return (WORD)m_pszFileName.GetSize();}
/**
\return the comment size in characters (without NULL)
*/
WORD GetCommentSize(){return (WORD)m_pszComment.GetSize();}
/**
\return the extra field size in characters
*/
WORD GetExtraFieldSize(){return (WORD)m_pExtraField.GetSize();}
/**
\return the filename
*/
CZipString GetFileName();
/**
Set the filename
\param lpszFileName
\return
\c true, if conversion from UNICODE to single byte was successful
(or if there was no conversion needed or possible); otherwise \c false;
*/
bool SetFileName(LPCTSTR lpszFileName);
/**
\return the file comment
*/
CZipString GetComment();
/**
Set the file comment.
\param lpszComment
\return
\c true, if conversion from UNICODE to single byte was successful
(or if there was no conversion needed or possible); otherwise \c false;
*/
bool SetComment(LPCTSTR lpszComment);
/**
\return \c true if the data descriptor is present
*/
bool IsDataDescr();
/**
\return \c if the file is encrypted ( a password is needed to extract this file)
\see CZipArchive::SetPassword
*/
bool IsEncrypted();
char m_szSignature[4]; ///< central file header signature
WORD m_uVersionMadeBy; ///< version made by and system compatibility
WORD m_uVersionNeeded; ///< version needed to extract
WORD m_uFlag; ///< general purpose bit flag
WORD m_uMethod; ///< compression method
WORD m_uModTime; ///< last mod file time
WORD m_uModDate; ///< last mod file date
DWORD m_uCrc32; ///< crc-32
DWORD m_uComprSize; ///< compressed size
DWORD m_uUncomprSize; ///< uncompressed size
// filename length 2 bytes
// WORD m_uFileNameSize;
// extra field length 2 bytes
// WORD m_uExtraFieldSize;
// file comment length 2 bytes
// WORD m_uCommentSize;
WORD m_uDiskStart; ///< disk number start
WORD m_uInternalAttr; ///< internal file attributes
protected:
DWORD m_uExternalAttr; ///< external file attributes
public:
DWORD m_uOffset; ///< relative offset of local header
CZipAutoBuffer m_pExtraField; ///< extra field (variable size)
static char m_gszSignature[]; ///< central file header signature
static char m_gszLocalSignature[]; ///< local file header signature
/**
Set #m_uModDate, #m_uModTime
(file modification time)
\param const time_t& ttime
\see GetTime
*/
void SetTime(const time_t& ttime);
/**
\return the modification time
\see SetTime
*/
time_t GetTime();
/**
\return the total size of the structure as stored in the central directory
*/
DWORD GetSize();
/**
\return the system compatibility of the current file as
the one of ZipCompatibility::ZipPlatforms values;
usually the same as CZipArchive::GetSystemComatibility.
Software can use this information e.g. to determine the line
record format for text files etc.
ZipArchive library uses it to perform a proper attributes conversion.
\see CZipArchive::GetSystemComatibility
\see ZipPlatform::GetSystemID
*/
int GetSystemCompatibility()
{
return (m_uVersionMadeBy & 0xFF00) >> 8;
}
/**
\return the attributes of the file converted to the current system compatible value
\note Throws exception if the archive system or the current system
is not supported by the ZipArchive library.
*/
DWORD GetSystemAttr();
/**
\return \c true, if this object represents a directory; otherwise \c false;
*/
bool IsDirectory();
protected:
/**
Set the system compatibility of the file.
\param iSystemID
one of ZipCompatibility::ZipPlatforms values
\see CZipArchive::GetSystemCompatibility
*/
void SetSystemCompatibility(int iSystemID)
{
m_uVersionMadeBy &= 0x00FF;
m_uVersionMadeBy |= (iSystemID << 8);
}
/**
Set the system attributes
if you wish to set the attributes of this structure use CZipArchive::SetFileHeaderAttr()
\param uAttr
attibutes to set
\note Throws exceptions if the archive system or the current system
is not supported by the ZipArchive library.
\see CZipArchive::SetFileHeaderAttr
\see GetSystemAttr
\see SetSystemCompatibility
*/
void SetSystemAttr(DWORD uAttr);
/**
Set the version made by number.
\param uVersion
*/
void SetVersion(WORD uVersion)
{
if ((m_uVersionMadeBy & 0x00FF) != (uVersion & 0x00FF))
{
m_uVersionMadeBy &= 0xFF00;
m_uVersionMadeBy |= (uVersion & 0x00FF);
}
}
/**
a filename
*/
CZipAutoBuffer m_pszFileName;
/**
a file comment
*/
CZipAutoBuffer m_pszComment;
/**
Fill the buffer with the current values of crc and compressed and
uncompressed sizes of the file.
\param pBuffer
*/
void GetCrcAndSizes(char* pBuffer);
/**
Check whether the actual values of crc and compressed and
uncompressed sizes of the file are the same as defined in
the file header.
\param pBuf
buffer with the mentioned data
\return \c true if they are the same; otherwise \c false;
*/
bool CheckCrcAndSizes(char* pBuf);
/**
Prepare the data for the class while adding a new file.
Called by CZipArchive::OpenNewFile
\param iLevel
a compression level
\param bExtraHeader
\c true, if the data descriptor will be present
\param bEncrypted
\c true, if the file will be encrypted
\return \c true if the sizes of the filename, extra field and comments
does not exceed \c unsigned \c short maximum value; otherwise \c false;
*/
bool PrepareData(int iLevel, bool bExtraHeader, bool bEncrypted);
/**
Write the local file header to the \e storage
\param storage
\note Throws exceptions.
*/
void WriteLocal(CZipStorage& storage);
/**
Read the file header from the central directory record from \e pStorage.
\param *pStorage
\return \c true if the whole file header is on one disk in
a multi-disk archive; otherwise \c false;
\note Throws exceptions.
*/
bool Read(CZipStorage *pStorage);
/**
Read the local file header from \e pStorage and check for consistency.
\param *pStorage
\param iLocExtrFieldSize
receives local extra field size
\return \c false, if something goes wrong; otherwise \c true;
\note Throws exceptions.
*/
bool ReadLocal(CZipStorage *pStorage, WORD& iLocExtrFieldSize);
/**
Write the file header to \e pStorage.
\param *pStorage
\return the size of the file header
\note Throws exceptions.
*/
DWORD Write(CZipStorage *pStorage);
};
#endif // !defined(AFX_FILEHEADER_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_)

View File

@@ -0,0 +1,78 @@
/**
* \file ZipFileMapping.h
* Interface for the CZipFileMapping class.
*
* \author Tadeusz Dracz
*
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_AUTOHANDLE_H__D68326EA_D7FA_4792_AB1F_68D09533E399__INCLUDED_)
#define AFX_AUTOHANDLE_H__D68326EA_D7FA_4792_AB1F_68D09533E399__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
namespace ziparchv
{
struct CZipFileMapping
{
CZipFileMapping()
{
m_hFileMap = NULL;
m_pFileMap = NULL;
}
bool CreateMapping(HANDLE hFile)
{
if (!hFile)
return false;
m_hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
0, 0, _T("ZipArchive Mapping File"));
if (!m_hFileMap)
return false;
// Get pointer to memory representing file
m_pFileMap = MapViewOfFile(m_hFileMap, FILE_MAP_WRITE, 0, 0, 0);
return (m_pFileMap != NULL);
}
void RemoveMapping()
{
if (m_pFileMap)
{
UnmapViewOfFile(m_pFileMap);
m_pFileMap = NULL;
}
if (m_hFileMap)
{
CloseHandle(m_hFileMap);
m_hFileMap = NULL;
}
}
~CZipFileMapping()
{
RemoveMapping();
}
char* GetMappedMemory()
{
return reinterpret_cast<char*> (m_pFileMap);
}
protected:
HANDLE m_hFileMap;
LPVOID m_pFileMap;
};
}
#endif // !defined(AFX_AUTOHANDLE_H__D68326EA_D7FA_4792_AB1F_68D09533E399__INCLUDED_)

View File

@@ -0,0 +1,33 @@
// ZipInternalInfo.cpp: implementation of the CZipInternalInfo class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipinternalinfo.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CZipInternalInfo::CZipInternalInfo()
{
m_iBufferSize = 16384;
}
CZipInternalInfo::~CZipInternalInfo()
{
}
void CZipInternalInfo::Init()
{
m_pBuffer.Allocate(m_iBufferSize);
}

View File

@@ -0,0 +1,60 @@
/**
* \file ZipInternalInfo.h
* Interface for the CZipInternalInfo structure.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_)
#define AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipautobuffer.h"
#include "zlib.h"
/**
The purpose of this structure is to hold the data that allow communication
with the zlib library
*/
ZEXPORT struct CZipInternalInfo
{
CZipInternalInfo();
virtual ~CZipInternalInfo();
/**
Allocate internal buffer of m_iBufferSize size
*/
void Init();
z_stream m_stream; ///< zlib library data stream
DWORD m_uUncomprLeft; ///< bytes left to uncompress
DWORD m_uComprLeft; ///< bytes left to decompress
DWORD m_uCrc32; ///< crc32 file control value
/**
The size of the buffer used in decompressing data.
Set before opening the archive.
It is usually set with CZipArchive::SetAdvanced
(specify this value as the second argument).
\see CZipArchive::SetAdvanced
*/
DWORD m_iBufferSize;
/**
This buffer caches data during compression and decompression.
*/
CZipAutoBuffer m_pBuffer;
};
#endif // !defined(AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_)

View File

@@ -0,0 +1,99 @@
// ZipMemFile.cpp: implementation of the CZipMemFile class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipmemfile.h"
#include "zipexception.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void CZipMemFile::Grow(long nGrowTo)
{
if (m_nBufSize < (UINT)nGrowTo)
{
if (m_nGrowBy == 0)
CZipException::Throw(CZipException::memError);
long nNewSize = m_nBufSize;
while (nNewSize < nGrowTo)
nNewSize += m_nGrowBy;
BYTE* lpNew;
if (m_lpBuf)
lpNew = (BYTE*)realloc((void*) m_lpBuf, nNewSize);
else
lpNew = (BYTE*)malloc(nNewSize);
if (!lpNew)
CZipException::Throw(CZipException::memError);
m_nBufSize = nNewSize;
m_lpBuf = lpNew;
}
}
void CZipMemFile::SetLength(long nNewLen)
{
if (m_nBufSize < (UINT)nNewLen)
Grow(nNewLen);
else
m_nPos = nNewLen;
m_nDataSize = nNewLen;
}
UINT CZipMemFile::Read(void *lpBuf, UINT nCount)
{
if (m_nPos > m_nDataSize)
return 0;
UINT nToRead = (m_nPos + nCount > m_nDataSize) ? m_nDataSize - m_nPos : nCount;
memcpy(lpBuf, m_lpBuf + m_nPos, nToRead);
m_nPos += nToRead;
return nToRead;
}
void CZipMemFile::Write(const void *lpBuf, UINT nCount)
{
if (!nCount)
return;
if (m_nPos + nCount > m_nBufSize)
Grow(m_nPos + nCount);
memcpy(m_lpBuf + m_nPos, lpBuf, nCount);
m_nPos += nCount;
if (m_nPos > m_nDataSize)
m_nDataSize = m_nPos;
}
long CZipMemFile::Seek(long lOff, int nFrom)
{
long lNew = m_nPos;
if (nFrom == CZipAbstractFile::begin)
lNew = lOff;
else if (nFrom == CZipAbstractFile::current)
lNew += lOff;
else if (nFrom == CZipAbstractFile::end)
lNew = m_nDataSize + lOff;
else
return lNew;
if (lNew< 0)
CZipException::Throw(CZipException::memError);
m_nPos = lNew;
return lNew;
}
bool CZipMemFile::Open(LPCTSTR lpszFileName, UINT openFlags, bool shareMode)
{
return 1;
}

View File

@@ -0,0 +1,103 @@
/**
* \file ZipMemFile.h
* Interface for the CZipMemFile class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPMEMFILE_H__EA73AB25_6B51_4C5E_8D78_BAC95812598F__INCLUDED_)
#define AFX_ZIPMEMFILE_H__EA73AB25_6B51_4C5E_8D78_BAC95812598F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipabstractfile.h"
#include "zipstring.h"
/**
A memory buffer which behaves like a physical file.
Automatically grows when necessary
*/
ZEXPORT class CZipMemFile : public CZipAbstractFile
{
protected:
UINT m_nGrowBy, m_nPos;
UINT m_nBufSize, m_nDataSize;
BYTE* m_lpBuf;
bool m_bAutoDelete;
void Free()
{
if (m_lpBuf)
{
free(m_lpBuf);
m_lpBuf = NULL;
}
}
void Init()
{
m_nGrowBy = m_nPos = 0;
m_nBufSize = m_nDataSize = 0;
m_lpBuf = NULL;
}
void Grow(long nBytes);
public:
bool IsClosed() { return m_lpBuf == NULL;}
void Flush(){}
long Seek(long lOff, int nFrom);
DWORD GetLength() {return m_nDataSize;}
void Write(const void* lpBuf, UINT nCount);
UINT Read(void* lpBuf, UINT nCount);
void SetLength(long nNewLen);
CZipString GetFilePath() {return _T("");}
bool Open(LPCTSTR lpszFileName, UINT openFlags, bool shareMode);
CZipMemFile(long nGrowBy = 1024)
{
Init();
m_nGrowBy = nGrowBy;
m_bAutoDelete = true;
}
CZipMemFile(BYTE* lpBuf, UINT nBufSize, long nGrowBy = 0)
{
Attach(lpBuf, nBufSize, nGrowBy);
}
long GetPosition(){ return m_nPos;}
void Attach(BYTE* lpBuf, UINT nBufSize, long nGrowBy = 0)
{
Close();
m_lpBuf = lpBuf;
m_nGrowBy = nGrowBy;
m_nBufSize = nBufSize;
m_nDataSize = nGrowBy == 0 ? nBufSize : 0;
m_bAutoDelete = false;
}
BYTE* Detach()
{
BYTE* b = m_lpBuf;
Init();
return b;
}
void Close()
{
if (m_bAutoDelete)
Free();
Init();
}
virtual ~CZipMemFile(){Close();}
};
#endif // !defined(AFX_ZIPMEMFILE_H__EA73AB25_6B51_4C5E_8D78_BAC95812598F__INCLUDED_)

View File

@@ -251,7 +251,7 @@ if (iReturn) {
szTempString =(LPCTSTR)fh.GetFileName();
szFileNameInZip=(const char *)szTempString;
pItem=hb_itemPutC(NULL,(char *)szFileNameInZip);
hb_itemArrayPut(pTempArray,filePos,pItem);
hb_arraySet(pTempArray,filePos,pItem);
hb_itemRelease(pItem);
#if defined(__WIN32__)
szAttr[0] = uAttr & FILE_ATTRIBUTE_READONLY ? _T('r') : _T('-');
@@ -264,29 +264,29 @@ if (iReturn) {
if (fh.m_uUncomprSize>0) {
pItem=hb_itemPutNL(NULL,fh.m_uUncomprSize);
hb_itemArrayPut(pTempArray,Lenght,pItem);
hb_arraySet(pTempArray,Lenght,pItem);
hb_itemRelease(pItem);
pItem=hb_itemPutNL(NULL,fh.m_uComprSize);
hb_itemArrayPut(pTempArray,Size,pItem);
hb_arraySet(pTempArray,Size,pItem);
hb_itemRelease(pItem);
iRatio=100-((fh.m_uComprSize*100)/fh.m_uUncomprSize);
if (iRatio <0){
iRatio=0;
}
pItem=hb_itemPutNL(NULL,iRatio);
hb_itemArrayPut(pTempArray,Ratio,pItem);
hb_arraySet(pTempArray,Ratio,pItem);
hb_itemRelease(pItem);
}
else {
pItem=hb_itemPutNL(NULL,fh.m_uUncomprSize);
hb_itemArrayPut(pTempArray,Lenght,pItem);
hb_arraySet(pTempArray,Lenght,pItem);
hb_itemRelease(pItem);
pItem=hb_itemPutNL(NULL,fh.m_uComprSize);
hb_itemArrayPut(pTempArray,Size,pItem);
hb_arraySet(pTempArray,Size,pItem);
hb_itemRelease(pItem);
iRatio=0;
pItem=hb_itemPutNL(NULL,iRatio);
hb_itemArrayPut(pTempArray,Ratio,pItem);
hb_arraySet(pTempArray,Ratio,pItem);
hb_itemRelease(pItem);
}
#if defined(__WIN32__)
@@ -310,18 +310,18 @@ if (iReturn) {
}
}
pItem=hb_itemPutC(NULL,szMethod);
hb_itemArrayPut(pTempArray,Method,pItem);
hb_arraySet(pTempArray,Method,pItem);
hb_itemRelease(pItem);
sprintf(szCRC,"%8.8lx\n",(uLong)fh.m_uCrc32);
pItem=hb_itemPutCL(NULL,szCRC,8);
hb_itemArrayPut(pTempArray,Crc32,pItem);
hb_arraySet(pTempArray,Crc32,pItem);
hb_itemRelease(pItem);
pItem=hb_itemPutD(NULL,(long) (fh.m_uModDate >> 9) +1980 , (long) ((fh.m_uModDate & ~0xFE00) >> 5) ,(long)fh.m_uModDate & ~0xFFE0);
/* (long)file_info.tmu_date.tm_year ,(long)file_info.tmu_date.tm_mon + 1,(long)file_info.tmu_date.tm_mday);*/
hb_itemArrayPut(pTempArray,Date,pItem);
hb_arraySet(pTempArray,Date,pItem);
hb_itemRelease(pItem);
theTime=fh.GetTime();
SzTime= localtime(&theTime);
@@ -335,12 +335,12 @@ if (iReturn) {
}
}
pItem=hb_itemPutCL(NULL,szTime,5);
hb_itemArrayPut(pTempArray,Time,pItem);
hb_arraySet(pTempArray,Time,pItem);
hb_itemRelease(pItem);
pItem=hb_itemPutCL(NULL,szAttr,5);
hb_itemArrayPut(pTempArray,Attr,pItem);
hb_arraySet(pTempArray,Attr,pItem);
hb_itemRelease(pItem);
hb_itemArrayPut(pArray,uiCount+1,pTempArray);
hb_arraySet(pArray,uiCount+1,pTempArray);
hb_itemRelease(pTempArray);
}
@@ -349,7 +349,7 @@ if (iReturn) {
CZipString szTempString=(LPCTSTR)fh.GetFileName();
szFileNameInZip=(const char *)szTempString;
pItem=hb_itemPutC(NULL,(char *) szFileNameInZip);
hb_itemArrayPut(pArray,uiCount+1,pItem);
hb_arraySet(pArray,uiCount+1,pItem);
hb_itemRelease(pItem);
}
}

View File

@@ -0,0 +1,73 @@
// ZipPathComponent.cpp: implementation of the CZipPathComponent class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zippathcomponent.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CZipPathComponent::~CZipPathComponent()
{
}
void CZipPathComponent::SetFullPath(const CZipString& szFullPath)
{
TCHAR szDrive[_MAX_DRIVE];
TCHAR szDir[_MAX_DIR];
TCHAR szFname[_MAX_FNAME];
TCHAR szExt[_MAX_EXT];
m_szPrefix.Empty();
CZipString szTempPath = szFullPath;
LPCTSTR szWinUNC = {_T("\\\\?\\UNC\\")};
LPCTSTR szUnic = {_T("\\\\?\\")};
LPCTSTR szUNC = {_T("\\\\")};
if (szTempPath.Left(8) == szWinUNC) // UNC path meeting Windows File Name Conventions required for some functions
{
szTempPath = szTempPath.Mid(8);
m_szPrefix = szWinUNC;
}
else if (szTempPath.Left(4) == szUnic) // Unicode path
{
szTempPath = szTempPath.Mid(4);
m_szPrefix = szUnic;
}
else if (szTempPath.Left(2) == szUNC) // UNC path
m_szPrefix = szUNC;
_tsplitpath(szTempPath, szDrive , szDir, szFname, szExt);
m_szDrive = szDrive;
m_szDirectory = szDir;
m_szDirectory.TrimLeft(m_cSeparator);
m_szDirectory.TrimRight(m_cSeparator);
SetExtension(szExt);
m_szFileName = szFname;
}
CZipString CZipPathComponent::GetNoDrive()
{
CZipString szPath = m_szDirectory;
CZipString szFileName = GetFullFileName();
if (!szFileName.IsEmpty() && !szPath.IsEmpty())
szPath += m_cSeparator;
szPath += szFileName;
return szPath;
}

View File

@@ -0,0 +1,160 @@
/**
* \file ZipPathComponent.h
* Interface for the CZipPathComponent class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPPATHCOMPONENT_H__9B222C08_AD11_4138_96CC_1237511E3E37__INCLUDED_)
#define AFX_ZIPPATHCOMPONENT_H__9B222C08_AD11_4138_96CC_1237511E3E37__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "zipstring.h"
/**
A class splitting a file path into components.
*/
class CZipPathComponent
{
public:
CZipPathComponent(){}
virtual ~CZipPathComponent();
static TCHAR m_cSeparator; ///< A system - specific default path separator. Defined in ZipPlatform.cpp.
/**
Append a path separator to \e szPath if it is not already there.
\param szPath
*/
static void AppendSeparator(CZipString& szPath)
{
// szPath.TrimRight(m_cSeparator);
szPath.TrimRight(_T("\\/"));
szPath += m_cSeparator;
}
/**
Construct the object and set a path.
\param szFullPath
the full path of the file
\see SetFullPath
*/
CZipPathComponent(const CZipString& szFullPath)
{
SetFullPath(szFullPath);
}
// full path of the file (not a directory alone)
/**
Set the path.
\param szFullPath
a full path to the file (including a filename - the last element in the
path is assumed to be a filename)
*/
void SetFullPath(const CZipString& szFullPath);
/**
\return the filename (without an extension)
*/
CZipString GetFileName() { return m_szFileName;}
/**
Set the filename only (without extension).
\param szFileName
\return
*/
void SetFileName(const CZipString& szFileName) { m_szFileName = szFileName;}
/**
Set the extension alone.
\param lpszExt
may but not have to contain a dot at the beginning
*/
void SetExtension(LPCTSTR lpszExt)
{
m_szFileExt = lpszExt;
m_szFileExt.TrimLeft(_T('.'));
}
/**
\return the file extension without a dot
*/
CZipString GetFileExt() { return m_szFileExt;}
/**
\return the drive (no path separator at the end)
*/
CZipString GetFileDrive() { return m_szDrive;}
/**
\return the full path without the drive (no separator at the beginning)
*/
CZipString GetNoDrive();
/**
\return the filename including the extension
*/
CZipString GetFullFileName()
{
CZipString szFullFileName = m_szFileName;
if (!m_szFileExt.IsEmpty())
{
szFullFileName += _T(".");
szFullFileName += m_szFileExt;
}
return szFullFileName;
}
/**
\return the full path of the file (including the filename)
*/
CZipString GetFullPath()
{
CZipString szFullPath = GetFilePath();
CZipString szFileName = GetFullFileName();
if (!szFileName.IsEmpty())
{
szFullPath += m_cSeparator;
szFullPath += szFileName;
}
return szFullPath;
}
/**
\return the path of the file (without the separator at the end)
*/
CZipString GetFilePath()
{
CZipString szDrive = m_szDrive;
CZipString szDir = m_szDirectory;
if (!szDrive.IsEmpty() && !szDir.IsEmpty())
szDrive += m_cSeparator;
return m_szPrefix + szDrive + szDir;
}
protected:
/**
\name Path components
*/
//@{
CZipString m_szDirectory, ///< a directory(ies) (one or more) without the path separators at the end and the beginning
m_szFileName, ///< a filename without an extension
m_szFileExt, ///< a file extension without a dot
m_szDrive, ///< a drive (if the system path standard uses it) without a path separator at the end
m_szPrefix; ///< a prefix (e.g. for the UNC path or Unicode path under Windows)
//@}
};
#endif // !defined(AFX_ZIPPATHCOMPONENT_H__9B222C08_AD11_4138_96CC_1237511E3E37__INCLUDED_)

View File

@@ -0,0 +1,270 @@
// ZipPlatform.cpp: implementation of the ZipPlatform namespace.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipplatform.h"
#include "zipfileheader.h"
#include "zipexception.h"
#include "zipautobuffer.h"
#include <sys/stat.h>
#if defined _MSC_VER && !defined __BORLANDC__ /*_MSC_VER may be defined in Borland after converting the VC project */
#include <sys/utime.h>
#else
#include <utime.h>
#endif
#include <direct.h>
#include <io.h>
#include <time.h>
#include "zippathcomponent.h"
TCHAR CZipPathComponent::m_cSeparator = _T('\\');
#include "zipcompatibility.h"
#ifndef _UTIMBUF_DEFINED
#define _utimbuf utimbuf
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DWORD ZipPlatform::GetDeviceFreeSpace(LPCTSTR lpszPath)
{
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
CZipPathComponent zpc (lpszPath);
if (!GetDiskFreeSpace(
zpc.GetFileDrive(),
&SectorsPerCluster,
&BytesPerSector,
&NumberOfFreeClusters,
&TotalNumberOfClusters))
return 0;
__int64 total = SectorsPerCluster * BytesPerSector * NumberOfFreeClusters;
return (DWORD)total;
}
bool ZipPlatform::GetCurrentDirectory(CZipString& sz)
{
DWORD i = ::GetCurrentDirectory(0, NULL);
if (!i)
return false;
TCHAR* pBuf = new TCHAR[i];
bool b = true;
if (!::GetCurrentDirectory(i, pBuf))
b = false;
else
sz = pBuf;
delete[] pBuf;
return b;
}
bool ZipPlatform::SetFileAttr(LPCTSTR lpFileName, DWORD uAttr)
{
return ::SetFileAttributes(lpFileName, uAttr) != 0;
}
bool ZipPlatform::GetFileAttr(LPCTSTR lpFileName, DWORD& uAttr)
{
// not using MFC due to MFC bug (attr is one byte there)
DWORD temp = ::GetFileAttributes(lpFileName);
if (temp == -1)
return false;
uAttr = temp;
return true;
}
bool ZipPlatform::GetFileModTime(LPCTSTR lpFileName, time_t & ttime)
{
#if defined _MSC_VER && !defined __BORLANDC__ /*_MSC_VER may be defined in Borland after converting the VC project */
struct _stat st;
if (_tstat(lpFileName, &st) != 0)
#else
struct stat st;
if (stat(lpFileName, &st) != 0)
#endif
return false;
ttime = st.st_mtime;
return true;
}
bool ZipPlatform::SetFileModTime(LPCTSTR lpFileName, time_t ttime)
{
struct _utimbuf ub;
ub.actime = time(NULL);
ub.modtime = ttime;
return _tutime(lpFileName, &ub) == 0;
}
bool ZipPlatform::ChangeDirectory(LPCTSTR lpDirectory)
{
return _tchdir(lpDirectory) == 0; // returns 0 if ok
}
int ZipPlatform::FileExists(LPCTSTR lpszName)
{
if (_taccess(lpszName, 0) == 0)
{
if (DirectoryExists(lpszName))
return -1;
return 1;
}
else
return 0;
}
ZIPINLINE bool ZipPlatform::IsDriveRemovable(LPCTSTR lpszFilePath)
{
CZipPathComponent zpc(lpszFilePath);
return ::GetDriveType(zpc.GetFileDrive()) == DRIVE_REMOVABLE;
}
ZIPINLINE bool ZipPlatform::SetVolLabel(LPCTSTR lpszPath, LPCTSTR lpszLabel)
{
CZipPathComponent zpc(lpszPath);
CZipString szDrive = zpc.GetFileDrive();
CZipPathComponent::AppendSeparator(szDrive);
return ::SetVolumeLabel(szDrive, lpszLabel) != 0;
}
ZIPINLINE void ZipPlatform::AnsiOem(CZipAutoBuffer& buffer, bool bAnsiToOem)
{
if (bAnsiToOem)
CharToOemBuffA(buffer, buffer, buffer.GetSize());
else
OemToCharBuffA(buffer, buffer, buffer.GetSize());
}
ZIPINLINE void ZipPlatform::RemoveFile(LPCTSTR lpszFileName)
{
if (!::DeleteFile((LPTSTR)lpszFileName))
CZipException::Throw(CZipException::notRemoved, lpszFileName);
}
ZIPINLINE void ZipPlatform::RenameFile( LPCTSTR lpszOldName, LPCTSTR lpszNewName )
{
if (!::MoveFile((LPTSTR)lpszOldName, (LPTSTR)lpszNewName))
CZipException::Throw(CZipException::notRenamed, lpszOldName);
}
ZIPINLINE bool ZipPlatform::IsDirectory(DWORD uAttr)
{
return (uAttr & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
ZIPINLINE bool ZipPlatform::CreateDirectory(LPCTSTR lpDirectory)
{
return ::CreateDirectory(lpDirectory, NULL) != 0;
}
// ZIPINLINE DWORD ZipPlatform::GetDefaultAttributes()
// {
// return FILE_ATTRIBUTE_ARCHIVE;
// }
ZIPINLINE int ZipPlatform::GetSystemID()
{
return ZipCompatibility::zcDosFat;
}
#ifdef _UNICODE
int ZipPlatform::WideToSingle(LPCTSTR lpWide, CZipAutoBuffer &szSingle)
{
size_t wideLen = wcslen(lpWide);
if (wideLen == 0)
{
szSingle.Release();
return 0;
}
// iLen does not include terminating character
int iLen = WideCharToMultiByte(CP_ACP,0, lpWide, wideLen, szSingle,
0, NULL, NULL);
if (iLen > 0)
{
szSingle.Allocate(iLen, true);
iLen = WideCharToMultiByte(CP_ACP,0, lpWide , wideLen, szSingle,
iLen, NULL, NULL);
ASSERT(iLen != 0);
}
else // here it means error
{
szSingle.Release();
iLen --;
}
return iLen;
}
int ZipPlatform::SingleToWide(const CZipAutoBuffer &szSingle, CZipString& szWide)
{
int singleLen = szSingle.GetSize();
// iLen doesn't include terminating character
int iLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSingle.GetBuffer(), singleLen, NULL, 0);
if (iLen > 0)
{
iLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSingle.GetBuffer(), singleLen,
szWide.GetBuffer(iLen) , iLen);
szWide.ReleaseBuffer(iLen);
ASSERT(iLen != 0);
}
else
{
szWide.Empty();
iLen --; // return -1
}
return iLen;
}
#endif
#ifndef _MFC_VER
#include <io.h>
#include <share.h>
bool ZipPlatform::TruncateFile(int iDes, DWORD iSize)
{
int ret = chsize(iDes, iSize);
return ret != -1;
}
int ZipPlatform::OpenFile(LPCTSTR lpszFileName, UINT iMode, int iShareMode)
{
switch (iShareMode)
{
case (CZipFile::shareDenyWrite & CZipFile::shareDenyRead):
iShareMode = SH_DENYRW;
break;
case (CZipFile::shareDenyRead):
iShareMode = SH_DENYRD;
break;
case (CZipFile::shareDenyWrite):
iShareMode = SH_DENYWR;
break;
default:
iShareMode = SH_DENYNO;
}
return _tsopen(lpszFileName, iMode, iShareMode, S_IREAD | S_IWRITE /*required only when O_CREAT mode*/);
}
bool ZipPlatform::FlushFile(int iDes)
{
return _commit(iDes) == 0;
}
int ZipPlatform::GetFileSystemHandle(int iDes)
{
return _get_osfhandle(iDes);
}
#endif //_MFC_VER

View File

@@ -0,0 +1,164 @@
/**
* \file ZipPlatform.h
* ZipPlatform namespace declaration.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZipPlatform_H__E2FE6343_9D03_4F3C_A1F7_706C9F0ED978__INCLUDED_)
#define AFX_ZipPlatform_H__E2FE6343_9D03_4F3C_A1F7_706C9F0ED978__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CZipFileHeader;
class CZipAutoBuffer;
#include "zipstring.h"
#include "zippathcomponent.h"
#include <sys\types.h>
/**
Interface to the system API.
All functions have a system - specific implementation .
*/
namespace ZipPlatform
{
/**
\return A current system name tag.
May be one of ZipCompatibility::ZipPlatforms values.
\see CZipArchive::GetSystemCompatibility
*/
ZIPINLINE int GetSystemID();
/**
\return the default file attributes for
*/
// DWORD GetDefaultAttributes();
/**
Get the current directory and store it in \e sz
\param sz
\return \c true if successful
*/
/**
Get the free space on the device pointed by \e lpszPath
*/
DWORD GetDeviceFreeSpace(LPCTSTR lpszPath);
/**
\name Various operations on files and directories.
All the functions which are returning a \c bool value,
return \c true when the operation was successful.
*/
//@{
bool GetCurrentDirectory(CZipString& sz);
bool ChangeDirectory(LPCTSTR lpDirectory);
bool SetFileAttr(LPCTSTR lpFileName, DWORD uAttr);
bool GetFileAttr(LPCTSTR lpFileName, DWORD& uAttr);
bool GetFileModTime(LPCTSTR lpFileName, time_t & ttime); ///< get the file modification time
bool SetFileModTime(LPCTSTR lpFileName, time_t ttime); ///< set the file modification time
ZIPINLINE bool CreateDirectory(LPCTSTR lpDirectory);
ZIPINLINE bool SetVolLabel(LPCTSTR lpszPath, LPCTSTR lpszLabel); ///< \c lpszPath may point to a file on the device
bool ForceDirectory(LPCTSTR lpDirectory); ///< create nested directories at once
ZIPINLINE void RemoveFile(LPCTSTR lpszFileName);
ZIPINLINE void RenameFile( LPCTSTR lpszOldName, LPCTSTR lpszNewName );
#ifndef _MFC_VER
bool TruncateFile(int iDes, DWORD iSize);
int OpenFile(LPCTSTR lpszFileName, UINT iMode, int iShareMode);
bool FlushFile(int iDes); ///< flush the file to the disk.
int GetFileSystemHandle(int iDes); ///< return the underlying system handle
#endif
//@}
/**
\param lpszDir
\return \c true, if \e lpszDir directory exists; otherwise \c false;
*/
bool DirectoryExists(LPCTSTR lpszDir);
/**
\param lpszFilePath
may point to a file path or a directory on the device
\return \c true if the drive is removable.
Implemented only on Windows system, in all others always returns \c true.
*/
ZIPINLINE bool IsDriveRemovable(LPCTSTR lpszFilePath);
/**
\param uAttr
attributes value to test
\return \c true if the attributes are the directory attributes
*/
ZIPINLINE bool IsDirectory(DWORD uAttr);
/**
Perform the translation between ANSI and OEM character sets.
\remark
- The conversion is performed only for the zip archives created under Windows platform.
- Windows archiving programs convert a filename to OEM before adding it to the archive.
- OEM conversion only influences the ANSI values above 126, so it
affects only strings containing international characters.
\param buffer
buffer to be translated
\param bAnsiToOem
if \c true, convert ANSI to OEM
if \c false, OEM to ANSI
*/
ZIPINLINE void AnsiOem(CZipAutoBuffer& buffer, bool bAnsiToOem);
/**
Check if the given file or directory exists.
\param lpszName
\return
- -1 if the given file is a directory
- 1 a file
- 0 if there is no such a file
*/
int FileExists(LPCTSTR lpszName);
#ifdef _UNICODE
/**
Convert wide character string to single character string.
\param lpWide
Wide string to convert
\param szSingle
buffer to receive converted string (without the terminating NULL character)
\return
the \e szSingle buffer length, or \c -1 when not succeeded
\note Only in UNICODE version.
*/
int WideToSingle(LPCTSTR lpWide, CZipAutoBuffer &szSingle);
/**
Convert single character string to wide character string.
\param szSingle
single string to convert (no terminating NULL character at the end)
\param szWide
receives the wide string after the conversion
\return \e the length of the string after the conversion (without the NULL character),
or \c -1 when not succeeded
\note Only in UNICODE version.
*/
int SingleToWide(const CZipAutoBuffer &szSingle, CZipString& szWide);
#endif
};
#endif // !defined(AFX_ZipPlatform_H__E2FE6343_9D03_4F3C_A1F7_706C9F0ED978__INCLUDED_)

View File

@@ -0,0 +1,44 @@
// ZipPlatformComm.cpp - functions portable across the systems
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipplatform.h"
using namespace ZipPlatform;
bool ZipPlatform::DirectoryExists(LPCTSTR lpszDir)
{
CZipString sz;
if (!GetCurrentDirectory(sz))
return false;
if (!ChangeDirectory(lpszDir))
return false;
ChangeDirectory(sz);
return true;
}
bool ZipPlatform::ForceDirectory(LPCTSTR lpDirectory)
{
ASSERT(lpDirectory);
CZipString szDirectory = lpDirectory;
szDirectory.TrimRight(CZipPathComponent::m_cSeparator);
CZipPathComponent zpc(szDirectory);
if ((zpc.GetFilePath() == szDirectory) ||
(FileExists(szDirectory) == -1))
return true;
if (!ForceDirectory(zpc.GetFilePath()))
return false;
if (!CreateDirectory(szDirectory))
return false;
return true;
}

View File

@@ -0,0 +1,421 @@
// ZipStorage.cpp: implementation of the CZipStorage class.
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zipstorage.h"
#include "ziparchive.h"
// #include "ZipPathComponent.h"
#include "zipplatform.h"
//////////////////////////////////////////////////////////////////////
// disk spanning objectives:
// - sinature at the first disk at the beginning
// - headers and central dir records not divided between disks
// - each file has a data descriptor preceded by the signature
// (bit 3 set in flag);
char CZipStorage::m_gszExtHeaderSignat[] = {0x50, 0x4b, 0x07, 0x08};
CZipStorage::CZipStorage()
{
m_pCallbackData = m_pChangeDiskFunc = NULL;
m_iWriteBufferSize = 65535;
m_iCurrentDisk = -1;
m_pFile = NULL;
}
CZipStorage::~CZipStorage()
{
}
DWORD CZipStorage::Read(void *pBuf, DWORD iSize, bool bAtOnce)
{
if (iSize == 0)
return 0;
DWORD iRead = 0;
while (!iRead)
{
iRead = m_pFile->Read(pBuf, iSize);
if (!iRead)
if (IsSpanMode())
ChangeDisk(m_iCurrentDisk + 1);
else
ThrowError(CZipException::badZipFile);
}
if (iRead == iSize)
return iRead;
else if (bAtOnce || !IsSpanMode())
ThrowError(CZipException::badZipFile);
while (iRead < iSize)
{
ChangeDisk(m_iCurrentDisk + 1);
UINT iNewRead = m_pFile->Read((char*)pBuf + iRead, iSize - iRead);
if (!iNewRead && iRead < iSize)
ThrowError(CZipException::badZipFile);
iRead += iNewRead;
}
return iRead;
}
void CZipStorage::Open(LPCTSTR szPathName, int iMode, int iVolumeSize)
{
m_pWriteBuffer.Allocate(m_iWriteBufferSize);
m_uBytesInWriteBuffer = 0;
m_bNewSpan = false;
m_pFile = &m_internalfile;
m_bInMemory = false;
if ((iMode == CZipArchive::zipCreate) ||(iMode == CZipArchive::zipCreateSpan)) // create new archive
{
m_iCurrentDisk = 0;
if (iMode == CZipArchive::zipCreate)
{
m_iSpanMode = noSpan;
OpenFile(szPathName, CZipFile::modeCreate | CZipFile::modeReadWrite);
}
else // create disk spanning archive
{
m_bNewSpan = true;
m_iBytesWritten = 0;
if (iVolumeSize <= 0) // pkzip span
{
if (!m_pChangeDiskFunc)
ThrowError(CZipException::noCallback);
if (!ZipPlatform::IsDriveRemovable(szPathName))
ThrowError(CZipException::nonRemovable);
m_iSpanMode = pkzipSpan;
}
else
{
m_iTdSpanData = iVolumeSize;
m_iSpanMode = tdSpan;
}
NextDisk(4, szPathName);
Write(m_gszExtHeaderSignat, 4, true);
}
}
else // open existing
{
OpenFile(szPathName, CZipFile::modeNoTruncate |
((iMode == CZipArchive::zipOpenReadOnly) ? CZipFile::modeRead : CZipFile::modeReadWrite));
// m_uData, m_bAllowModif i m_iSpanMode are automatically set during reading the central dir
m_iSpanMode = iVolumeSize == 0 ? suggestedAuto : suggestedTd;
}
}
void CZipStorage::Open(CZipMemFile& mf, int iMode)
{
m_pWriteBuffer.Allocate(m_iWriteBufferSize);
m_uBytesInWriteBuffer = 0;
m_bNewSpan = false;
m_pFile = &mf;
m_bInMemory = true;
if (iMode == CZipArchive::zipCreate)
{
m_iCurrentDisk = 0;
m_iSpanMode = noSpan;
mf.SetLength(0);
}
else // open existing
{
mf.SeekToBegin();
m_iSpanMode = suggestedAuto;
}
}
int CZipStorage::IsSpanMode()
{
return m_iSpanMode == noSpan ? 0 : (m_bNewSpan ? 1 : -1);
}
void CZipStorage::ChangeDisk(int iNumber)
{
if (iNumber == m_iCurrentDisk)
return;
ASSERT(m_iSpanMode != noSpan);
m_iCurrentDisk = iNumber;
OpenFile(m_iSpanMode == pkzipSpan ? ChangePkzipRead() : ChangeTdRead(),
CZipFile::modeNoTruncate | CZipFile::modeRead);
}
void CZipStorage::ThrowError(int err)
{
CZipException::Throw(err, m_pFile->GetFilePath());
}
bool CZipStorage::OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow)
{
return m_pFile->Open(lpszName, uFlags | CZipFile::shareDenyWrite, bThrow);
}
int CZipStorage::GetCurrentDisk()
{
return m_iCurrentDisk;
}
CZipString CZipStorage::ChangePkzipRead()
{
CZipString szTemp = m_pFile->GetFilePath();
m_pFile->Close();
CallCallback(-1 , szTemp);
return szTemp;
}
CZipString CZipStorage::ChangeTdRead()
{
CZipString szTemp = GetTdVolumeName(m_iCurrentDisk == m_iTdSpanData);
m_pFile->Close();
return szTemp;
}
void CZipStorage::Close(bool bAfterException)
{
if (!bAfterException)
{
Flush();
if ((m_iSpanMode == tdSpan) && (m_bNewSpan))
{
// give to the last volume the zip extension
CZipString szFileName = m_pFile->GetFilePath();
CZipString szNewFileName = GetTdVolumeName(true);
if (!m_bInMemory)
m_pFile->Close();
if (ZipPlatform::FileExists(szNewFileName))
ZipPlatform::RemoveFile(szNewFileName);
ZipPlatform::RenameFile(szFileName, szNewFileName);
}
else
{
if (!m_bInMemory)
m_pFile->Close();
}
}
else
{
if (!m_bInMemory)
m_pFile->Close();
}
m_pWriteBuffer.Release();
m_iCurrentDisk = -1;
m_iSpanMode = noSpan;
m_pFile = NULL;
}
CZipString CZipStorage::GetTdVolumeName(bool bLast, LPCTSTR lpszZipName)
{
CZipString szFilePath = lpszZipName ? lpszZipName : (LPCTSTR)m_pFile->GetFilePath();
CZipPathComponent zpc(szFilePath);
CZipString szExt;
if (bLast)
szExt = _T("zip");
else
szExt.Format(_T("%.3d"), m_iCurrentDisk);
zpc.SetExtension(szExt);
return zpc.GetFullPath();
}
void CZipStorage::NextDisk(int iNeeded, LPCTSTR lpszFileName)
{
Flush();
ASSERT(m_iSpanMode != noSpan);
if (m_iBytesWritten)
{
m_iBytesWritten = 0;
m_iCurrentDisk++;
if (m_iCurrentDisk >= 999)
ThrowError(CZipException::tooManyVolumes);
}
CZipString szFileName;
bool bPkSpan = (m_iSpanMode == pkzipSpan);
if (bPkSpan)
szFileName = lpszFileName ? lpszFileName : (LPCTSTR)m_pFile->GetFilePath();
else
szFileName = GetTdVolumeName(false, lpszFileName);
m_pFile->Close();
if (bPkSpan)
{
int iCode = iNeeded;
while (true)
{
CallCallback(iCode, szFileName);
if (ZipPlatform::FileExists(szFileName))
iCode = -2;
else
{
CZipString label;
label.Format(_T("pkback# %.3d"), m_iCurrentDisk + 1);
if (!ZipPlatform::SetVolLabel(szFileName, label))
iCode = -3;
else if (!OpenFile(szFileName, CZipFile::modeCreate | CZipFile::modeReadWrite, false))
iCode = -4;
else
break;
}
}
m_uCurrentVolSize = GetFreeVolumeSpace();
}
else
{
m_uCurrentVolSize = m_iTdSpanData;
OpenFile(szFileName, CZipFile::modeCreate | CZipFile::modeReadWrite);
}
}
void CZipStorage::CallCallback(int iCode, CZipString szTemp)
{
ASSERT(m_pChangeDiskFunc);
if (!(*m_pChangeDiskFunc)(m_iCurrentDisk + 1, iCode, m_pCallbackData))
CZipException::Throw(CZipException::aborted, szTemp);
}
DWORD CZipStorage::GetFreeVolumeSpace()
{
ASSERT (m_iSpanMode == pkzipSpan);
CZipString szTemp = m_pFile->GetFilePath();
if (szTemp.IsEmpty()) // called once when creating a disk spanning archive
return 0;
else
return ZipPlatform::GetDeviceFreeSpace(szTemp);
}
void CZipStorage::UpdateSpanMode(WORD uLastDisk)
{
m_iCurrentDisk = uLastDisk;
if (uLastDisk)
{
// disk spanning detected
if (m_iSpanMode == suggestedAuto)
m_iSpanMode = ZipPlatform::IsDriveRemovable(m_pFile->GetFilePath()) ?
pkzipSpan : tdSpan;
else
m_iSpanMode = tdSpan;
if (m_iSpanMode == pkzipSpan)
{
if (!m_pChangeDiskFunc)
ThrowError(CZipException::noCallback);
}
else /*if (m_iSpanMode == tdSpan)*/
m_iTdSpanData = uLastDisk; // disk with .zip extension ( the last one)
m_pWriteBuffer.Release(); // no need for this in this case
}
else
m_iSpanMode = noSpan;
}
void CZipStorage::Write(const void *pBuf, DWORD iSize, bool bAtOnce)
{
if (!IsSpanMode())
WriteInternalBuffer((char*)pBuf, iSize);
else
{
// if not at once, one byte is enough free space
DWORD iNeeded = bAtOnce ? iSize : 1;
DWORD uTotal = 0;
while (uTotal < iSize)
{
DWORD uFree;
while ((uFree = VolumeLeft()) < iNeeded)
{
if ((m_iSpanMode == tdSpan) && !m_iBytesWritten && !m_uBytesInWriteBuffer)
// in the tdSpan mode, if the size of the archive is less
// than the size of the packet to be written at once,
// increase once the size of the volume
m_uCurrentVolSize = iNeeded;
else
NextDisk(iNeeded);
}
DWORD uLeftToWrite = iSize - uTotal;
DWORD uToWrite = uFree < uLeftToWrite ? uFree : uLeftToWrite;
WriteInternalBuffer((char*)pBuf + uTotal, uToWrite);
if (bAtOnce)
return;
else
uTotal += uToWrite;
}
}
}
void CZipStorage::WriteInternalBuffer(const char *pBuf, DWORD uSize)
{
DWORD uWritten = 0;
while (uWritten < uSize)
{
DWORD uFreeInBuffer = GetFreeInBuffer();
if (uFreeInBuffer == 0)
{
Flush();
uFreeInBuffer = m_pWriteBuffer.GetSize();
}
DWORD uLeftToWrite = uSize - uWritten;
DWORD uToCopy = uLeftToWrite < uFreeInBuffer ? uLeftToWrite : uFreeInBuffer;
memcpy(m_pWriteBuffer + m_uBytesInWriteBuffer, pBuf + uWritten, uToCopy);
uWritten += uToCopy;
m_uBytesInWriteBuffer += uToCopy;
}
}
DWORD CZipStorage::VolumeLeft()
{
// for pkzip span m_uCurrentVolSize is updated after each flush()
return m_uCurrentVolSize - m_uBytesInWriteBuffer - ((m_iSpanMode == pkzipSpan) ? 0 : m_iBytesWritten);
}
void CZipStorage::Flush()
{
m_iBytesWritten += m_uBytesInWriteBuffer;
if (m_uBytesInWriteBuffer)
{
m_pFile->Write(m_pWriteBuffer, m_uBytesInWriteBuffer);
m_uBytesInWriteBuffer = 0;
}
if (m_iSpanMode == pkzipSpan)
// after writing it is difficult to predict the free space due to
// not completly written clusters, write operation may start from
// the new cluster
m_uCurrentVolSize = GetFreeVolumeSpace();
}
DWORD CZipStorage::GetPosition()
{
return m_pFile->GetPosition() + m_uBytesInWriteBuffer;
}
DWORD CZipStorage::GetFreeInBuffer()
{
return m_pWriteBuffer.GetSize() - m_uBytesInWriteBuffer;
}

View File

@@ -0,0 +1,375 @@
/**
* \file ZipStorage.h
* Interface for the CZipStorage class.
*
* \author Tadeusz Dracz
*/
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_)
#define AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_
#include "zipfile.h"
#include "zipautobuffer.h"
#include "zipstring.h"
#include "zipmemfile.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
typedef bool (*ZIPCALLBACKFUN )(DWORD, int , void* );
/**
Class that represents a physical storage of the archive
*/
ZEXPORT class CZipStorage
{
friend class CZipCentralDir;
public:
/**
The type of the disk spanning archive.
\see CZipArchive::GetSpanMode
*/
enum ZipSpanMode {
noSpan, ///< no disk spanning
pkzipSpan, ///< \ref PKSpan "disk spanning compatible with PKZIP"
tdSpan, ///< \ref TDSpan "TD mode disk spanning archive"
/**
Detect the type automatically.
If the archive is on the removable device assume PKZIP compatible,
otherwise TD mode compatible.
*/
suggestedAuto,
/**
If the disk spanning archive is on the removable device
assume it is TD mode compatible
*/
suggestedTd
};
CZipStorage();
virtual ~CZipStorage();
/**
Open the archive in memory (new or existing).
The parameters are the same as CZipArchive::ZipOpenMode.
\param mf
\param iMode
\note Throws exceptions.
\see CZipArchive::Open(CZipMemFile& , int);
*/
void Open(CZipMemFile& mf, int iMode);
/**
Open or create an archive.
The parameters are the same as CZipArchive::Open.
\param szPathName
\param iMode
\param iVolumeSize
\note Throws exceptions.
\see CZipArchive::Open
*/
void Open(LPCTSTR szPathName, int iMode, int iVolumeSize);
/**
Called only by CZipCentralDir::Read() when opening an existing archive.
\param uLastDisk
the disk number the central directory is on
\note Throws exceptions.
*/
void UpdateSpanMode(WORD uLastDisk);
/**
Write chunk of data to the archive.
\param pBuf
buffer with data
\param iSize
bytes to write
\param bAtOnce
if \c true, the whole data must fit in the current volume,
otherwise the disk change is performed
\note Throws exceptions.
*/
void Write(const void *pBuf, DWORD iSize, bool bAtOnce);
/**
Read chunk of data from the archive.
\param pBuf
buffer to receive data
\param iSize
bytes to read
\param bAtOnce
if \c true, the specified count of bytes must be read from the same
volume (no disk change allowed)
\note Throws exceptions.
*/
DWORD Read(void* pBuf, DWORD iSize, bool bAtOnce);
/**
Return the position in the file, taking into account the bytes in the write buffer.
\note Throws exceptions.
*/
DWORD GetPosition();
/**
Flush the data from the read buffer to the disk.
\note Throws exceptions.
*/
void Flush();
/**
A method used to change disks during writing to the disk spanning archive.
\param iNeeded
no of bytes needed on the disk
\param lpszFileName
the archive filename
\note Throws exceptions.
*/
void NextDisk(int iNeeded, LPCTSTR lpszFileName = NULL);
/**
\return a zero-based number of the current disk
*/
int GetCurrentDisk();
/**
Change the disk during extract operations.
\param iNumber
a zero-based disk number requested
\return
*/
void ChangeDisk(int iNumber);
/**
Detect the span mode.
\return
- -1 - existing disk spanning archive opened
- 0 - no disk spanning archive
- 1 - disk spanning archive in creation
*/
int IsSpanMode();
/**
\param bAfterException
set to \c true after the library has throw an exception.
The simplified mode is used then.
In this case it'll be possible to reuse the object to operate on another
archive, but the current archive file will not be valid anyway.
\note Throws exceptions.
*/
void Close(bool bAfterException);
/**
The size of the write buffer.
Set before opening the archive.
It is usually set with CZipArchive::SetAdvanced
(specify this value as the first argument).
\see CZipArchive::SetAdvanced
*/
int m_iWriteBufferSize;
/**
The User data to be passed to the callback function as the third parameter.
\see \ref callDes "CZipArchive::SetSpanCallback"
*/
void* m_pCallbackData;
/**
The physical archive file (on a storage device).
Not used when opening archive in memory
with Open(CZipMemFile& , int).
*/
CZipFile m_internalfile;
/**
The buffer representing the archive.
It is a physical file or a memory buffer depending on what
method was used to open the archive. In the first case it is
a pointer to #m_internalfile.
\see Open(LPCTSTR, int, int);
\see Open(CZipMemFile& mf, int iMode)
*/
CZipAbstractFile* m_pFile;
/**
Takes one of the values of #ZipSpanMode.
*/
int m_iSpanMode;
/**
A callback function called when there is a need for a disk change
while operating on a #pkzipSpan archive.
\see \ref callDes "CZipArchive::SetSpanCallback"
*/
ZIPCALLBACKFUN m_pChangeDiskFunc;
/**
The signature of the extended header
*/
static char m_gszExtHeaderSignat[];
protected:
/**
Open a physical file.
\param lpszName
the name of the file to open
\param uFlags
file open flags
\param bThrow
if \c true then throw an exception in case of failure
\return \c true if successful
*/
bool OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow = true);
/**
Throw an exception with the given code.
\param err
\see CZipException::Throw
*/
void ThrowError(int err);
/**
Return the number of bytes left on the current volume.
*/
DWORD VolumeLeft();
/**
Write data to the internal buffer.
\param *pBuf
the buffer to copy data from
\param uSize
bytes to write
\note Throws exceptions.
*/
void WriteInternalBuffer(const char *pBuf, DWORD uSize);
/**
\return the number of free bytes on the current removable disk
*/
DWORD GetFreeVolumeSpace();
/**
Call the callback function.
Throw an exception if the callback function returns \c false.
\param iCode
a code to be passed to the callback function
\param szTemp
a string to be used as a filename (the second argument
of CZipException::Throw) when the exception must be thrown
\note Throws exceptions.
\see \ref callDes "CZipArchive::SetSpanCallback"
\see CZipException::Throw
*/
void CallCallback(int iCode, CZipString szTemp);
/**
Construct the name of the volume in #tdSpan mode.
\param bLast
must be \c true if constructing the last volume name (an extension "zip" is given)
\param lpszZipName
the name of the archive
\return
the new volume name
*/
CZipString GetTdVolumeName(bool bLast, LPCTSTR lpszZipName = NULL);
/**
Change the disk in #tdSpan mode
*/
CZipString ChangeTdRead();
/**
Change the disk in #pkzipSpan mode
*/
CZipString ChangePkzipRead();
/**
Used only in \ref TDSpan "TD span mode" . The value it holds depends on the open mode.
- Opened existing disk spanning archive - store the number of the last
disk ( the one with "zip" extension).
- Disk spanning archive in creation - the size of the volume.
\see CZipArchive::Open
\see CZipArchive::GetSpanMode
*/
int m_iTdSpanData;
/**
\return the count bytes left free in the write buffer
*/
DWORD GetFreeInBuffer();
/**
Number of bytes available in the write buffer.
*/
DWORD m_uBytesInWriteBuffer;
/**
The value it holds depends on the open mode:
\par
- #tdSpan : the total size of the current volume
- #pkzipSpan: a free space on the current volume
*/
DWORD m_uCurrentVolSize;
/**
number of bytes left free in the write buffer
*/
DWORD m_uVolumeFreeInBuffer;
/**
Write buffer caching data.
*/
CZipAutoBuffer m_pWriteBuffer;
/**
Used only during disk spanning archive creation.
Tells how many bytes have been written physically to the current volume.
*/
DWORD m_iBytesWritten;
/**
\c True, if the current archive is a new disk spanning archive.
*/
bool m_bNewSpan;
/**
The current disk in a disk spanning archive.
Disk no 0 is the first disk.
*/
int m_iCurrentDisk;
/**
It is set to \e true when an archive is created in memory; \e false otherwise.
*/
bool m_bInMemory;
};
#endif // !defined(AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_)

View File

@@ -0,0 +1,211 @@
// ZipString.cpp : CZipString STL implemmentation
// Part of the ZipArchive library
//
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
#ifndef __ZIPSTRING_H__
#define __ZIPSTRING_H__
#include "stdafx.h"
#if defined(_MSC_VER) && (_MSC_VER > 1100)
#pragma warning( push, 3 ) // STL requrements
#endif
#include <string>
#include <algorithm>
#include <locale>
#include <stdarg.h>
#include <stdio.h>
#ifndef _vsntprintf
#ifdef _UNICODE
#define _vsntprintf _vsnwprintf
#else
#define _vsntprintf _vsnprintf
#endif
#endif
#if defined _MSC_VER && !defined __BORLANDC__/*_MSC_VER may be defined in Borland after converting the VC project */
#define _ZIPUSEFACET(loc, fac) std::use_facet(loc, (fac *)0, true)
#else
#define _ZIPUSEFACET(loc, fac) std::use_facet< fac > (loc)
#endif
typedef std::basic_string<TCHAR> stdbs;
/**
This is not a full MFC - CString replacement.
For now it contains mostly the methods required by ZipArchive library.
*/
class CZipString : public stdbs
{
void TrimInternalL(size_type iPos)
{
if (iPos == npos)
erase ();
if (iPos)
erase(0, iPos);
}
void TrimInternalR(size_type iPos)
{
if (iPos == npos)
erase ();
erase(++iPos);
}
static int zslen(const TCHAR* lpsz)
{
return lpsz ? std::char_traits<TCHAR>::length(lpsz) : 0;
}
public:
CZipString(){}
explicit CZipString (TCHAR ch, int nRepeat = 1):stdbs(nRepeat, ch){}
CZipString( const CZipString& stringSrc ) {assign(stringSrc);}
CZipString( const stdbs& stringSrc ) {assign(stringSrc);}
CZipString( LPCTSTR lpsz ):stdbs(lpsz){}
operator LPCTSTR() const{return c_str();}
int GetLength() const {return size();}
bool IsEmpty() const {return empty();}
void Empty() {erase(begin(), end());}
TCHAR GetAt (int iIndex) const{return at(iIndex);}
TCHAR operator[] (int iIndex) const{return at(iIndex);}
void SetAt( int nIndex, TCHAR ch ) {at(nIndex) = ch;}
LPTSTR GetBuffer(int nMinBufLength)
{
if (size() < nMinBufLength)
resize(nMinBufLength);
return empty() ? const_cast<TCHAR*>(data()) : &(at(0));
}
void ReleaseBuffer( int nNewLength = -1 ) { resize(nNewLength > -1 ? nNewLength : zslen(c_str()));}
void TrimLeft( TCHAR chTarget )
{
TrimInternalL(find_first_not_of(chTarget));
}
void TrimLeft( LPCTSTR lpszTargets )
{
TrimInternalL(find_first_not_of(lpszTargets));
}
void TrimRight( TCHAR chTarget )
{
TrimInternalR(find_last_not_of(chTarget));
}
void TrimRight( LPCTSTR lpszTargets )
{
TrimInternalR(find_last_not_of(lpszTargets));
}
void Format(LPCTSTR lpszFormat, ...)
{
va_list arguments;
va_start (arguments, lpszFormat);
TCHAR* pBuf = NULL;
int iCounter = 1, uTotal = 0;
do
{
int nLen = sizeof(TCHAR) * iCounter*1024;
pBuf = (TCHAR*)realloc((void*)pBuf, nLen);
if (!pBuf)
return;
uTotal = _vsntprintf(pBuf, nLen - 1, lpszFormat, arguments);
if (uTotal == -1 || (uTotal == nLen - 1) ) // for some implementations
{
pBuf[nLen - 1] = _T('\0');
if (iCounter == 7)
break;
}
else
{
pBuf[uTotal] = _T('\0');
break;
}
} while (true);
va_end (arguments);
*this = pBuf;
free(pBuf);
}
void Insert( int nIndex, LPCTSTR pstr ){insert(nIndex, pstr, zslen(pstr));}
void Insert( int nIndex, TCHAR ch ) {insert(nIndex, 1, ch);}
int Delete( int nIndex, int nCount = 1 )
{
int iSize = size();
int iToDelete = iSize < nIndex + nCount ? iSize - nIndex : nCount;
if (iToDelete > 0)
{
erase(nIndex, iToDelete);
iSize -= iToDelete;
}
return iSize;
}
void MakeLower()
{
TCHAR* pBegin = &(at(0));
_ZIPUSEFACET(std::locale(), std::ctype<TCHAR>).tolower(pBegin, pBegin + size());
}
void MakeUpper()
{
TCHAR* pBegin = &(at(0));
_ZIPUSEFACET(std::locale(), std::ctype<TCHAR>).toupper(pBegin, pBegin + size());
}
void MakeReverse()
{
std::reverse(begin(), end());
}
CZipString Left( int nCount ) const { return substr(0, nCount);}
CZipString Right( int nCount) const
{
nCount = size() < nCount ? size() : nCount;
return substr(size() - nCount);
}
CZipString Mid( int nFirst ) const {return substr(nFirst);}
CZipString Mid( int nFirst, int nCount ) const {return substr(nFirst, nCount);}
int Collate( LPCTSTR lpsz ) const
{
return _ZIPUSEFACET(std::locale(), std::collate<TCHAR>).compare(c_str(), c_str() + size(), lpsz, lpsz + zslen(lpsz));
}
int CollateNoCase( LPCTSTR lpsz ) const
{
CZipString s1(c_str()), s2(lpsz);
s1.MakeLower();
s2.MakeLower();
return s1.Collate(s2);
}
int Compare( LPCTSTR lpsz ) const
{
return compare(lpsz);
}
int CompareNoCase( LPCTSTR lpsz ) const
{
CZipString s1(c_str()), s2(lpsz);
s1.MakeLower();
s2.MakeLower();
return s1.Compare(s2);
}
bool operator != (LPCTSTR lpsz)
{
return Compare(lpsz) != 0;
}
bool operator == (LPCTSTR lpsz)
{
return Compare(lpsz) == 0;
}
};
#if defined(_MSC_VER) && (_MSC_VER > 1100)
#pragma warning( pop)
#endif
#endif //__ZIPSTRING_H__

View File

@@ -0,0 +1,225 @@
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#include "zutil.h"
struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef STDC
extern void exit OF((int));
#endif
const char *z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */
"stream end", /* Z_STREAM_END 1 */
"", /* Z_OK 0 */
"file error", /* Z_ERRNO (-1) */
"stream error", /* Z_STREAM_ERROR (-2) */
"data error", /* Z_DATA_ERROR (-3) */
"insufficient memory", /* Z_MEM_ERROR (-4) */
"buffer error", /* Z_BUF_ERROR (-5) */
"incompatible version",/* Z_VERSION_ERROR (-6) */
""};
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
#ifdef DEBUG
# ifndef verbose
# define verbose 0
# endif
int z_verbose = verbose;
void z_error (m)
char *m;
{
fprintf(stderr, "%s\n", m);
exit(1);
}
#endif
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
#ifndef HAVE_MEMCPY
void zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
{
if (len == 0) return;
do {
*dest++ = *source++; /* ??? to be unrolled */
} while (--len != 0);
}
int zmemcmp(s1, s2, len)
const Bytef* s1;
const Bytef* s2;
uInt len;
{
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
}
return 0;
}
void zmemzero(dest, len)
Bytef* dest;
uInt len;
{
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
} while (--len != 0);
}
#endif
#ifdef __TURBOC__
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
/* Small and medium model in Turbo C are for now limited to near allocation
* with reduced MAX_WBITS and MAX_MEM_LEVEL
*/
# define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
* and farmalloc(64K) returns a pointer with an offset of 8, so we
* must fix the pointer. Warning: the pointer must be put back to its
* original form in order to free it, use zcfree().
*/
#define MAX_PTR 10
/* 10*64K = 640K */
local int next_ptr = 0;
typedef struct ptr_table_s {
voidpf org_ptr;
voidpf new_ptr;
} ptr_table;
local ptr_table table[MAX_PTR];
/* This table is used to remember the original form of pointers
* to large buffers (64K). Such pointers are normalized with a zero offset.
* Since MSDOS is not a preemptive multitasking OS, this table is not
* protected from concurrent access. This hack doesn't work anyway on
* a protected system like OS/2. Use Microsoft C instead.
*/
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
{
voidpf buf = opaque; /* just to make some compilers happy */
ulg bsize = (ulg)items*size;
/* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf;
} else {
buf = farmalloc(bsize + 16L);
}
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
table[next_ptr].org_ptr = buf;
/* Normalize the pointer to seg:0 */
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
*(ush*)&buf = 0;
table[next_ptr++].new_ptr = buf;
return buf;
}
void zcfree (voidpf opaque, voidpf ptr)
{
int n;
if (*(ush*)&ptr != 0) { /* object < 64K */
farfree(ptr);
return;
}
/* Find the original pointer */
for (n = 0; n < next_ptr; n++) {
if (ptr != table[n].new_ptr) continue;
farfree(table[n].org_ptr);
while (++n < next_ptr) {
table[n-1] = table[n];
}
next_ptr--;
return;
}
ptr = opaque; /* just to make some compilers happy */
Assert(0, "zcfree: ptr not found");
}
#endif
#endif /* __TURBOC__ */
#if defined(M_I86) && !defined(__32BIT__)
/* Microsoft C in 16-bit mode */
# define MY_ZCALLOC
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
# define _halloc halloc
# define _hfree hfree
#endif
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
{
if (opaque) opaque = 0; /* to make compiler happy */
return _halloc((long)items, size);
}
void zcfree (voidpf opaque, voidpf ptr)
{
if (opaque) opaque = 0; /* to make compiler happy */
_hfree(ptr);
}
#endif /* MSC */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC
extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
voidpf zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
if (opaque) items += size - size; /* make compiler happy */
return (voidpf)calloc(items, size);
}
void zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
free(ptr);
if (opaque) return; /* make compiler happy */
}
#endif /* MY_ZCALLOC */

View File

@@ -0,0 +1,220 @@
/* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* WARNING: this file should *not* be used by applications. It is
part of the implementation of the compression library and is
subject to change. Applications should only use zlib.h.
*/
/* @(#) $Id$ */
#ifndef _Z_UTIL_H
#define _Z_UTIL_H
#include "zlib.h"
#ifdef STDC
# include <stddef.h>
# include <string.h>
# include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
extern int errno;
#else
# include <errno.h>
#endif
#ifndef local
# define local static
#endif
/* compile with -Dlocal if your debugger can't find static symbols */
typedef unsigned char uch;
typedef uch FAR uchf;
typedef unsigned short ush;
typedef ush FAR ushf;
typedef unsigned long ulg;
extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = (char*)ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */
/* common constants */
#ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS
#endif
/* default windowBits for decompression. MAX_WBITS is for compression only */
#if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
#else
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
#endif
/* default memLevel */
#define STORED_BLOCK 0
#define STATIC_TREES 1
#define DYN_TREES 2
/* The three kinds of block type */
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */
#ifdef MSDOS
# define OS_CODE 0x00
# if defined(__TURBOC__) || defined(__BORLANDC__)
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
/* Allow compilation with ANSI keywords only enabled */
void _Cdecl farfree( void *block );
void *_Cdecl farmalloc( unsigned long nbytes );
# else
# include <alloc.h>
# endif
# else /* MSC or DJGPP */
# include <malloc.h>
# endif
#endif
#ifdef OS2
# define OS_CODE 0x06
#endif
#ifdef WIN32 /* Window 95 & Windows NT */
# define OS_CODE 0x0b
#endif
#if defined(VAXC) || defined(VMS)
# define OS_CODE 0x02
# define F_OPEN(name, mode) \
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
#endif
#ifdef AMIGA
# define OS_CODE 0x01
#endif
#if defined(ATARI) || defined(atarist)
# define OS_CODE 0x05
#endif
#if defined(MACOS) || defined(TARGET_OS_MAC)
# define OS_CODE 0x07
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
# include <unix.h> /* for fdopen */
# else
# ifndef fdopen
# define fdopen(fd,mode) NULL /* No fdopen() */
# endif
# endif
#endif
#ifdef __50SERIES /* Prime/PRIMOS */
# define OS_CODE 0x0F
#endif
#ifdef TOPS20
# define OS_CODE 0x0a
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif
#if (defined(_MSC_VER) && (_MSC_VER > 600))
# define fdopen(fd,type) _fdopen(fd,type)
#endif
/* Common defaults */
#ifndef OS_CODE
# define OS_CODE 0x03 /* assume Unix */
#endif
#ifndef F_OPEN
# define F_OPEN(name, mode) fopen((name), (mode))
#endif
/* functions */
#ifdef HAVE_STRERROR
extern char *strerror OF((int));
# define zstrerror(errnum) strerror(errnum)
#else
# define zstrerror(errnum) ""
#endif
#if defined(pyr)
# define NO_MEMCPY
#endif
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
/* Use our own functions for small and medium model with MSC <= 5.0.
* You may have to use the same strategy for Borland C (untested).
* The __SC__ check is for Symantec.
*/
# define NO_MEMCPY
#endif
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
# define HAVE_MEMCPY
#endif
#ifdef HAVE_MEMCPY
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len)
# else
# define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len)
# endif
#else
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
extern void zmemzero OF((Bytef* dest, uInt len));
#endif
/* Diagnostic functions */
#ifdef DEBUG
# include <stdio.h>
extern int z_verbose;
extern void z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
uInt len));
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
void zcfree OF((voidpf opaque, voidpf ptr));
#define ZALLOC(strm, items, size) \
(*((strm)->zalloc))((strm)->opaque, (items), (size))
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
#endif /* _Z_UTIL_H */