117651Speter/* zutil.c -- target dependent utility functions for the compression library
2312335Sdelphij * Copyright (C) 1995-2017 Jean-loup Gailly
3131377Stjr * For conditions of distribution and use, see copyright notice in zlib.h
417651Speter */
517651Speter
633904Ssteve/* @(#) $Id$ */
717651Speter
817651Speter#include "zutil.h"
9237248Sdelphij#ifndef Z_SOLO
10237248Sdelphij#  include "gzguts.h"
11237248Sdelphij#endif
1217651Speter
13250224Sdelphijz_const char * const z_errmsg[10] = {
14311285Sdelphij    (z_const char *)"need dictionary",     /* Z_NEED_DICT       2  */
15311285Sdelphij    (z_const char *)"stream end",          /* Z_STREAM_END      1  */
16311285Sdelphij    (z_const char *)"",                    /* Z_OK              0  */
17311285Sdelphij    (z_const char *)"file error",          /* Z_ERRNO         (-1) */
18311285Sdelphij    (z_const char *)"stream error",        /* Z_STREAM_ERROR  (-2) */
19311285Sdelphij    (z_const char *)"data error",          /* Z_DATA_ERROR    (-3) */
20311285Sdelphij    (z_const char *)"insufficient memory", /* Z_MEM_ERROR     (-4) */
21311285Sdelphij    (z_const char *)"buffer error",        /* Z_BUF_ERROR     (-5) */
22311285Sdelphij    (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
23311285Sdelphij    (z_const char *)""
24311285Sdelphij};
2517651Speter
2617651Speter
2733904Ssteveconst char * ZEXPORT zlibVersion()
2817651Speter{
2917651Speter    return ZLIB_VERSION;
3017651Speter}
3117651Speter
32131377StjruLong ZEXPORT zlibCompileFlags()
33131377Stjr{
34131377Stjr    uLong flags;
35131377Stjr
36131377Stjr    flags = 0;
37205194Sdelphij    switch ((int)(sizeof(uInt))) {
38131377Stjr    case 2:     break;
39131377Stjr    case 4:     flags += 1;     break;
40131377Stjr    case 8:     flags += 2;     break;
41131377Stjr    default:    flags += 3;
42131377Stjr    }
43205194Sdelphij    switch ((int)(sizeof(uLong))) {
44131377Stjr    case 2:     break;
45131377Stjr    case 4:     flags += 1 << 2;        break;
46131377Stjr    case 8:     flags += 2 << 2;        break;
47131377Stjr    default:    flags += 3 << 2;
48131377Stjr    }
49205194Sdelphij    switch ((int)(sizeof(voidpf))) {
50131377Stjr    case 2:     break;
51131377Stjr    case 4:     flags += 1 << 4;        break;
52131377Stjr    case 8:     flags += 2 << 4;        break;
53131377Stjr    default:    flags += 3 << 4;
54131377Stjr    }
55205194Sdelphij    switch ((int)(sizeof(z_off_t))) {
56131377Stjr    case 2:     break;
57131377Stjr    case 4:     flags += 1 << 6;        break;
58131377Stjr    case 8:     flags += 2 << 6;        break;
59131377Stjr    default:    flags += 3 << 6;
60131377Stjr    }
61311285Sdelphij#ifdef ZLIB_DEBUG
62131377Stjr    flags += 1 << 8;
63131377Stjr#endif
64131377Stjr#if defined(ASMV) || defined(ASMINF)
65131377Stjr    flags += 1 << 9;
66131377Stjr#endif
67131377Stjr#ifdef ZLIB_WINAPI
68131377Stjr    flags += 1 << 10;
69131377Stjr#endif
70131377Stjr#ifdef BUILDFIXED
71131377Stjr    flags += 1 << 12;
72131377Stjr#endif
73131377Stjr#ifdef DYNAMIC_CRC_TABLE
74131377Stjr    flags += 1 << 13;
75131377Stjr#endif
76131377Stjr#ifdef NO_GZCOMPRESS
77157043Sdes    flags += 1L << 16;
78131377Stjr#endif
79131377Stjr#ifdef NO_GZIP
80157043Sdes    flags += 1L << 17;
81131377Stjr#endif
82131377Stjr#ifdef PKZIP_BUG_WORKAROUND
83157043Sdes    flags += 1L << 20;
84131377Stjr#endif
85131377Stjr#ifdef FASTEST
86157043Sdes    flags += 1L << 21;
87131377Stjr#endif
88237248Sdelphij#if defined(STDC) || defined(Z_HAVE_STDARG_H)
89237248Sdelphij#  ifdef NO_vsnprintf
90237248Sdelphij    flags += 1L << 25;
91237248Sdelphij#    ifdef HAS_vsprintf_void
92237248Sdelphij    flags += 1L << 26;
93237248Sdelphij#    endif
94237248Sdelphij#  else
95237248Sdelphij#    ifdef HAS_vsnprintf_void
96237248Sdelphij    flags += 1L << 26;
97237248Sdelphij#    endif
98237248Sdelphij#  endif
99131377Stjr#else
100237248Sdelphij    flags += 1L << 24;
101237248Sdelphij#  ifdef NO_snprintf
102237248Sdelphij    flags += 1L << 25;
103237248Sdelphij#    ifdef HAS_sprintf_void
104237248Sdelphij    flags += 1L << 26;
105237248Sdelphij#    endif
106237248Sdelphij#  else
107237248Sdelphij#    ifdef HAS_snprintf_void
108237248Sdelphij    flags += 1L << 26;
109237248Sdelphij#    endif
110237248Sdelphij#  endif
111131377Stjr#endif
112237248Sdelphij    return flags;
113131377Stjr}
11433904Ssteve
115311285Sdelphij#ifdef ZLIB_DEBUG
116311285Sdelphij#include <stdlib.h>
11733904Ssteve#  ifndef verbose
11833904Ssteve#    define verbose 0
11933904Ssteve#  endif
120206905Sdelphijint ZLIB_INTERNAL z_verbose = verbose;
12133904Ssteve
122206905Sdelphijvoid ZLIB_INTERNAL z_error (m)
12317651Speter    char *m;
12417651Speter{
12517651Speter    fprintf(stderr, "%s\n", m);
12617651Speter    exit(1);
12717651Speter}
12817651Speter#endif
12917651Speter
13033904Ssteve/* exported to allow conversion of error code to string for compress() and
13133904Ssteve * uncompress()
13233904Ssteve */
13333904Ssteveconst char * ZEXPORT zError(err)
13433904Ssteve    int err;
13533904Ssteve{
13633904Ssteve    return ERR_MSG(err);
13733904Ssteve}
13833904Ssteve
139131377Stjr#if defined(_WIN32_WCE)
140157043Sdes    /* The Microsoft C Run-Time Library for Windows CE doesn't have
141157043Sdes     * errno.  We define it as a global variable to simplify porting.
142157043Sdes     * Its value is always 0 and should not be used.
143157043Sdes     */
144131377Stjr    int errno = 0;
145131377Stjr#endif
14633904Ssteve
14717651Speter#ifndef HAVE_MEMCPY
14817651Speter
149206905Sdelphijvoid ZLIB_INTERNAL zmemcpy(dest, source, len)
15017651Speter    Bytef* dest;
15142468Speter    const Bytef* source;
15217651Speter    uInt  len;
15317651Speter{
15417651Speter    if (len == 0) return;
15517651Speter    do {
15617651Speter        *dest++ = *source++; /* ??? to be unrolled */
15717651Speter    } while (--len != 0);
15817651Speter}
15917651Speter
160206905Sdelphijint ZLIB_INTERNAL zmemcmp(s1, s2, len)
16142468Speter    const Bytef* s1;
16242468Speter    const Bytef* s2;
16317651Speter    uInt  len;
16417651Speter{
16517651Speter    uInt j;
16617651Speter
16717651Speter    for (j = 0; j < len; j++) {
16817651Speter        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
16917651Speter    }
17017651Speter    return 0;
17117651Speter}
17217651Speter
173206905Sdelphijvoid ZLIB_INTERNAL zmemzero(dest, len)
17417651Speter    Bytef* dest;
17517651Speter    uInt  len;
17617651Speter{
17717651Speter    if (len == 0) return;
17817651Speter    do {
17917651Speter        *dest++ = 0;  /* ??? to be unrolled */
18017651Speter    } while (--len != 0);
18117651Speter}
18217651Speter#endif
18317651Speter
184230837Sdelphij#ifndef Z_SOLO
185131377Stjr
186131377Stjr#ifdef SYS16BIT
187131377Stjr
18817651Speter#ifdef __TURBOC__
189131377Stjr/* Turbo C in 16-bit mode */
190131377Stjr
19117651Speter#  define MY_ZCALLOC
19217651Speter
19317651Speter/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
19417651Speter * and farmalloc(64K) returns a pointer with an offset of 8, so we
19517651Speter * must fix the pointer. Warning: the pointer must be put back to its
19617651Speter * original form in order to free it, use zcfree().
19717651Speter */
19817651Speter
19917651Speter#define MAX_PTR 10
20017651Speter/* 10*64K = 640K */
20117651Speter
20217651Speterlocal int next_ptr = 0;
20317651Speter
20417651Spetertypedef struct ptr_table_s {
20517651Speter    voidpf org_ptr;
20617651Speter    voidpf new_ptr;
20717651Speter} ptr_table;
20817651Speter
20917651Speterlocal ptr_table table[MAX_PTR];
21017651Speter/* This table is used to remember the original form of pointers
21117651Speter * to large buffers (64K). Such pointers are normalized with a zero offset.
21217651Speter * Since MSDOS is not a preemptive multitasking OS, this table is not
21317651Speter * protected from concurrent access. This hack doesn't work anyway on
21417651Speter * a protected system like OS/2. Use Microsoft C instead.
21517651Speter */
21617651Speter
217206905Sdelphijvoidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
21817651Speter{
219311285Sdelphij    voidpf buf;
22017651Speter    ulg bsize = (ulg)items*size;
22117651Speter
222311285Sdelphij    (void)opaque;
223311285Sdelphij
22417651Speter    /* If we allocate less than 65520 bytes, we assume that farmalloc
22517651Speter     * will return a usable pointer which doesn't have to be normalized.
22617651Speter     */
22717651Speter    if (bsize < 65520L) {
22817651Speter        buf = farmalloc(bsize);
22917651Speter        if (*(ush*)&buf != 0) return buf;
23017651Speter    } else {
23117651Speter        buf = farmalloc(bsize + 16L);
23217651Speter    }
23317651Speter    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
23417651Speter    table[next_ptr].org_ptr = buf;
23517651Speter
23617651Speter    /* Normalize the pointer to seg:0 */
23717651Speter    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
23817651Speter    *(ush*)&buf = 0;
23917651Speter    table[next_ptr++].new_ptr = buf;
24017651Speter    return buf;
24117651Speter}
24217651Speter
243206905Sdelphijvoid ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
24417651Speter{
24517651Speter    int n;
246311285Sdelphij
247311285Sdelphij    (void)opaque;
248311285Sdelphij
24917651Speter    if (*(ush*)&ptr != 0) { /* object < 64K */
25017651Speter        farfree(ptr);
25117651Speter        return;
25217651Speter    }
25317651Speter    /* Find the original pointer */
25417651Speter    for (n = 0; n < next_ptr; n++) {
25517651Speter        if (ptr != table[n].new_ptr) continue;
25617651Speter
25717651Speter        farfree(table[n].org_ptr);
25817651Speter        while (++n < next_ptr) {
25917651Speter            table[n-1] = table[n];
26017651Speter        }
26117651Speter        next_ptr--;
26217651Speter        return;
26317651Speter    }
26417651Speter    Assert(0, "zcfree: ptr not found");
26517651Speter}
266131377Stjr
26717651Speter#endif /* __TURBOC__ */
26817651Speter
26917651Speter
270131377Stjr#ifdef M_I86
27117651Speter/* Microsoft C in 16-bit mode */
27217651Speter
27317651Speter#  define MY_ZCALLOC
27417651Speter
27542468Speter#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
27617651Speter#  define _halloc  halloc
27717651Speter#  define _hfree   hfree
27817651Speter#endif
27917651Speter
280206905Sdelphijvoidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
28117651Speter{
282311285Sdelphij    (void)opaque;
28317651Speter    return _halloc((long)items, size);
28417651Speter}
28517651Speter
286206905Sdelphijvoid ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
28717651Speter{
288311285Sdelphij    (void)opaque;
28917651Speter    _hfree(ptr);
29017651Speter}
29117651Speter
292131377Stjr#endif /* M_I86 */
29317651Speter
294131377Stjr#endif /* SYS16BIT */
29517651Speter
296131377Stjr
29717651Speter#ifndef MY_ZCALLOC /* Any system without a special alloc function */
29817651Speter
29917651Speter#ifndef STDC
300131377Stjrextern voidp  malloc OF((uInt size));
30117651Speterextern voidp  calloc OF((uInt items, uInt size));
30217651Speterextern void   free   OF((voidpf ptr));
30317651Speter#endif
30417651Speter
305206905Sdelphijvoidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
30617651Speter    voidpf opaque;
30717651Speter    unsigned items;
30817651Speter    unsigned size;
30917651Speter{
310311285Sdelphij    (void)opaque;
311131377Stjr    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
312131377Stjr                              (voidpf)calloc(items, size);
31317651Speter}
31417651Speter
315206905Sdelphijvoid ZLIB_INTERNAL zcfree (opaque, ptr)
31617651Speter    voidpf opaque;
31717651Speter    voidpf ptr;
31817651Speter{
319311285Sdelphij    (void)opaque;
32017651Speter    free(ptr);
32117651Speter}
32217651Speter
32317651Speter#endif /* MY_ZCALLOC */
324230837Sdelphij
325230837Sdelphij#endif /* !Z_SOLO */
326