Browse Source

Introduce memory allocation utlity functions

Also, all the allocations done by the hipack parser go through a function
pointer that is user-settable, which allows for integrating a custom memory
allocator.
Adrian Perez de Castro 4 years ago
parent
commit
6c3f2d5821
3 changed files with 82 additions and 0 deletions
  1. 1 0
      Makefile
  2. 53 0
      hipack-alloc.c
  3. 28 0
      hipack.h

+ 1 - 0
Makefile

@@ -2,6 +2,7 @@ CFLAGS += -std=c99
 hipack_PATH ?= .
 hipack_OBJS = ${hipack_PATH}/hipack-parser.o \
 			  ${hipack_PATH}/hipack-string.o \
+			  ${hipack_PATH}/hipack-alloc.o \
 			  ${hipack_PATH}/hipack-list.o \
 			  ${hipack_PATH}/hipack-dict.o
 hipack = ${hipack_PATH}/libhipack.a

+ 53 - 0
hipack-alloc.c

@@ -0,0 +1,53 @@
+/*
+ * hipack-alloc.c
+ * Copyright (C) 2015 Adrian Perez <aperez@igalia.com>
+ *
+ * Distributed under terms of the MIT license.
+ */
+
+#include "hipack.h"
+#include <sys/types.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+void* (*hipack_alloc) (void*, size_t) = hipack_alloc_stdlib;
+
+
+void*
+hipack_alloc_stdlib (void *optr, size_t size)
+{
+    if (size) {
+        optr = optr ?  realloc (optr, size) : malloc (size);
+        if (!optr) {
+            fprintf (stderr, "aborted: %s\n", strerror (errno));
+            fflush (stderr);
+            abort ();
+        }
+    } else {
+        free (optr);
+        optr = NULL;
+    }
+    return optr;
+}
+
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW	((size_t)1 << (sizeof(size_t) * 4))
+
+void*
+hipack_alloc_array_extra (void *optr, size_t nmemb, size_t size, size_t extra)
+{
+	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+        nmemb > 0 && SIZE_MAX / nmemb < size) {
+        fprintf (stderr, "aborted: %s\n", strerror (ENOMEM));
+        fflush (stderr);
+        abort ();
+    }
+	return (*hipack_alloc) (optr, size * nmemb + extra);
+}
+
+

+ 28 - 0
hipack.h

@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <stdint.h>
+#include <string.h>
 #include <stdbool.h>
 
 
@@ -24,6 +25,33 @@ typedef enum {
 } hipack_type_t;
 
 
+extern void* (*hipack_alloc) (void*, size_t);
+extern void* hipack_alloc_stdlib (void*, size_t);
+extern void* hipack_alloc_array_extra (void*, size_t nmemb, size_t size, size_t extra);
+
+
+static inline void*
+hipack_alloc_bzero (size_t size)
+{
+    assert (size > 0);
+    return memset ((*hipack_alloc) (NULL, size), 0, size);
+}
+
+
+static inline void*
+hipack_alloc_array (void *optr, size_t nmemb, size_t size)
+{
+    return hipack_alloc_array_extra (optr, nmemb, size, 0);
+}
+
+
+static inline void
+hipack_alloc_free (void *optr)
+{
+    (*hipack_alloc) (optr, 0);
+}
+
+
 /* Forward declarations. */
 typedef struct hipack_value     hipack_value_t;
 typedef struct hipack_string    hipack_string_t;