return ptrc - buf;
}
+
+MemoryContext *
+allocMemoryContext(MemoryContext* parent, int flags) {
+ MemoryContext *res;
+
+ res = (MemoryContext*)tmalloc( sizeof(MemoryContext) );
+ res->flags = flags;
+ res->parent = parent;
+ if ( parent ) {
+ res->child = parent->child;
+ parent->child = res;
+ } else
+ res->child = NULL;
+
+ res->chunk = (MemoryChunk*)tmalloc( MEMCHNKHDRSZ + CNTXCHUNK );
+ res->chunk->size = res->chunk->freesize = CNTXCHUNK;
+ res->chunk->next = NULL;
+
+ return res;
+}
+
+void
+freeMemoryContext(MemoryContext *cntx) {
+ MemoryContext *ptr=cntx;
+ MemoryChunk *chunk, *chunkptr;
+
+ if ( cntx->parent )
+ cntx->parent->child=NULL;
+
+ while( ptr ) {
+ cntx=ptr->child;
+
+ chunkptr=ptr->chunk;
+ while( chunkptr ) {
+ chunk=chunkptr->next;
+ tfree(chunkptr);
+ chunkptr=chunk;
+ }
+
+ tfree(ptr);
+ ptr=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;
+ MCAllocatedSpace *alloc;
+
+ size = PTRALIGN(size) + MCASHDRSZ;
+ if ( cntx->flags & MC_DEBUG )
+ size += sizeof(u_int32_t);
+
+ if ( chunk->freesize < size ) {
+ MemoryChunk *newchunk;
+
+ if ( size >= CNTXCHUNK ) {
+ newchunk = (MemoryChunk*)tmalloc(MEMCHNKHDRSZ + size);
+ newchunk->size = newchunk->freesize = size;
+ newchunk->next = chunk->next;
+ chunk->next = newchunk;
+ } else {
+ newchunk = (MemoryChunk*)tmalloc(MEMCHNKHDRSZ + CNTXCHUNK);
+ newchunk->size = newchunk->freesize = CNTXCHUNK;
+ newchunk->next = chunk;
+ cntx->chunk = newchunk;
+ }
+
+ chunk = newchunk;
+ }
+
+ 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;
+ memset( alloc->data, 0xc3, size - MCASHDRSZ - sizeof(u_int32_t) );
+ }
+
+ return (void*)(alloc->data);
+}
+
+void *
+mc0alloc(MemoryContext *cntx, size_t size) {
+ void *res = mcalloc(cntx, size);
+ memset( res, 0, size );
+ return res;
+}
+
+void *
+mcrealloc(void * ptr, size_t size) {
+ MCAllocatedSpace *alloc = (MCAllocatedSpace*)( (char*)ptr - MCASHDRSZ );
+ size_t realsize;
+
+ if ( ptr==NULL )
+ tlog(TL_CRIT|TL_EXIT, "mcrealloc: realloc null pointer");
+
+ if ( alloc->cntx->flags & MC_DEBUG ) {
+ tassert( *(u_int32_t*)( (char*)alloc + alloc->size - sizeof(u_int32_t) ) == MCMAGICKNUMBER );
+ realsize = alloc->size - MCASHDRSZ - sizeof(u_int32_t);
+ } else
+ realsize = alloc->size - MCASHDRSZ;
+
+ if ( size > realsize ) {
+ 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;
+ alloc->size+=PTRALIGN(size)-realsize;
+ if ( alloc->cntx->flags & MC_DEBUG ) {
+ memset( (char*)(alloc->data) + realsize, 0xc3, PTRALIGN(size)-realsize );
+ *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) = MCMAGICKNUMBER;
+ }
+ } else {
+ void *newptr = mcalloc(alloc->cntx, size);
+ memcpy( newptr, ptr, realsize );
+ ptr = newptr;
+ if ( alloc->cntx->flags & MC_DEBUG )
+ memset( (char*)ptr + realsize, 0xc3, PTRALIGN(size)-realsize );
+ }
+ }
+
+ return ptr;
+}
+
+
+void
+mcfree(void * ptr) {
+ MCAllocatedSpace *alloc = (MCAllocatedSpace*)( (char*)ptr - MCASHDRSZ );
+ MemoryChunk *chunk;
+
+ if ( ptr==NULL )
+ tlog(TL_CRIT|TL_EXIT, "mcfree: free null pointer");
+
+ if ( alloc->cntx->flags & MC_DEBUG )
+ tassert( *(u_int32_t*)((char*)alloc + alloc->size - sizeof(u_int32_t) ) == MCMAGICKNUMBER );
+
+ 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;
+}
+
+char *
+mcstrdup(MemoryContext *cntx, char * src) {
+ return mcnstrdup(cntx, src, strlen(src));
+}
+
+char *
+mcnstrdup(MemoryContext *cntx, char *src, int len) {
+ char *dest=(char*)mcalloc(cntx, len+1);
+ memcpy(dest, src, len);
+ dest[len]='\0';
+ return dest;
+}
+