Index: libroar/memmgr.c
===================================================================
--- libroar/memmgr.c	(revision 5755)
+++ libroar/memmgr.c	(revision 5757)
@@ -49,9 +49,88 @@
 #define _err(x) do { roar_err_set((x)); return NULL; } while (0)
 
+#ifdef ROAR_HAVE_CALLOC
+static void *  __libroar_calloc   (void * userdata, size_t nmemb, size_t size) {
+ void * ret;
+ roar_err_clear_all();
+ ret  = calloc(nmemb, size);
+ roar_err_update();
+ return ret;
+}
+#endif
+#ifdef ROAR_HAVE_MALLOC
+static void *  __libroar_malloc   (void * userdata, size_t size) {
+ void * ret;
+ roar_err_clear_all();
+ ret  = malloc(size);
+ roar_err_update();
+ return ret;
+}
+#endif
+#ifdef ROAR_HAVE_FREE
+static int     __libroar_free     (void * userdata, void * ptr) {
+ free(ptr);
+ return 0;
+}
+#endif
+#ifdef ROAR_HAVE_REALLOC
+static void *  __libroar_realloc  (void * userdata, void * ptr, size_t size) {
+ void * ret;
+ roar_err_clear_all();
+ ret  = realloc(ptr, size);
+ roar_err_update();
+ return ret;
+}
+#endif
+
+static const struct roar_libroar_memmgrapi __memory_default_api = {
+#ifdef ROAR_HAVE_CALLOC
+ .calloc = __libroar_calloc,
+#else
+ .calloc = NULL,
+#endif
+#ifdef ROAR_HAVE_MALLOC
+ .malloc = __libroar_malloc,
+#else
+ .malloc = NULL,
+#endif
+#ifdef ROAR_HAVE_FREE
+ .free = __libroar_free,
+#else
+ .free = NULL,
+#endif
+#ifdef ROAR_HAVE_REALLOC
+ .realloc = __libroar_realloc,
+#else
+ .realloc = NULL,
+#endif
+ .reset = NULL, // not needed
+ .sizeofbuf = NULL, // not supported
+
+ // Not yet supported:
+ .mlock = NULL,
+ .munlock = NULL,
+ .mlockall = NULL,
+ .munlockall = NULL,
+
+ // no need with C API.
+ .userdata = NULL
+};
+
+static const struct roar_libroar_memmgrapi * memory_api = &__memory_default_api;
+
+int    roar_libroar_set_memmgrapi(const struct roar_libroar_memmgrapi * api) {
+ if ( api == NULL )
+  memory_api = &__memory_default_api;
+ memory_api = api;
+ return 0;
+}
+
 #ifdef ROAR_USE_MEMMGR
-
 int     roar_mm_reset(void) {
  // currently this does nothing.
  // we need to free pools and such here later.
+
+ if ( memory_api->reset != NULL )
+  return memory_api->reset(memory_api->userdata);
  return 0;
 }
@@ -66,4 +145,7 @@
   return 0;
 
+ if ( memory_api->sizeofbuf != NULL )
+  return memory_api->sizeofbuf(memory_api->userdata, buf);
+
  roar_err_set(ROAR_ERROR_NOTSUP);
  return -1;
@@ -78,26 +160,18 @@
  }
 
-#ifdef ROAR_HAVE_CALLOC
- roar_err_clear_all();
- ret = calloc(nmemb, size);
-
- if ( ret == NULL )
-  roar_err_update();
-
- return ret;
-#else
- ret = roar_mm_malloc(nmemb*size);
- if ( ret == NULL )
-  return NULL;
-
- memset(ret, 0, nmemb*size);
-
- return ret;
-#endif
+ if ( memory_api->calloc != NULL ) {
+  return memory_api->calloc(memory_api->userdata, nmemb, size);
+ } else {
+  ret = roar_mm_malloc(nmemb*size);
+  if ( ret == NULL )
+   return NULL;
+
+  memset(ret, 0, nmemb*size);
+
+  return ret;
+ }
 }
 
 void * roar_mm_malloc(size_t size) {
- void * ret;
-
  if ( size == 0 ) {
   _libroar_null_buffer_check();
@@ -105,19 +179,13 @@
  }
 
-#ifdef ROAR_HAVE_MALLOC
- roar_err_clear_all();
- ret = malloc(size);
-
- if ( ret == NULL )
-  roar_err_update();
-
- return ret;
-#elif defined(ROAR_HAVE_CALLOC)
- return roar_mm_calloc(1, size);
-#elif defined(ROAR_HAVE_REALLOC)
- return roar_mm_realloc(NULL, size);
-#else
- _err(ROAR_ERROR_NOSYS);
-#endif
+ if ( memory_api->malloc != NULL ) {
+  return memory_api->malloc(memory_api->userdata, size);
+ } else if ( memory_api->calloc != NULL ) {
+  return roar_mm_calloc(1, size);
+ } else if ( memory_api->realloc != NULL ) {
+  return roar_mm_realloc(NULL, size);
+ } else {
+  _err(ROAR_ERROR_NOSYS);
+ }
 }
 
@@ -129,22 +197,19 @@
  }
 
-#ifdef ROAR_HAVE_FREE
- free(ptr);
- return 0;
-#elif defined(ROAR_HAVE_REALLOC)
- if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer )
-  return -1;
- return 0;
-#else
- roar_err_set(ROAR_ERROR_NOSYS);
- return -1;
-#endif
+ if ( memory_api->free != NULL ) {
+  return memory_api->free(memory_api->userdata, ptr);
+ } else if ( memory_api->realloc != NULL ) {
+  if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer )
+   return -1;
+  return 0;
+ } else {
+  roar_err_set(ROAR_ERROR_NOSYS);
+  return -1;
+ }
 }
 
 void * roar_mm_realloc(void *ptr, size_t size) {
  void * ret;
-#ifndef ROAR_HAVE_REALLOC
  ssize_t len;
-#endif
 
  if ( ptr == NULL )
@@ -157,25 +222,19 @@
  }
 
-#ifdef ROAR_HAVE_REALLOC
- roar_err_clear_all();
- ret = realloc(ptr, size);
-
- if ( ret == NULL )
-  roar_err_update();
-
- return ret;
-#else
- len = roar_mm_sizeof(ptr);
- if ( len == -1 )
-  return NULL;
-
- ret = roar_mm_malloc(size); 
- if ( ret == NULL )
-  return NULL;
-
- memcpy(ret, ptr, len > (ssize_t)size ? size : len);
-
- return ret;
-#endif
+ if ( memory_api->realloc != NULL ) {
+  return memory_api->realloc(memory_api->userdata, ptr, size);
+ } else {
+  len = roar_mm_sizeof(ptr);
+  if ( len == -1 )
+   return NULL;
+
+  ret = roar_mm_malloc(size); 
+  if ( ret == NULL )
+   return NULL;
+
+  memcpy(ret, ptr, len > (ssize_t)size ? size : len);
+
+  return ret;
+ }
 }
 #endif
