blob: da56e3981bcd66ccb6b82af29dfcf85bf600f261 [file] [log] [blame]
#define IN_BALLOC
#include "uemf.h"
#include <stdarg.h>
#include <stdlib.h>
static bType *bQhead[B_MAX_CLASS];
static char *bFreeBuf;
static char *bFreeNext;
static int bFreeSize;
static int bFreeLeft;
static int bFlags = B_USE_MALLOC;
static int bopenCount = 0;
static int ballocGetSize(int size, int *q);
int bopen(void *buf, int bufsize, int flags)
{
bFlags = flags;
if (++bopenCount > 1) {
return 0;
}
if (buf == NULL) {
if (bufsize == 0) {
bufsize = B_DEFAULT_MEM;
}
if ((buf = malloc(bufsize)) == NULL) {
--bopenCount;
return -1;
}
} else {
bFlags |= B_USER_BUF;
}
bFreeSize = bFreeLeft = bufsize;
bFreeBuf = bFreeNext = buf;
memset(bQhead, 0, sizeof(bQhead));
return 0;
}
void bclose()
{
if (--bopenCount <= 0 && !(bFlags & B_USER_BUF)) {
free(bFreeBuf);
bopenCount = 0;
}
}
bType *balloc_tmp;
void *balloc(B_ARGS_DEC, int size)
{
bType *bp;
int q, memSize;
if (bFreeBuf == NULL) {
if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) {
return NULL;
}
}
if (size < 0) {
return NULL;
}
memSize = ballocGetSize(size+1, &q);
if (q >= B_MAX_CLASS) {
if (bFlags & B_USE_MALLOC) {
bp = (bType*) malloc(memSize);
if (bp == NULL) {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
} else {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
bp->u.size = memSize - sizeof(bType);
bp->flags = B_MALLOCED;
} else if ((bp = bQhead[q]) != NULL) {
#ifdef WEBS_SECURITY
bType *tmp = bp->u.next;
if(tmp != NULL)
balloc_tmp = tmp->u.next;
#endif
bQhead[q] = bp->u.next;
bp->u.size = memSize - sizeof(bType);
bp->flags = 0;
} else {
if (bFreeLeft > memSize) {
bp = (bType*) bFreeNext;
bFreeNext += memSize;
bFreeLeft -= memSize;
bp->u.size = memSize - sizeof(bType);
bp->flags = 0;
} else if (bFlags & B_USE_MALLOC) {
if ((bp = (bType*) malloc(memSize)) == NULL) {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
bp->u.size = memSize - sizeof(bType);
bp->flags = B_MALLOCED;
} else {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
}
bp->flags |= B_INTEGRITY;
return (void*) ((char*) bp + sizeof(bType));
}
void bfree(B_ARGS_DEC, void *mp)
{
bType *bp;
int q, memSize;
bp = (bType*) ((char*) mp - sizeof(bType));
a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
if ((bp->flags & B_INTEGRITY_MASK) != B_INTEGRITY) {
return;
}
memSize = ballocGetSize(bp->u.size, &q);
if (bp->flags & B_MALLOCED) {
free(bp);
return;
}
bp->u.next = bQhead[q];
bQhead[q] = bp;
bp->flags = B_FILL_WORD;
}
void bfreeSafe(B_ARGS_DEC, void *mp)
{
if (mp) {
bfree(B_ARGS, mp);
}
}
char_t *bstrdup(B_ARGS_DEC, char_t *s)
{
char_t *cp;
int len;
if (s == NULL) {
s = T("");
}
len = gstrlen(s) + 1;
if ((cp = balloc(B_ARGS, len * sizeof(char_t))) != NULL) {
gstrcpy(cp, s);
}
return cp;
}
void *brealloc(B_ARGS_DEC, void *mp, int newsize)
{
bType *bp;
void *newbuf;
if (mp == NULL) {
return balloc(B_ARGS, newsize);
}
bp = (bType*) ((char*) mp - sizeof(bType));
a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
if (bp->u.size >= newsize) {
return mp;
}
if ((newbuf = balloc(B_ARGS, newsize)) != NULL) {
memcpy(newbuf, mp, bp->u.size);
bfree(B_ARGS, mp);
}
return newbuf;
}
static int ballocGetSize(int size, int *q)
{
int mask;
mask = (size == 0) ? 0 : (size-1) >> B_SHIFT;
for (*q = 0; mask; mask >>= 1) {
*q = *q + 1;
}
return ((1 << (B_SHIFT + *q)) + sizeof(bType));
}