fix timeout of test_service, misc signed/unsigned and unused argument issues
[oweals/gnunet.git] / src / util / common_allocation.c
index cd7175eacdf714ea45f771363fab8a79bc0bd066..be2538c3f4c941661bb5e1c012df2baccf27210c 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2001, 2002, 2003, 2005, 2006 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2001, 2002, 2003, 2005, 2006 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -32,9 +32,9 @@
 #include <malloc/malloc.h>
 #endif
 
-#define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__)
+#define LOG(kind,...) GNUNET_log_from (kind, "util-common-allocation",__VA_ARGS__)
 
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-common-allocation", syscall)
 
 #ifndef INT_MAX
 #define INT_MAX 0x7FFFFFFF
@@ -85,6 +85,82 @@ GNUNET_xmalloc_ (size_t size,
 }
 
 
+/**
+ * Allocate memory for a two dimensional array in one block
+ * and set up pointers. Aborts if no more memory is available.
+ * Don't use GNUNET_xnew_array_2d_ directly. Use the
+ * #GNUNET_new_array_2d macro.
+ * The memory of the elements will be zero'ed out.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param elementSize size of a single element in bytes
+ * @param filename where is this call being made (for debugging)
+ * @param linenumber line where this call is being made (for debugging)
+ * @return allocated memory, never NULL
+ */
+void **
+GNUNET_xnew_array_2d_ (size_t n,
+                      size_t m,
+                      size_t elementSize,
+                       const char *filename,
+                      int linenumber)
+{
+       /* use char pointer internally to avoid void pointer arithmetic warnings */
+       char **ret = GNUNET_xmalloc_ (n * sizeof (void *) +  /* 1. dim header */
+                                     n * m * elementSize,   /* element data */
+                                     filename, linenumber);
+
+       for (size_t i = 0; i < n; i++)
+               ret[i] = (char *)ret +          /* base address */
+                        n * sizeof (void *) +  /* skip 1. dim header */
+                        i * m * elementSize;   /* skip to 2. dim row header */
+       return (void **)ret;
+}
+
+
+/**
+ * Allocate memory for a three dimensional array in one block
+ * and set up pointers. Aborts if no more memory is available.
+ * Don't use GNUNET_xnew_array_3d_ directly. Use the
+ * #GNUNET_new_array_3d macro.
+ * The memory of the elements will be zero'ed out.
+ *
+ * @param n size of the first dimension
+ * @param m size of the second dimension
+ * @param o size of the third dimension
+ * @param elementSize size of a single element in bytes
+ * @param filename where is this call being made (for debugging)
+ * @param linenumber line where this call is being made (for debugging)
+ * @return allocated memory, never NULL
+ */
+void ***
+GNUNET_xnew_array_3d_ (size_t n, size_t m, size_t o, size_t elementSize,
+                       const char *filename, int linenumber)
+{
+       /* use char pointer internally to avoid void pointer arithmetic warnings */
+       char ***ret = GNUNET_xmalloc_ (n * sizeof (void **) +    /* 1. dim header */
+                                      n * m * sizeof (void *) + /* 2. dim header */
+                                      n * m * o * elementSize,  /* element data */
+                                      filename, linenumber);
+
+       for (size_t i = 0; i < n; i++)
+       {
+               /* need to cast to (char *) temporarily for byte level acuracy */
+               ret[i] = (char **)((char *)ret +             /* base address */
+                                  n * sizeof (void **) +    /* skip 1. dim header */
+                                  i * m * sizeof (void *)); /* skip to 2. dim header */
+               for (size_t j = 0; j < m; j++)
+                       ret[i][j] = (char *)ret +              /* base address */
+                                   n * sizeof (void **) +     /* skip 1. dim header */
+                                   n * m * sizeof (void *) +  /* skip 2. dim header */
+                                   i * m * o * elementSize +  /* skip to 2. dim part */
+                                       j * o * elementSize;   /* skip to 3. dim row data */
+       }
+       return (void ***)ret;
+}
+
+
 /**
  * Allocate and initialize memory. Checks the return value, aborts if no more
  * memory is available.  Don't use #GNUNET_xmemdup_() directly. Use the
@@ -124,7 +200,7 @@ GNUNET_xmemdup_ (const void *buf,
   ret = &((size_t *) ret)[1];
   mem_used += size;
 #endif
-  memcpy (ret, buf, size);
+  GNUNET_memcpy (ret, buf, size);
   return ret;
 }
 
@@ -145,6 +221,8 @@ GNUNET_xmalloc_unchecked_ (size_t size,
 {
   void *result;
 
+  (void) filename;
+  (void) linenumber;
 #ifdef W32_MEM_LIMIT
   size += sizeof (size_t);
   if (mem_used + size > W32_MEM_LIMIT)
@@ -169,6 +247,7 @@ GNUNET_xmalloc_unchecked_ (size_t size,
 /**
  * Reallocate memory. Checks the return value, aborts if no more
  * memory is available.
+ * The content of the intersection of the new and old size will be unchanged.
  *
  * @param ptr the pointer to reallocate
  * @param n how many bytes of memory to allocate
@@ -178,10 +257,13 @@ GNUNET_xmalloc_unchecked_ (size_t size,
  */
 void *
 GNUNET_xrealloc_ (void *ptr,
-                 size_t n,
-                 const char *filename,
-                 int linenumber)
+                  size_t n,
+                  const char *filename,
+                  int linenumber)
 {
+  (void) filename;
+  (void) linenumber;
+
 #ifdef W32_MEM_LIMIT
   n += sizeof (size_t);
   ptr = &((size_t *) ptr)[-1];
@@ -190,7 +272,8 @@ GNUNET_xrealloc_ (void *ptr,
   ptr = realloc (ptr, n);
   if ((NULL == ptr) && (n > 0))
   {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "realloc");
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+                 "realloc");
     GNUNET_assert (0);
   }
 #ifdef W32_MEM_LIMIT
