/* zutil.c -- target dependent utility functions for the compression library
 * Copyright (C) 1995-2017 Jean-loup Gailly
 * For conditions of distribution and use, see copyright notice in zlib.h
 */

#include "zbuild.h"
#include "zutil_p.h"
#include "zutil.h"

z_const char * const PREFIX(z_errmsg)[10] = {
    (z_const char *)"need dictionary",     /* Z_NEED_DICT       2  */
    (z_const char *)"stream end",          /* Z_STREAM_END      1  */
    (z_const char *)"",                    /* Z_OK              0  */
    (z_const char *)"file error",          /* Z_ERRNO         (-1) */
    (z_const char *)"stream error",        /* Z_STREAM_ERROR  (-2) */
    (z_const char *)"data error",          /* Z_DATA_ERROR    (-3) */
    (z_const char *)"insufficient memory", /* Z_MEM_ERROR     (-4) */
    (z_const char *)"buffer error",        /* Z_BUF_ERROR     (-5) */
    (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
    (z_const char *)""
};

const char zlibng_string[] =
    " zlib-ng 2.1.0.devel forked from zlib";

#ifdef ZLIB_COMPAT
const char * Z_EXPORT zlibVersion(void) {
    return ZLIB_VERSION;
}
#endif

const char * Z_EXPORT zlibng_version(void) {
    return ZLIBNG_VERSION;
}

unsigned long Z_EXPORT PREFIX(zlibCompileFlags)(void) {
    unsigned long flags;

    flags = 0;
    switch ((int)(sizeof(unsigned int))) {
    case 2:     break;
    case 4:     flags += 1;     break;
    case 8:     flags += 2;     break;
    default:    flags += 3;
    }
    switch ((int)(sizeof(unsigned long))) {
    case 2:     break;
    case 4:     flags += 1 << 2;        break;
    case 8:     flags += 2 << 2;        break;
    default:    flags += 3 << 2;
    }
    switch ((int)(sizeof(void *))) {
    case 2:     break;
    case 4:     flags += 1 << 4;        break;
    case 8:     flags += 2 << 4;        break;
    default:    flags += 3 << 4;
    }
    switch ((int)(sizeof(z_off_t))) {
    case 2:     break;
    case 4:     flags += 1 << 6;        break;
    case 8:     flags += 2 << 6;        break;
    default:    flags += 3 << 6;
    }
#ifdef ZLIB_DEBUG
    flags += 1 << 8;
#endif
#ifdef ZLIB_WINAPI
    flags += 1 << 10;
#endif
    /* Bit 13 reserved for DYNAMIC_CRC_TABLE */
#ifdef NO_GZCOMPRESS
    flags += 1L << 16;
#endif
#ifdef NO_GZIP
    flags += 1L << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
    flags += 1L << 20;
#endif
    return flags;
}

#ifdef ZLIB_DEBUG
#  include <stdlib.h>
#  ifndef verbose
#    define verbose 0
#  endif
int Z_INTERNAL z_verbose = verbose;

void Z_INTERNAL z_error(char *m) {
    fprintf(stderr, "%s\n", m);
    exit(1);
}
#endif

/* exported to allow conversion of error code to string for compress() and
 * uncompress()
 */
const char * Z_EXPORT PREFIX(zError)(int err) {
    return ERR_MSG(err);
}

void Z_INTERNAL *zng_calloc(void *opaque, unsigned items, unsigned size) {
    Z_UNUSED(opaque);
    return zng_alloc((size_t)items * (size_t)size);
}

void Z_INTERNAL zng_cfree(void *opaque, void *ptr) {
    Z_UNUSED(opaque);
    zng_free(ptr);
}

/* Since we support custom memory allocators, some which might not align memory as we expect,
 * we have to ask for extra memory and return an aligned pointer. */
void Z_INTERNAL *zng_alloc_aligned(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align) {
    uintptr_t return_ptr, original_ptr;
    uint32_t alloc_size, align_diff;
    void *ptr;

    /* If no custom calloc function used then call zlib-ng's aligned calloc */
    if (zalloc == zng_calloc)
        return zng_calloc(opaque, items, size);

    /* Allocate enough memory for proper alignment and to store the original memory pointer */
    alloc_size = sizeof(void *) + (items * size) + align;
    ptr = zalloc(opaque, 1, alloc_size);
    if (!ptr)
        return NULL;

    /* Calculate return pointer address with space enough to store original pointer */
    align_diff = align - ((uintptr_t)ptr % align);
    return_ptr = (uintptr_t)ptr + align_diff;
    if (align_diff < sizeof(void *))
        return_ptr += align;

    /* Store the original pointer for free() */
    original_ptr = return_ptr - sizeof(void *);
    memcpy((void *)original_ptr, &ptr, sizeof(void *));

    /* Return properly aligned pointer in allocation */
    return (void *)return_ptr;
}

void Z_INTERNAL zng_free_aligned(zng_cfree_func zfree, void *opaque, void *ptr) {
    /* If no custom cfree function used then call zlib-ng's aligned cfree */
    if (zfree == zng_cfree) {
        zng_cfree(opaque, ptr);
        return;
    }
    if (!ptr)
        return;

    /* Calculate offset to original memory allocation pointer */
    void *original_ptr = (void *)((uintptr_t)ptr - sizeof(void *));
    void *free_ptr = *(void **)original_ptr;

    /* Free original memory allocation */
    zfree(opaque, free_ptr);
}
