zutil.c revision 230837
1/* zutil.c -- target dependent utility functions for the compression library
2 * Copyright (C) 1995-2005, 2010, 2011 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* @(#) $Id$ */
7
8#include "zutil.h"
9
10#ifndef NO_DUMMY_DECL
11struct internal_state      {int dummy;}; /* for buggy compilers */
12#endif
13
14const char * const z_errmsg[10] = {
15"need dictionary",     /* Z_NEED_DICT       2  */
16"stream end",          /* Z_STREAM_END      1  */
17"",                    /* Z_OK              0  */
18"file error",          /* Z_ERRNO         (-1) */
19"stream error",        /* Z_STREAM_ERROR  (-2) */
20"data error",          /* Z_DATA_ERROR    (-3) */
21"insufficient memory", /* Z_MEM_ERROR     (-4) */
22"buffer error",        /* Z_BUF_ERROR     (-5) */
23"incompatible version",/* Z_VERSION_ERROR (-6) */
24""};
25
26
27const char * ZEXPORT zlibVersion()
28{
29    return ZLIB_VERSION;
30}
31
32uLong ZEXPORT zlibCompileFlags()
33{
34    uLong flags;
35
36    flags = 0;
37    switch ((int)(sizeof(uInt))) {
38    case 2:     break;
39    case 4:     flags += 1;     break;
40    case 8:     flags += 2;     break;
41    default:    flags += 3;
42    }
43    switch ((int)(sizeof(uLong))) {
44    case 2:     break;
45    case 4:     flags += 1 << 2;        break;
46    case 8:     flags += 2 << 2;        break;
47    default:    flags += 3 << 2;
48    }
49    switch ((int)(sizeof(voidpf))) {
50    case 2:     break;
51    case 4:     flags += 1 << 4;        break;
52    case 8:     flags += 2 << 4;        break;
53    default:    flags += 3 << 4;
54    }
55    switch ((int)(sizeof(z_off_t))) {
56    case 2:     break;
57    case 4:     flags += 1 << 6;        break;
58    case 8:     flags += 2 << 6;        break;
59    default:    flags += 3 << 6;
60    }
61#ifdef DEBUG
62    flags += 1 << 8;
63#endif
64#if defined(ASMV) || defined(ASMINF)
65    flags += 1 << 9;
66#endif
67#ifdef ZLIB_WINAPI
68    flags += 1 << 10;
69#endif
70#ifdef BUILDFIXED
71    flags += 1 << 12;
72#endif
73#ifdef DYNAMIC_CRC_TABLE
74    flags += 1 << 13;
75#endif
76#ifdef NO_GZCOMPRESS
77    flags += 1L << 16;
78#endif
79#ifdef NO_GZIP
80    flags += 1L << 17;
81#endif
82#ifdef PKZIP_BUG_WORKAROUND
83    flags += 1L << 20;
84#endif
85#ifdef FASTEST
86    flags += 1L << 21;
87#endif
88#ifdef Z_SOLO
89    return flags;
90#else
91    return flags + gzflags();
92#endif
93}
94
95#ifdef DEBUG
96
97#  ifndef verbose
98#    define verbose 0
99#  endif
100int ZLIB_INTERNAL z_verbose = verbose;
101
102void ZLIB_INTERNAL z_error (m)
103    char *m;
104{
105    fprintf(stderr, "%s\n", m);
106    exit(1);
107}
108#endif
109
110/* exported to allow conversion of error code to string for compress() and
111 * uncompress()
112 */
113const char * ZEXPORT zError(err)
114    int err;
115{
116    return ERR_MSG(err);
117}
118
119#if defined(_WIN32_WCE)
120    /* The Microsoft C Run-Time Library for Windows CE doesn't have
121     * errno.  We define it as a global variable to simplify porting.
122     * Its value is always 0 and should not be used.
123     */
124    int errno = 0;
125#endif
126
127#ifndef HAVE_MEMCPY
128
129void ZLIB_INTERNAL zmemcpy(dest, source, len)
130    Bytef* dest;
131    const Bytef* source;
132    uInt  len;
133{
134    if (len == 0) return;
135    do {
136        *dest++ = *source++; /* ??? to be unrolled */
137    } while (--len != 0);
138}
139
140int ZLIB_INTERNAL zmemcmp(s1, s2, len)
141    const Bytef* s1;
142    const Bytef* s2;
143    uInt  len;
144{
145    uInt j;
146
147    for (j = 0; j < len; j++) {
148        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
149    }
150    return 0;
151}
152
153void ZLIB_INTERNAL zmemzero(dest, len)
154    Bytef* dest;
155    uInt  len;
156{
157    if (len == 0) return;
158    do {
159        *dest++ = 0;  /* ??? to be unrolled */
160    } while (--len != 0);
161}
162#endif
163
164#ifndef Z_SOLO
165
166#ifdef SYS16BIT
167
168#ifdef __TURBOC__
169/* Turbo C in 16-bit mode */
170
171#  define MY_ZCALLOC
172
173/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
174 * and farmalloc(64K) returns a pointer with an offset of 8, so we
175 * must fix the pointer. Warning: the pointer must be put back to its
176 * original form in order to free it, use zcfree().
177 */
178
179#define MAX_PTR 10
180/* 10*64K = 640K */
181
182local int next_ptr = 0;
183
184typedef struct ptr_table_s {
185    voidpf org_ptr;
186    voidpf new_ptr;
187} ptr_table;
188
189local ptr_table table[MAX_PTR];
190/* This table is used to remember the original form of pointers
191 * to large buffers (64K). Such pointers are normalized with a zero offset.
192 * Since MSDOS is not a preemptive multitasking OS, this table is not
193 * protected from concurrent access. This hack doesn't work anyway on
194 * a protected system like OS/2. Use Microsoft C instead.
195 */
196
197voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
198{
199    voidpf buf = opaque; /* just to make some compilers happy */
200    ulg bsize = (ulg)items*size;
201
202    /* If we allocate less than 65520 bytes, we assume that farmalloc
203     * will return a usable pointer which doesn't have to be normalized.
204     */
205    if (bsize < 65520L) {
206        buf = farmalloc(bsize);
207        if (*(ush*)&buf != 0) return buf;
208    } else {
209        buf = farmalloc(bsize + 16L);
210    }
211    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
212    table[next_ptr].org_ptr = buf;
213
214    /* Normalize the pointer to seg:0 */
215    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
216    *(ush*)&buf = 0;
217    table[next_ptr++].new_ptr = buf;
218    return buf;
219}
220
221void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
222{
223    int n;
224    if (*(ush*)&ptr != 0) { /* object < 64K */
225        farfree(ptr);
226        return;
227    }
228    /* Find the original pointer */
229    for (n = 0; n < next_ptr; n++) {
230        if (ptr != table[n].new_ptr) continue;
231
232        farfree(table[n].org_ptr);
233        while (++n < next_ptr) {
234            table[n-1] = table[n];
235        }
236        next_ptr--;
237        return;
238    }
239    ptr = opaque; /* just to make some compilers happy */
240    Assert(0, "zcfree: ptr not found");
241}
242
243#endif /* __TURBOC__ */
244
245
246#ifdef M_I86
247/* Microsoft C in 16-bit mode */
248
249#  define MY_ZCALLOC
250
251#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
252#  define _halloc  halloc
253#  define _hfree   hfree
254#endif
255
256voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
257{
258    if (opaque) opaque = 0; /* to make compiler happy */
259    return _halloc((long)items, size);
260}
261
262void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
263{
264    if (opaque) opaque = 0; /* to make compiler happy */
265    _hfree(ptr);
266}
267
268#endif /* M_I86 */
269
270#endif /* SYS16BIT */
271
272
273#ifndef MY_ZCALLOC /* Any system without a special alloc function */
274
275#ifndef STDC
276extern voidp  malloc OF((uInt size));
277extern voidp  calloc OF((uInt items, uInt size));
278extern void   free   OF((voidpf ptr));
279#endif
280
281voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
282    voidpf opaque;
283    unsigned items;
284    unsigned size;
285{
286    if (opaque) items += size - size; /* make compiler happy */
287    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
288                              (voidpf)calloc(items, size);
289}
290
291void ZLIB_INTERNAL zcfree (opaque, ptr)
292    voidpf opaque;
293    voidpf ptr;
294{
295    free(ptr);
296    if (opaque) return; /* make compiler happy */
297}
298
299#endif /* MY_ZCALLOC */
300
301#endif /* !Z_SOLO */
302