@@ -224,8 +307,8 @@ GNUNET_xrealloc_ (void *ptr,
  * want to keep track of allocations.
  *
  * @param ptr the pointer to free
- * @param filename where in the code was the call to GNUNET_array_grow
- * @param linenumber where in the code was the call to GNUNET_array_grow
+ * @param filename where in the code was the call to GNUNET_free
+ * @param linenumber where in the code was the call to GNUNET_free
  */
 void
 GNUNET_xfree_ (void *ptr,
@@ -249,7 +332,7 @@ GNUNET_xfree_ (void *ptr,
 
     for (i=0;i<s/8;i++)
       base[i] = baadfood;
-    memcpy (&base[s/8], &baadfood, s % 8);
+    GNUNET_memcpy (&base[s/8], &baadfood, s % 8);
   }
 #endif
 #endif
@@ -280,7 +363,7 @@ GNUNET_xstrdup_ (const char *str,
   res = GNUNET_xmalloc_ (slen,
                         filename,
                         linenumber);
-  memcpy (res,
+  GNUNET_memcpy (res,
          str,
          slen);
   return res;
@@ -329,7 +412,7 @@ GNUNET_xstrndup_ (const char *str,
   res = GNUNET_xmalloc_ (len + 1,
                         filename,
                         linenumber);
-  memcpy (res, str, len);
+  GNUNET_memcpy (res, str, len);
   /* res[len] = '\0'; 'malloc' zeros out anyway */
   return res;
 }
@@ -351,7 +434,7 @@ void
 GNUNET_xgrow_ (void **old,
               size_t elementSize,
               unsigned int *oldCount,
-               unsigned int newCount,
+         unsigned int newCount,
               const char *filename,
               int linenumber)
 {
@@ -360,21 +443,20 @@ GNUNET_xgrow_ (void **old,
 
   GNUNET_assert_at (INT_MAX / elementSize > newCount, filename, linenumber);
   size = newCount * elementSize;
-  if (size == 0)
+  if (0 == size)
   {
     tmp = NULL;
   }
   else
   {
     tmp = GNUNET_xmalloc_ (size, filename, linenumber);
-    memset (tmp, 0, size);      /* client code should not rely on this, though... */
-    if (*oldCount > newCount)
-      *oldCount = newCount;     /* shrink is also allowed! */
     if (NULL != *old)
-      memcpy (tmp, *old, elementSize * (*oldCount));
+    {
+      GNUNET_memcpy (tmp, *old, elementSize * GNUNET_MIN(*oldCount, newCount));
+    }
   }
 
-  if (*old != NULL)
+  if (NULL != *old)
   {
     GNUNET_xfree_ (*old, filename, linenumber);
   }
@@ -428,9 +510,13 @@ GNUNET_snprintf (char *buf,
   va_list args;
 
   va_start (args, format);
-  ret = VSNPRINTF (buf, size, format, args);
+  ret = VSNPRINTF (buf,
+                  size,
+                  format,
+                  args);
   va_end (args);
-  GNUNET_assert (ret < size);
+  GNUNET_assert ( (ret >= 0) &&
+                 (((size_t) ret) < size) );
   return ret;
 }
 
@@ -450,7 +536,9 @@ GNUNET_copy_message (const struct GNUNET_MessageHeader *msg)
   msize = ntohs (msg->size);
   GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
   ret = GNUNET_malloc (msize);
-  memcpy (ret, msg, msize);
+  GNUNET_memcpy (ret,
+                msg,
+                msize);
   return ret;
 }