2006-06-17 21:07:08 +08:00
|
|
|
/** \file halloc_util.c
|
2006-02-09 23:50:20 +08:00
|
|
|
|
|
|
|
A hierarchical memory allocation system. Works just like talloc
|
|
|
|
used in Samba, except that an arbitrary block allocated with
|
|
|
|
malloc() can be registered to be freed by halloc_free.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2006-02-28 21:17:16 +08:00
|
|
|
|
2006-02-09 23:50:20 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2006-02-11 08:13:17 +08:00
|
|
|
#include <string.h>
|
2006-02-09 23:50:20 +08:00
|
|
|
|
2006-02-28 21:17:16 +08:00
|
|
|
#include "fallback.h"
|
2006-02-09 23:50:20 +08:00
|
|
|
#include "util.h"
|
2006-02-28 21:17:16 +08:00
|
|
|
|
2006-02-09 23:50:20 +08:00
|
|
|
#include "common.h"
|
|
|
|
#include "halloc.h"
|
|
|
|
|
|
|
|
void *global_context=0;
|
|
|
|
|
|
|
|
void halloc_util_init()
|
|
|
|
{
|
|
|
|
global_context = halloc( 0, 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void halloc_util_destroy()
|
|
|
|
{
|
|
|
|
halloc_free( global_context );
|
|
|
|
}
|
|
|
|
|
|
|
|
array_list_t *al_halloc( void *context )
|
|
|
|
{
|
|
|
|
array_list_t *res = halloc( context, sizeof( array_list_t ) );
|
|
|
|
if( !res )
|
2006-07-03 18:39:57 +08:00
|
|
|
DIE_MEM();
|
2006-02-09 23:50:20 +08:00
|
|
|
al_init( res );
|
2007-02-24 21:19:32 +08:00
|
|
|
halloc_register_function( context?context:res, (void (*)(void *)) &al_destroy, res );
|
2006-02-09 23:50:20 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
string_buffer_t *sb_halloc( void *context )
|
|
|
|
{
|
|
|
|
string_buffer_t *res = halloc( context, sizeof( string_buffer_t ) );
|
|
|
|
if( !res )
|
2006-07-03 18:39:57 +08:00
|
|
|
DIE_MEM();
|
2006-02-09 23:50:20 +08:00
|
|
|
sb_init( res );
|
2007-02-24 21:19:32 +08:00
|
|
|
halloc_register_function( context?context:res, (void (*)(void *)) &sb_destroy, res );
|
2006-02-09 23:50:20 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2006-06-20 08:50:10 +08:00
|
|
|
/**
|
|
|
|
A function that takes a single parameter, which is a function pointer, and calls it.
|
|
|
|
*/
|
2006-02-09 23:50:20 +08:00
|
|
|
static void halloc_passthrough( void *f )
|
|
|
|
{
|
|
|
|
void (*func)() = (void (*)() )f;
|
|
|
|
func();
|
|
|
|
}
|
|
|
|
|
|
|
|
void halloc_register_function_void( void *context, void (*func)() )
|
|
|
|
{
|
|
|
|
halloc_register_function( context, &halloc_passthrough, (void *)func );
|
|
|
|
}
|
|
|
|
|
|
|
|
void *halloc_register( void *context, void *data )
|
|
|
|
{
|
|
|
|
if( !data )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
halloc_register_function( context, &free, data );
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2006-06-12 22:12:33 +08:00
|
|
|
wchar_t *halloc_wcsdup( void *context, const wchar_t *in )
|
2006-02-11 08:13:17 +08:00
|
|
|
{
|
|
|
|
size_t len=wcslen(in);
|
|
|
|
wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1));
|
|
|
|
|
|
|
|
if( out == 0 )
|
|
|
|
{
|
2006-07-03 18:39:57 +08:00
|
|
|
DIE_MEM();
|
2006-02-11 08:13:17 +08:00
|
|
|
}
|
|
|
|
memcpy( out, in, sizeof( wchar_t)*(len+1));
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
wchar_t *halloc_wcsndup( void * context, const wchar_t *in, int c )
|
|
|
|
{
|
|
|
|
wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) );
|
|
|
|
if( res == 0 )
|
|
|
|
{
|
2006-07-03 18:39:57 +08:00
|
|
|
DIE_MEM();
|
2006-02-11 08:13:17 +08:00
|
|
|
}
|
2006-02-21 22:46:42 +08:00
|
|
|
wcslcpy( res, in, c+1 );
|
2006-02-11 08:13:17 +08:00
|
|
|
res[c] = L'\0';
|
|
|
|
return res;
|
|
|
|
}
|