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