/*
******************************************************************************
*
*   Copyright (C) 2002-2012, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
******************************************************************************
*
* File cmemory.c      ICU Heap allocation.
*                     All ICU heap allocation, both for C and C++ new of ICU
*                     class types, comes through these functions.
*
*                     If you have a need to replace ICU allocation, this is the
*                     place to do it.
*
*                     Note that uprv_malloc(0) returns a non-NULL pointer, and
*                     that a subsequent free of that pointer value is a NOP.
*
******************************************************************************
*/
#include "unicode/uclean.h"
#include "cmemory.h"
#include "putilimp.h"
#include "uassert.h"
#include <stdlib.h>

/* uprv_malloc(0) returns a pointer to this read-only data. */
static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};

/* Function Pointers for user-supplied heap functions  */
static const void     *pContext;
static UMemAllocFn    *pAlloc;
static UMemReallocFn  *pRealloc;
static UMemFreeFn     *pFree;

/* Flag indicating whether any heap allocations have happened.
 *   Used to prevent changing out the heap functions after allocations have been made */
static UBool   gHeapInUse;

#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
#include <stdio.h>
static int n=0;
static long b=0; 
#endif

#if U_DEBUG

static char gValidMemorySink = 0;

U_CAPI void uprv_checkValidMemory(const void *p, size_t n) {
    /*
     * Access the memory to ensure that it's all valid.
     * Load and save a computed value to try to ensure that the compiler
     * does not throw away the whole loop.
     * A thread analyzer might complain about un-mutexed access to gValidMemorySink
     * which is true but harmless because no one ever uses the value in gValidMemorySink.
     */
    const char *s = (const char *)p;
    char c = gValidMemorySink;
    size_t i;
    U_ASSERT(p != NULL);
    for(i = 0; i < n; ++i) {
        c ^= s[i];
    }
    gValidMemorySink = c;
}

#endif  /* U_DEBUG */

U_CAPI void * U_EXPORT2
uprv_malloc(size_t s) {
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
#if 1
  putchar('>');
  fflush(stdout);
#else
  fprintf(stderr,"MALLOC\t#%d\t%ul bytes\t%ul total\n", ++n,s,(b+=s)); fflush(stderr);
#endif
#endif
    if (s > 0) {
        gHeapInUse = TRUE;
        if (pAlloc) {
            return (*pAlloc)(pContext, s);
        } else {
            return uprv_default_malloc(s);
        }
    } else {
        return (void *)zeroMem;
    }
}

U_CAPI void * U_EXPORT2
uprv_realloc(void * buffer, size_t size) {
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
  putchar('~');
  fflush(stdout);
#endif
    if (buffer == zeroMem) {
        return uprv_malloc(size);
    } else if (size == 0) {
        if (pFree) {
            (*pFree)(pContext, buffer);
        } else {
            uprv_default_free(buffer);
        }
        return (void *)zeroMem;
    } else {
        gHeapInUse = TRUE;
        if (pRealloc) {
            return (*pRealloc)(pContext, buffer, size);
        } else {
            return uprv_default_realloc(buffer, size);
        }
    }
}

U_CAPI void U_EXPORT2
uprv_free(void *buffer) {
#if U_DEBUG && defined(UPRV_MALLOC_COUNT)
  putchar('<');
  fflush(stdout);
#endif
    if (buffer != zeroMem) {
        if (pFree) {
            (*pFree)(pContext, buffer);
        } else {
            uprv_default_free(buffer);
        }
    }
}

U_CAPI void * U_EXPORT2
uprv_calloc(size_t num, size_t size) {
    void *mem = NULL;
    size *= num;
    mem = uprv_malloc(size);
    if (mem) {
        uprv_memset(mem, 0, size);
    }
    return mem;
}

U_CAPI void U_EXPORT2
u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f,  UErrorCode *status)
{
    if (U_FAILURE(*status)) {
        return;
    }
    if (a==NULL || r==NULL || f==NULL) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    if (gHeapInUse) {
        *status = U_INVALID_STATE_ERROR;
        return;
    }
    pContext  = context;
    pAlloc    = a;
    pRealloc  = r;
    pFree     = f;
}


U_CFUNC UBool cmemory_cleanup(void) {
    pContext   = NULL;
    pAlloc     = NULL;
    pRealloc   = NULL;
    pFree      = NULL;
    gHeapInUse = FALSE;
    return TRUE;
}


/*
 *   gHeapInUse
 *       Return True if ICU has allocated any memory.
 *       Used by u_SetMutexFunctions() and similar to verify that ICU has not
 *               been used, that it is in a pristine initial state.
 */
U_CFUNC UBool cmemory_inUse() {
    return gHeapInUse;
}

