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