| #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)); |
| } |
| |
| |