/*
	WARNING: This file was generated by dkct.
	Changes you make here will be lost if dkct is run again!
	You should modify the original source and run dkct on it.
	Original source: dk3mem.ctr
*/

/*
Copyright (C) 2011-2013, Dirk Krause

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above opyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used
  to endorse or promote products derived from this software without specific
  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**	@file dk3mem.c The dk3mem module.
*/


#line 123 "dk3mem.ctr"

#include "dk3all.h"






#line 129 "dk3mem.ctr"



void
dk3mem_res(void *mp, size_t sz)
{
  if((mp) && (sz)) {
#if DK3_HAVE_MEMSET
    memset(mp, '\0', sz);
#else
#if DK3_HAVE_BZERO
    bzero(mp, sz);
#else
    register char *ptr;
    register size_t i;
    ptr = (char *)mp; i = sz;
    while(i--) { *(ptr++) = '\0'; }
#endif
#endif
  }
}



void
dk3mem_cpy(void *dp, void const *sp, size_t sz)
{
  if((dp) && (sp) && (sz)) {
#if DK3_HAVE_MEMCPY
    memcpy(dp, sp, sz);
#else
#if DK3_HAVE_BCOPY
    bcopy(sp, dp, sz);
#else
    register char *mydp;
    register char const *mysp;
    register size_t i;
    mydp = (char *)dp;
    mysp = (char const *)sp;
    i = sz;
    while(i--) { *(mydp++) = *(mysp++); }
#endif
#endif
  }
}



int
dk3mem_cmp(void const *s1, void const *s2, size_t sz)
{
  int back = 0;
  if(s1) {
    if(s2) {
#if DK3_HAVE_MEMCMP
        back = memcmp(s1, s2, sz);
#else
#if DK3_HAVE_BCMP
        back = bcmp(s1, s2, sz);
#else
        register char const *mys1;
        register char const *mys2;
	register size_t i;
	register int myback = 0;
        mys1 = (char const *)s1; mys2 = (char const *)s2;
        for(i = 0; ((i < sz) && (myback == 0)); i++) {
          if(*mys1 > *mys2) {
            myback = 1;
          } else {
            if(*mys1 < *mys2) {
              myback = -1;
            } else {
              mys1++; mys2++;
            }
          }
        }
	back = myback;
#endif
#endif
    } else { back = 1; }
  } else {
    if(s2) { back = -1; }
  }
  return back;
}



void *
dk3mem_malloc_app(size_t sz, dk3_app_t *app)
{
  void		*back = NULL;
  char		c8buffer[64];	/* Buffer to show number of bytes. */
  dkChar	dkbuffer[64];	/* Buffer to show number of bytes. */
  

#line 224 "dk3mem.ctr"
  if(sz) {
#if DK3_ON_WINDOWS && (_MSC_VER > 1100)
    

#line 227 "dk3mem.ctr"
    back = (void *)LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT), sz);
#else
#if DK3_HAVE_MALLOC && DK3_HAVE_FREE
    

#line 231 "dk3mem.ctr"
    back = malloc(sz);
    

#line 233 "dk3mem.ctr"
#else
#error "The malloc and free functions are not available here!"
#endif
#endif
    if(back) {	

#line 238 "dk3mem.ctr"
      dk3mem_res(back, sz);
    } else {	

#line 240 "dk3mem.ctr"
      if(app) {	

#line 241 "dk3mem.ctr"
        /* ERROR: Failed to allocate n bytes! */
	if(dk3ma_uintmax_to_c8_string(c8buffer, sizeof(c8buffer),(dk3_um_t)sz)) {
	  (void)dk3str_cnv_c8_to_str(
	    dkbuffer, DK3_SIZEOF(dkbuffer,dkChar), c8buffer
	  );
	  dk3app_log_i3(app, DK3_LL_ERROR, 12, 13, dkbuffer);
	} else {
	  dk3app_log_i1(app, DK3_LL_ERROR, 14);
	}
      }
    }
  } 

#line 253 "dk3mem.ctr"
  return back;
}


void *
dk3mem_malloc(size_t sz)
{
  void *back;
  back = dk3mem_malloc_app(sz, NULL);
  return back;
}



/**	Calculate number of bytes.
	@param	sz	Element size.
	@param	ne	Number of elements.
	@return	Product on success, 0 on error (mathematical overflow).
*/
static
size_t
dk3mem_mul_size_t(size_t sz, size_t ne)
{
  size_t back = 0;
  if(DK3_SIZE_T_MAX % sz) {
    if((DK3_SIZE_T_MAX / sz) > ne) {
      back = sz * ne;
    }
  } else {
    if((DK3_SIZE_T_MAX / sz) >= ne) {
      back = sz * ne;
    }
  }
  return back;
}


void *
dk3mem_alloc_app(size_t sz, size_t ne, dk3_app_t *app)
{
  void			*back = NULL;
  size_t		as = 0;		/* Allocation size. */
  char			c8b1[64];	/* Buffer for element size. */
  char			c8b2[64];	/* Buffer for number of elements. */
  dkChar		dkb1[64];	/* Buffer for element size. */
  dkChar		dkb2[64];	/* Buffer for number of elements. */
  int			ok = 0;		/* Flag: Success. */
  

#line 301 "dk3mem.ctr"
  if((sz) && (ne)) {	
    as = dk3mem_mul_size_t(sz, ne);
    if(as) {
      back = dk3mem_malloc_app(as, app);
    } else {
      if(app) {
        /* ERROR: Numeric overflow! */
	ok = 0;
	if(dk3ma_uintmax_to_c8_string(c8b1, sizeof(c8b1),(dk3_um_t)sz)) {
	  if(dk3ma_uintmax_to_c8_string(c8b2, sizeof(c8b2),(dk3_um_t)ne)) {
	    (void)dk3str_cnv_c8_to_str(
	      dkb1, DK3_SIZEOF(dkb1,dkChar), c8b1
	    );
	    (void)dk3str_cnv_c8_to_str(
	      dkb2, DK3_SIZEOF(dkb2,dkChar), c8b2
	    );
	  }
	}
	if(ok) {
	  dk3app_log_i5(app, DK3_LL_ERROR, 16, 17, 18, dkb1, dkb2);
	} else {
	  dk3app_log_i1(app, DK3_LL_ERROR, 15);
	}
      }
    }
  } 

#line 327 "dk3mem.ctr"
  return back;
}


void *
dk3mem_alloc(size_t sz, size_t ne)
{
  void *back;
  back = dk3mem_alloc_app(sz, ne, NULL);
  return back;
}

void
dk3mem_free (void *po)
{
  if(po) {
#if DK3_ON_WINDOWS && (_MSC_VER > 1100)
    LocalFree((HLOCAL)po);
#else
#if DK3_HAVE_MALLOC && DK3_HAVE_FREE
    free(po);
#endif
#endif
  }
}



/* vim: set ai sw=2 : */

