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