add .gitignore
[tedtools.git] / tmalloc.c
index d6c0b76..e93a46c 100644 (file)
--- a/tmalloc.c
+++ b/tmalloc.c
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <stdarg.h>
 
 #include "tlog.h"
 #include "tmalloc.h"
@@ -161,6 +162,25 @@ freeMemoryContext(MemoryContext *cntx) {
        }
 }
 
+void
+resetMemoryContext(MemoryContext *cntx) {
+       MemoryChunk *chunk, *chunkptr;
+
+       while( cntx ) {
+               chunkptr = cntx->chunk;
+               chunkptr->freesize = chunkptr->size;
+               chunkptr = chunkptr->next;
+               cntx->chunk->next = NULL;
+
+               while( chunkptr ) {
+                       chunk=chunkptr->next;
+                       tfree(chunkptr);
+                       chunkptr=chunk;
+               }
+               cntx=cntx->child;
+       }
+}
+
 void*   
 mcalloc(MemoryContext *cntx, size_t size) {
        MemoryChunk     *chunk = cntx->chunk;
@@ -188,10 +208,10 @@ mcalloc(MemoryContext *cntx, size_t size) {
                chunk = newchunk;
        }
 
-       chunk->freesize -= size;
-       alloc = (MCAllocatedSpace*)( chunk->data + chunk->freesize );
+       alloc = (MCAllocatedSpace*)( chunk->data + chunk->size - chunk->freesize );
        alloc->size = size; 
        alloc->cntx = cntx;
+       chunk->freesize -= size;
  
        if ( cntx->flags & MC_DEBUG ) {
                *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) = MCMAGICKNUMBER;
@@ -223,7 +243,8 @@ mcrealloc(void * ptr, size_t size) {
                realsize = alloc->size - MCASHDRSZ;
 
        if ( size > realsize ) {
-               if ( (char*)alloc == alloc->cntx->chunk->data + alloc->cntx->chunk->freesize && 
+               MemoryChunk *chunk = alloc->cntx->chunk;
+               if ( (char*)alloc == chunk->data + chunk->size - chunk->freesize - alloc->size &&
                                PTRALIGN(size)-realsize <= alloc->cntx->chunk->freesize ) {
                        /* just enlarge */
                        alloc->cntx->chunk->freesize -= PTRALIGN(size)-realsize;
@@ -248,6 +269,7 @@ mcrealloc(void * ptr, size_t size) {
 void    
 mcfree(void * ptr) {
        MCAllocatedSpace        *alloc = (MCAllocatedSpace*)( (char*)ptr - MCASHDRSZ );
+       MemoryChunk *chunk;
 
        if ( ptr==NULL )
                tlog(TL_CRIT|TL_EXIT, "mcfree: free null pointer");
@@ -255,7 +277,8 @@ mcfree(void * ptr) {
        if ( alloc->cntx->flags & MC_DEBUG ) 
                tassert(  *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) == MCMAGICKNUMBER );
 
-       if ( (char*)alloc == alloc->cntx->chunk->data + alloc->cntx->chunk->freesize ) /* last allocated value */
+       chunk = alloc->cntx->chunk;
+       if ( (char*)alloc == chunk->data + chunk->size - chunk->freesize - alloc->size ) /* last allocated value */
                alloc->cntx->chunk->freesize+=alloc->size;
 
        alloc->cntx=NULL;
@@ -274,3 +297,106 @@ mcnstrdup(MemoryContext *cntx, char *src, int len) {
        return dest;
 }
 
+/*********StringBuffer********/
+
+static inline void*
+StringBufferAlloc(StringBuffer* state, void *ptr, size_t size) {
+       if (state->mc)
+               return (ptr) ? mcrealloc(ptr, size) : mcalloc(state->mc, size);
+       else if (state->memalloc)
+               return state->memalloc(ptr, size);
+       else
+               return (ptr) ? trealloc(ptr, size) : tmalloc(size);
+}
+
+static StringBuffer*
+initStringBufferInternal(StringBuffer* state, int initsize) {
+    state->len = (initsize>0) ? initsize : 1024;
+       state->ptr = state->buf = (char*)StringBufferAlloc(state, NULL, initsize);
+       if (!state->ptr)
+               return NULL;
+
+       *(state->ptr) ='\0';
+
+       return state;
+}
+
+StringBuffer*
+initStringBuffer(StringBuffer* state, int initsize) {
+       memset(state, 0, sizeof(*state));
+       
+       return initStringBufferInternal(state, initsize);
+}
+
+StringBuffer*
+initStringBufferMC(StringBuffer* state, MemoryContext *mc, int initsize) {
+       memset(state, 0, sizeof(*state));
+       state->mc = mc;
+
+       return initStringBufferInternal(state, initsize);
+}
+
+StringBuffer*
+initStringBufferMA(StringBuffer* state, MemAlloc memalloc, int initsize) {
+       memset(state, 0, sizeof(*state));
+       state->memalloc = memalloc;
+
+       return initStringBufferInternal(state, initsize);
+}
+
+StringBuffer*
+appendStringBuffer( StringBuffer *state, char *string, int stringlen) {
+    if ( string ) {
+                       if ( stringlen <= 0 )
+                               stringlen = strlen(string);
+       } else
+               stringlen = 0;
+                                                                          
+       if ( stringlen == 0 )
+               return state;
+                                                                                                         
+       while ( state->len - ( state->ptr - state->buf ) < stringlen + 1 ) {
+                       int     diff = state->ptr - state->buf;
+
+                       state->len *= 2;
+                       state->buf = (char*)StringBufferAlloc(state, state->buf, state->len);
+                       state->ptr = state->buf + diff;
+       }
+
+       memcpy(state->ptr, string, stringlen);
+       state->ptr += stringlen;
+       *state->ptr = '\0';
+       return state;
+}
+
+StringBuffer*
+printStringBuffer( StringBuffer *state, const char *format, ...) {
+    va_list args;
+       int     printedlen;
+       int     buffreelen;
+
+       buffreelen = state->len - ( state->ptr - state->buf ) - 1;
+
+       va_start(args, format);
+       printedlen = vsnprintf(state->ptr, buffreelen, format, args);
+       va_end(args);
+       /*
+       * if buffer too short, resize buffer and
+       * print it again
+       */
+       if ( buffreelen<=printedlen ) {
+               u_int32_t curlen = state->ptr - state->buf;
+               do {
+                       state->len *= 2;
+               } while( state->ptr - state->buf + printedlen >= state->len );
+
+               state->buf = (char*)StringBufferAlloc(state, state->buf, state->len);
+               state->ptr = state->buf + curlen;
+               va_start(args, format);
+               printedlen = vsnprintf(state->ptr, printedlen+1, format, args);
+               va_end(args);
+       }
+       state->ptr += printedlen;
+       return state;
+}
+