avro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bru...@apache.org
Subject svn commit: r1057683 - in /avro/trunk: ./ lang/c/src/ lang/c/tests/
Date Tue, 11 Jan 2011 15:07:08 GMT
Author: brucem
Date: Tue Jan 11 15:07:07 2011
New Revision: 1057683

URL: http://svn.apache.org/viewvc?rev=1057683&view=rev
Log:
AVRO-549. Custom allocator interface.

You can now provide a custom allocation function, which the Avro library
will use for all of the memory that it obtains.  The allocator function
prototype is the same one used by the Lua interpreter; it's a generic
function that includes the functionality of malloc, realloc, and free.
It takes in the old pointer (ptr), the old size (osize), and the new
size (nsize) of the buffer.  For realloc, all three have real values.
For malloc, ptr will be NULL, and osize 0.  For free, nsize will be 0.

One wrinkle is that we have to be able to provide the allocated size of
the buffer when we free it, since we have to provide a value for osize.
For most of our allocations, this isn't a problem, since we allocated a
fixed-size buffer for a struct of some kind.  It's also not a problem
for the buffers associated with a bytes or fixed field, since we have
the buffer size right there.  For strings, however, we have to be more
clever; for most cases, our strdup replacement adds additional space to
the buffer to store its size.  This prevents us from having to add lots
of additional size_t fields all over the place.  We can't do this in the
string datum, however, since the givestring methods need to be able to
take in an arbitrary string pointer; this means we can't assume it has
our special size prefix.

Added:
    avro/trunk/lang/c/src/allocation.c
    avro/trunk/lang/c/src/allocation.h
Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/c/src/CMakeLists.txt
    avro/trunk/lang/c/src/Makefile.am
    avro/trunk/lang/c/src/avro.h
    avro/trunk/lang/c/src/datafile.c
    avro/trunk/lang/c/src/datum.c
    avro/trunk/lang/c/src/datum.h
    avro/trunk/lang/c/src/datum_read.c
    avro/trunk/lang/c/src/encoding.h
    avro/trunk/lang/c/src/encoding_binary.c
    avro/trunk/lang/c/src/io.c
    avro/trunk/lang/c/src/schema.c
    avro/trunk/lang/c/src/st.c
    avro/trunk/lang/c/tests/test_avro_data.c

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Tue Jan 11 15:07:07 2011
@@ -56,6 +56,9 @@ Avro 1.5.0 (unreleased)
     AVRO-159 Java: Allow maven builds to use avro: avro-maven-plugin
     (Hiram Chirino, Patrick Hunt via Scott Carey)
 
+    AVRO-549. C: Route all memory allocations through an interface. (Douglas
+    Creager via brucem)
+
   IMPROVEMENTS
 
     AVRO-682. Java: Add method DataFileStream.getMetaKeys().

Modified: avro/trunk/lang/c/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/CMakeLists.txt?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/CMakeLists.txt (original)
+++ avro/trunk/lang/c/src/CMakeLists.txt Tue Jan 11 15:07:07 2011
@@ -18,6 +18,8 @@
 #
 
 set(AVRO_SRC
+    allocation.h
+    allocation.c
     avro.h
     avro_private.h
     datafile.c

Modified: avro/trunk/lang/c/src/Makefile.am
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/Makefile.am?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/Makefile.am (original)
+++ avro/trunk/lang/c/src/Makefile.am Tue Jan 11 15:07:07 2011
@@ -9,6 +9,7 @@ lib_LTLIBRARIES = libavro.la
 libavro_la_SOURCES = st.c st.h schema.c schema.h schema_equal.c \
 datum.c datum_equal.c datum_validate.c datum_read.c datum_skip.c datum_write.c datum_size.c datum.h \
 io.c dump.c dump.h encoding_binary.c \
+allocation.h allocation.c \
 avro_private.h encoding.h datafile.c
 libavro_la_LIBADD = $(top_builddir)/jansson/src/.libs/libjansson.a
 libavro_la_LDFLAGS = \

Added: avro/trunk/lang/c/src/allocation.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/allocation.c?rev=1057683&view=auto
==============================================================================
--- avro/trunk/lang/c/src/allocation.c (added)
+++ avro/trunk/lang/c/src/allocation.c Tue Jan 11 15:07:07 2011
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0 
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.  See the License for the specific language governing
+ * permissions and limitations under the License. 
+ */
+
+#include <string.h>
+
+#include "avro.h"
+#include "avro_private.h"
+#include "allocation.h"
+
+static void *
+avro_default_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
+{
+	AVRO_UNUSED(ud);
+	AVRO_UNUSED(osize);
+
+	if (nsize == 0) {
+		free(ptr);
+		return NULL;
+	} else {
+		return realloc(ptr, nsize);
+	}
+}
+
+struct allocator_state  AVRO_CURRENT_ALLOCATOR = {
+	avro_default_allocator,
+	NULL
+};
+
+void avro_set_allocator(avro_allocator_t alloc, void *user_data)
+{
+	AVRO_CURRENT_ALLOCATOR.alloc = alloc;
+	AVRO_CURRENT_ALLOCATOR.user_data = user_data;
+}
+
+void *avro_calloc(size_t count, size_t size)
+{
+	void  *ptr = avro_malloc(count * size);
+	if (ptr != NULL) {
+		memset(ptr, 0, count * size);
+	}
+	return ptr;
+}
+
+char *avro_strdup(const char *str)
+{
+	if (str == NULL) {
+		return NULL;
+	}
+
+	size_t  str_size = strlen(str)+1;
+	size_t  buf_size = str_size + sizeof(size_t);
+
+	void  *buf = avro_malloc(buf_size);
+	if (buf == NULL) {
+		return NULL;
+	}
+
+	size_t  *size = buf;
+	char  *new_str = (char *) (size + 1);
+
+	*size = buf_size;
+	memcpy(new_str, str, str_size);
+
+	//fprintf(stderr, "--- new  %zu %p %s\n", *size, new_str, new_str);
+	return new_str;
+}
+
+void avro_str_free(char *str)
+{
+	size_t  *size = ((size_t *) str) - 1;
+	//fprintf(stderr, "--- free %zu %p %s\n", *size, str, str);
+	avro_free(size, *size);
+}

Added: avro/trunk/lang/c/src/allocation.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/allocation.h?rev=1057683&view=auto
==============================================================================
--- avro/trunk/lang/c/src/allocation.h (added)
+++ avro/trunk/lang/c/src/allocation.h Tue Jan 11 15:07:07 2011
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0 
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.  See the License for the specific language governing
+ * permissions and limitations under the License. 
+ */
+
+#ifndef AVRO_ALLOCATION_H
+#define AVRO_ALLOCATION_H
+#include <stdlib.h>
+#include "avro.h"		/* for avro_schema_t */
+
+struct allocator_state {
+	avro_allocator_t  alloc;
+	void  *user_data;
+};
+
+extern struct allocator_state  AVRO_CURRENT_ALLOCATOR;
+
+#define avro_realloc(ptr, osz, nsz)          \
+	(AVRO_CURRENT_ALLOCATOR.alloc        \
+	 (AVRO_CURRENT_ALLOCATOR.user_data,  \
+	  (ptr), (osz), (nsz)))
+
+#define avro_malloc(sz) (avro_realloc(NULL, 0, (sz)))
+#define avro_free(ptr, osz) (avro_realloc((ptr), (osz), 0))
+
+#define avro_new(type) (avro_realloc(NULL, 0, sizeof(type)))
+#define avro_freet(type, ptr) (avro_realloc((ptr), sizeof(type), 0))
+
+void *avro_calloc(size_t count, size_t size);
+
+/*
+ * This is probably too clever for our own good, but when we duplicate a
+ * string, we actually store its size in the same allocated memory
+ * buffer.  That lets us free the string later, without having to call
+ * strlen to get its size, and without the containing struct having to
+ * manually store the strings length.
+ *
+ * This means that any string return by avro_strdup MUST be freed using
+ * avro_str_free, and the only thing that can be passed into
+ * avro_str_free is a string created via avro_strdup.
+ */
+
+char *avro_strdup(const char *str);
+void avro_str_free(char *str);
+
+#endif

Modified: avro/trunk/lang/c/src/avro.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/avro.h?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/avro.h (original)
+++ avro/trunk/lang/c/src/avro.h Tue Jan 11 15:07:07 2011
@@ -26,6 +26,28 @@ extern "C" {
 #include <stdio.h>
 #include <stdint.h>
 
+/*
+ * Allocation interface.  You can provide a custom allocator for the
+ * library, should you wish.  The allocator is provided as a single
+ * generic function, which can emulate the standard malloc, realloc, and
+ * free functions.  The design of this allocation interface is inspired
+ * by the implementation of the Lua interpreter.
+ *
+ * The ptr parameter will be the location of any existing memory
+ * buffer.  The osize parameter will be the size of this existing
+ * buffer.  If ptr is NULL, then osize will be 0.  The nsize parameter
+ * will be the size of the new buffer, or 0 if the new buffer should be
+ * freed.
+ *
+ * If nsize is 0, then the allocation function must return NULL.  If
+ * nsize is not 0, then it should return NULL if the allocation fails.
+ */
+
+typedef void *
+(*avro_allocator_t)(void *user_data, void *ptr, size_t osize, size_t nsize);
+
+void avro_set_allocator(avro_allocator_t alloc, void *user_data);
+
 enum avro_type_t {
 	AVRO_STRING,
 	AVRO_BYTES,

Modified: avro/trunk/lang/c/src/datafile.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/datafile.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/datafile.c (original)
+++ avro/trunk/lang/c/src/datafile.c Tue Jan 11 15:07:07 2011
@@ -16,6 +16,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include "encoding.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -137,13 +138,13 @@ avro_file_writer_create(const char *path
 	if (!path || !is_avro_schema(schema) || !writer) {
 		return EINVAL;
 	}
-	w = malloc(sizeof(struct avro_file_writer_t_));
+	w = avro_new(struct avro_file_writer_t_);
 	if (!w) {
 		return ENOMEM;
 	}
 	rval = file_writer_create(path, schema, w);
 	if (rval) {
-		free(w);
+		avro_freet(struct avro_file_writer_t_, w);
 		return rval;
 	}
 	*writer = w;
@@ -205,7 +206,7 @@ static int file_writer_open(const char *
 	/* Position to end of file and get ready to write */
 	rval = file_writer_init_fp(path, "a", w);
 	if (rval) {
-		free(w);
+		avro_freet(struct avro_file_writer_t_, w);
 	}
 	return rval;
 }
@@ -217,13 +218,13 @@ int avro_file_writer_open(const char *pa
 	if (!path || !writer) {
 		return EINVAL;
 	}
-	w = malloc(sizeof(struct avro_file_writer_t_));
+	w = avro_new(struct avro_file_writer_t_);
 	if (!w) {
 		return ENOMEM;
 	}
 	rval = file_writer_open(path, w);
 	if (rval) {
-		free(w);
+		avro_freet(struct avro_file_writer_t_, w);
 		return rval;
 	}
 
@@ -245,7 +246,7 @@ int avro_file_reader(const char *path, a
 {
 	int rval;
 	FILE *fp;
-	avro_file_reader_t r = malloc(sizeof(struct avro_file_reader_t_));
+	avro_file_reader_t r = avro_new(struct avro_file_reader_t_);
 	if (!r) {
 		return ENOMEM;
 	}
@@ -331,7 +332,7 @@ int avro_file_writer_close(avro_file_wri
 	check(rval, avro_file_writer_flush(w));
 	avro_writer_free(w->datum_writer);
 	avro_writer_free(w->writer);
-	free(w);
+	avro_freet(struct avro_file_writer_t_, w);
 	return 0;
 }
 
@@ -366,6 +367,6 @@ int avro_file_reader_close(avro_file_rea
 {
 	avro_schema_decref(reader->writers_schema);
 	avro_reader_free(reader->reader);
-	free(reader);
+	avro_freet(struct avro_file_reader_t_, reader);
 	return 0;
 }

Modified: avro/trunk/lang/c/src/datum.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/datum.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/datum.c (original)
+++ avro/trunk/lang/c/src/datum.c Tue Jan 11 15:07:07 2011
@@ -16,6 +16,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
@@ -31,15 +32,32 @@ static void avro_datum_init(avro_datum_t
 	datum->refcount = 1;
 }
 
-static avro_datum_t avro_string_private(char *str,
-					void (*string_free) (void *ptr))
+/* need this since avro_free is a macro */
+static void
+avro_free_wrapper(void *ptr, size_t sz)
+{
+	avro_free(ptr, sz);
+}
+
+static void
+avro_str_free_wrapper(void *ptr, size_t sz)
+{
+	// don't need this, since the size is stored in the string
+	// buffer
+	AVRO_UNUSED(sz);
+	avro_str_free(ptr);
+}
+
+static avro_datum_t avro_string_private(char *str, int64_t size,
+					avro_free_func_t string_free)
 {
 	struct avro_string_datum_t *datum =
-	    malloc(sizeof(struct avro_string_datum_t));
+	    avro_new(struct avro_string_datum_t);
 	if (!datum) {
 		return NULL;
 	}
 	datum->s = str;
+	datum->size = size;
 	datum->free = string_free;
 
 	avro_datum_init(&datum->obj, AVRO_STRING);
@@ -48,21 +66,22 @@ static avro_datum_t avro_string_private(
 
 avro_datum_t avro_string(const char *str)
 {
-	char *p = strdup(str);
+	char *p = avro_strdup(str);
 	if (!p) {
 		return NULL;
 	}
-	return avro_string_private(p, free);
+	return avro_string_private(p, 0, avro_str_free_wrapper);
 }
 
 avro_datum_t avro_givestring(const char *str)
 {
-	return avro_string_private((char *)str, free);
+	int64_t  sz = strlen(str)+1;
+	return avro_string_private((char *)str, sz, avro_free_wrapper);
 }
 
 avro_datum_t avro_wrapstring(const char *str)
 {
-	return avro_string_private((char *)str, NULL);
+	return avro_string_private((char *)str, 0, NULL);
 }
 
 int avro_string_get(avro_datum_t datum, char **p)
@@ -74,8 +93,9 @@ int avro_string_get(avro_datum_t datum, 
 	return 0;
 }
 
-static int avro_string_set_private(avro_datum_t datum, const char *p,
-				   void (*string_free) (void *ptr))
+static int avro_string_set_private(avro_datum_t datum,
+	       			   const char *p, int64_t size,
+				   avro_free_func_t string_free)
 {
 	struct avro_string_datum_t *string;
 	if (!(is_avro_datum(datum) && is_avro_string(datum)) || !p) {
@@ -83,42 +103,44 @@ static int avro_string_set_private(avro_
 	}
 	string = avro_datum_to_string(datum);
 	if (string->free) {
-		string->free(string->s);
+		string->free(string->s, string->size);
 	}
 	string->free = string_free;
 	string->s = (char *)p;
+	string->size = size;
 	return 0;
 }
 
 int avro_string_set(avro_datum_t datum, const char *p)
 {
-	char *string_copy = strdup(p);
+	char *string_copy = avro_strdup(p);
 	int rval;
 	if (!string_copy) {
 		return ENOMEM;
 	}
-	rval = avro_string_set_private(datum, p, free);
+	rval = avro_string_set_private(datum, p, 0, avro_str_free_wrapper);
 	if (rval) {
-		free(string_copy);
+		avro_str_free(string_copy);
 	}
 	return rval;
 }
 
 int avro_givestring_set(avro_datum_t datum, const char *p)
 {
-	return avro_string_set_private(datum, p, free);
+	int64_t  size = strlen(p)+1;
+	return avro_string_set_private(datum, p, size, avro_free_wrapper);
 }
 
 int avro_wrapstring_set(avro_datum_t datum, const char *p)
 {
-	return avro_string_set_private(datum, p, NULL);
+	return avro_string_set_private(datum, p, 0, NULL);
 }
 
 static avro_datum_t avro_bytes_private(char *bytes, int64_t size,
-				       void (*bytes_free) (void *ptr))
+				       avro_free_func_t bytes_free)
 {
 	struct avro_bytes_datum_t *datum;
-	datum = malloc(sizeof(struct avro_bytes_datum_t));
+	datum = avro_new(struct avro_bytes_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -132,17 +154,22 @@ static avro_datum_t avro_bytes_private(c
 
 avro_datum_t avro_bytes(const char *bytes, int64_t size)
 {
-	char *bytes_copy = malloc(size);
+	char *bytes_copy = avro_malloc(size);
 	if (!bytes_copy) {
 		return NULL;
 	}
 	memcpy(bytes_copy, bytes, size);
-	return avro_bytes_private(bytes_copy, size, free);
+	avro_datum_t  result =
+		avro_bytes_private(bytes_copy, size, avro_free_wrapper);
+	if (result == NULL) {
+		avro_free(bytes_copy, size);
+	}
+	return result;
 }
 
 avro_datum_t avro_givebytes(const char *bytes, int64_t size)
 {
-	return avro_bytes_private((char *)bytes, size, free);
+	return avro_bytes_private((char *)bytes, size, avro_free_wrapper);
 }
 
 avro_datum_t avro_wrapbytes(const char *bytes, int64_t size)
@@ -152,19 +179,17 @@ avro_datum_t avro_wrapbytes(const char *
 
 static int avro_bytes_set_private(avro_datum_t datum, const char *bytes,
 				  const int64_t size,
-				  void (*bytes_free) (void *ptr))
+				  avro_free_func_t bytes_free)
 {
 	struct avro_bytes_datum_t *b;
 
-	AVRO_UNUSED(size);
-
 	if (!(is_avro_datum(datum) && is_avro_bytes(datum))) {
 		return EINVAL;
 	}
 
 	b = avro_datum_to_bytes(datum);
 	if (b->free) {
-		b->free(b->bytes);
+		b->free(b->bytes, b->size);
 	}
 
 	b->free = bytes_free;
@@ -176,14 +201,14 @@ static int avro_bytes_set_private(avro_d
 int avro_bytes_set(avro_datum_t datum, const char *bytes, const int64_t size)
 {
 	int rval;
-	char *bytes_copy = malloc(size);
+	char *bytes_copy = avro_malloc(size);
 	if (!bytes_copy) {
 		return ENOMEM;
 	}
 	memcpy(bytes_copy, bytes, size);
-	rval = avro_bytes_set_private(datum, bytes, size, free);
+	rval = avro_bytes_set_private(datum, bytes, size, avro_free_wrapper);
 	if (rval) {
-		free(bytes_copy);
+		avro_free(bytes_copy, size);
 	}
 	return rval;
 }
@@ -191,7 +216,7 @@ int avro_bytes_set(avro_datum_t datum, c
 int avro_givebytes_set(avro_datum_t datum, const char *bytes,
 		       const int64_t size)
 {
-	return avro_bytes_set_private(datum, bytes, size, free);
+	return avro_bytes_set_private(datum, bytes, size, avro_free_wrapper);
 }
 
 int avro_wrapbytes_set(avro_datum_t datum, const char *bytes,
@@ -213,7 +238,7 @@ int avro_bytes_get(avro_datum_t datum, c
 avro_datum_t avro_int32(int32_t i)
 {
 	struct avro_int32_datum_t *datum =
-	    malloc(sizeof(struct avro_int32_datum_t));
+	    avro_new(struct avro_int32_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -246,7 +271,7 @@ int avro_int32_set(avro_datum_t datum, c
 avro_datum_t avro_int64(int64_t l)
 {
 	struct avro_int64_datum_t *datum =
-	    malloc(sizeof(struct avro_int64_datum_t));
+	    avro_new(struct avro_int64_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -279,7 +304,7 @@ int avro_int64_set(avro_datum_t datum, c
 avro_datum_t avro_float(float f)
 {
 	struct avro_float_datum_t *datum =
-	    malloc(sizeof(struct avro_float_datum_t));
+	    avro_new(struct avro_float_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -312,7 +337,7 @@ int avro_float_get(avro_datum_t datum, f
 avro_datum_t avro_double(double d)
 {
 	struct avro_double_datum_t *datum =
-	    malloc(sizeof(struct avro_double_datum_t));
+	    avro_new(struct avro_double_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -345,7 +370,7 @@ int avro_double_get(avro_datum_t datum, 
 avro_datum_t avro_boolean(int8_t i)
 {
 	struct avro_boolean_datum_t *datum =
-	    malloc(sizeof(struct avro_boolean_datum_t));
+	    avro_new(struct avro_boolean_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -387,7 +412,7 @@ avro_datum_t avro_null(void)
 avro_datum_t avro_union(int64_t discriminant, avro_datum_t value)
 {
 	struct avro_union_datum_t *datum =
-	    malloc(sizeof(struct avro_union_datum_t));
+	    avro_new(struct avro_union_datum_t);
 	if (!datum) {
 		return NULL;
 	}
@@ -454,38 +479,38 @@ int avro_union_set_discriminant(avro_dat
 avro_datum_t avro_record(const char *name, const char *space)
 {
 	struct avro_record_datum_t *datum =
-	    malloc(sizeof(struct avro_record_datum_t));
+	    avro_new(struct avro_record_datum_t);
 	if (!datum) {
 		return NULL;
 	}
-	datum->name = strdup(name);
+	datum->name = avro_strdup(name);
 	if (!datum->name) {
-		free(datum);
+		avro_freet(struct avro_record_datum_t, datum);
 		return NULL;
 	}
-	datum->space = space ? strdup(space) : NULL;
+	datum->space = space ? avro_strdup(space) : NULL;
 	if (space && !datum->space) {
-		free((void *)datum->name);
-		free((void *)datum);
+		avro_str_free((char *) datum->name);
+		avro_freet(struct avro_record_datum_t, datum);
 		return NULL;
 	}
 	datum->field_order = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!datum->field_order) {
 		if (space) {
-			free((void *)datum->space);
+			avro_str_free((char *) datum->space);
 		}
-		free((char *)datum->name);
-		free(datum);
+		avro_str_free((char *) datum->name);
+		avro_freet(struct avro_record_datum_t, datum);
 		return NULL;
 	}
 	datum->fields_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!datum->fields_byname) {
 		st_free_table(datum->field_order);
 		if (space) {
-			free((void *)datum->space);
+			avro_str_free((char *) datum->space);
 		}
-		free((char *)datum->name);
-		free(datum);
+		avro_str_free((char *) datum->name);
+		avro_freet(struct avro_record_datum_t, datum);
 		return NULL;
 	}
 
@@ -527,7 +552,7 @@ avro_record_set(avro_datum_t datum, cons
 			/* Inserting new value */
 			struct avro_record_datum_t *record =
 			    avro_datum_to_record(datum);
-			key = strdup(field_name);
+			key = avro_strdup(field_name);
 			if (!key) {
 				return ENOMEM;
 			}
@@ -546,11 +571,11 @@ avro_record_set(avro_datum_t datum, cons
 avro_datum_t avro_enum(const char *name, int i)
 {
 	struct avro_enum_datum_t *datum =
-	    malloc(sizeof(struct avro_enum_datum_t));
+	    avro_new(struct avro_enum_datum_t);
 	if (!datum) {
 		return NULL;
 	}
-	datum->name = strdup(name);
+	datum->name = avro_strdup(name);
 	datum->value = i;
 
 	avro_datum_init(&datum->obj, AVRO_ENUM);
@@ -595,14 +620,14 @@ int avro_enum_set_name(avro_datum_t datu
 
 static avro_datum_t avro_fixed_private(const char *name, const char *bytes,
 				       const int64_t size,
-				       void (*fixed_free) (void *ptr))
+				       avro_free_func_t fixed_free)
 {
 	struct avro_fixed_datum_t *datum =
-	    malloc(sizeof(struct avro_fixed_datum_t));
+	    avro_new(struct avro_fixed_datum_t);
 	if (!datum) {
 		return NULL;
 	}
-	datum->name = strdup(name);
+	datum->name = avro_strdup(name);
 	datum->size = size;
 	datum->bytes = (char *)bytes;
 	datum->free = fixed_free;
@@ -613,12 +638,12 @@ static avro_datum_t avro_fixed_private(c
 
 avro_datum_t avro_fixed(const char *name, const char *bytes, const int64_t size)
 {
-	char *bytes_copy = malloc(size);
+	char *bytes_copy = avro_malloc(size);
 	if (!bytes_copy) {
 		return NULL;
 	}
 	memcpy(bytes_copy, bytes, size);
-	return avro_fixed_private(name, bytes, size, free);
+	return avro_fixed_private(name, bytes, size, avro_free_wrapper);
 }
 
 avro_datum_t avro_wrapfixed(const char *name, const char *bytes,
@@ -630,12 +655,12 @@ avro_datum_t avro_wrapfixed(const char *
 avro_datum_t avro_givefixed(const char *name, const char *bytes,
 			    const int64_t size)
 {
-	return avro_fixed_private(name, bytes, size, free);
+	return avro_fixed_private(name, bytes, size, avro_free_wrapper);
 }
 
 static int avro_fixed_set_private(avro_datum_t datum, const char *bytes,
 				  const int64_t size,
-				  void (*fixed_free) (void *ptr))
+				  avro_free_func_t fixed_free)
 {
 	struct avro_fixed_datum_t *fixed;
 
@@ -647,7 +672,7 @@ static int avro_fixed_set_private(avro_d
 
 	fixed = avro_datum_to_fixed(datum);
 	if (fixed->free) {
-		fixed->free(fixed->bytes);
+		fixed->free(fixed->bytes, fixed->size);
 	}
 
 	fixed->free = fixed_free;
@@ -659,14 +684,14 @@ static int avro_fixed_set_private(avro_d
 int avro_fixed_set(avro_datum_t datum, const char *bytes, const int64_t size)
 {
 	int rval;
-	char *bytes_copy = malloc(size);
+	char *bytes_copy = avro_malloc(size);
 	if (!bytes_copy) {
 		return ENOMEM;
 	}
 	memcpy(bytes_copy, bytes, size);
-	rval = avro_fixed_set_private(datum, bytes, size, free);
+	rval = avro_fixed_set_private(datum, bytes, size, avro_free_wrapper);
 	if (rval) {
-		free(bytes_copy);
+		avro_free(bytes_copy, size);
 	}
 	return rval;
 }
@@ -674,7 +699,7 @@ int avro_fixed_set(avro_datum_t datum, c
 int avro_givefixed_set(avro_datum_t datum, const char *bytes,
 		       const int64_t size)
 {
-	return avro_fixed_set_private(datum, bytes, size, free);
+	return avro_fixed_set_private(datum, bytes, size, avro_free_wrapper);
 }
 
 int avro_wrapfixed_set(avro_datum_t datum, const char *bytes,
@@ -696,19 +721,19 @@ int avro_fixed_get(avro_datum_t datum, c
 avro_datum_t avro_map(void)
 {
 	struct avro_map_datum_t *datum =
-	    malloc(sizeof(struct avro_map_datum_t));
+	    avro_new(struct avro_map_datum_t);
 	if (!datum) {
 		return NULL;
 	}
 	datum->map = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!datum->map) {
-		free(datum);
+		avro_freet(struct avro_map_datum_t, datum);
 		return NULL;
 	}
 	datum->keys_by_index = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!datum->keys_by_index) {
 		st_free_table(datum->map);
-		free(datum);
+		avro_freet(struct avro_map_datum_t, datum);
 		return NULL;
 	}
 
@@ -785,7 +810,7 @@ avro_map_set(avro_datum_t datum, const c
 		avro_datum_decref(old_datum);
 	} else {
 		/* Inserting a new value */
-		save_key = strdup(key);
+		save_key = avro_strdup(key);
 		if (!save_key) {
 			return ENOMEM;
 		}
@@ -801,13 +826,13 @@ avro_map_set(avro_datum_t datum, const c
 avro_datum_t avro_array(void)
 {
 	struct avro_array_datum_t *datum =
-	    malloc(sizeof(struct avro_array_datum_t));
+	    avro_new(struct avro_array_datum_t);
 	if (!datum) {
 		return NULL;
 	}
 	datum->els = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!datum->els) {
-		free(datum);
+		avro_freet(struct avro_array_datum_t, datum);
 		return NULL;
 	}
 
@@ -859,7 +884,7 @@ static int char_datum_free_foreach(char 
 	AVRO_UNUSED(arg);
 
 	avro_datum_decref(datum);
-	free(key);
+	avro_str_free(key);
 	return ST_DELETE;
 }
 
@@ -880,48 +905,38 @@ static void avro_datum_free(avro_datum_t
 				struct avro_string_datum_t *string;
 				string = avro_datum_to_string(datum);
 				if (string->free) {
-					string->free(string->s);
+					string->free(string->s, string->size);
 				}
-				free(string);
+				avro_freet(struct avro_string_datum_t, string);
 			}
 			break;
 		case AVRO_BYTES:{
 				struct avro_bytes_datum_t *bytes;
 				bytes = avro_datum_to_bytes(datum);
 				if (bytes->free) {
-					bytes->free(bytes->bytes);
+					bytes->free(bytes->bytes, bytes->size);
 				}
-				free(bytes);
+				avro_freet(struct avro_bytes_datum_t, bytes);
 			}
 			break;
 		case AVRO_INT32:{
-				struct avro_int32_datum_t *i;
-				i = avro_datum_to_int32(datum);
-				free(i);
+				avro_freet(struct avro_int32_datum_t, datum);
 			}
 			break;
 		case AVRO_INT64:{
-				struct avro_int64_datum_t *l;
-				l = avro_datum_to_int64(datum);
-				free(l);
+				avro_freet(struct avro_int64_datum_t, datum);
 			}
 			break;
 		case AVRO_FLOAT:{
-				struct avro_float_datum_t *f;
-				f = avro_datum_to_float(datum);
-				free(f);
+				avro_freet(struct avro_float_datum_t, datum);
 			}
 			break;
 		case AVRO_DOUBLE:{
-				struct avro_double_datum_t *d;
-				d = avro_datum_to_double(datum);
-				free(d);
+				avro_freet(struct avro_double_datum_t, datum);
 			}
 			break;
 		case AVRO_BOOLEAN:{
-				struct avro_boolean_datum_t *b;
-				b = avro_datum_to_boolean(datum);
-				free(b);
+				avro_freet(struct avro_boolean_datum_t, datum);
 			}
 			break;
 		case AVRO_NULL:
@@ -931,32 +946,33 @@ static void avro_datum_free(avro_datum_t
 		case AVRO_RECORD:{
 				struct avro_record_datum_t *record;
 				record = avro_datum_to_record(datum);
-				free((void *)record->name);
+				avro_str_free((char *) record->name);
 				if (record->space) {
-					free((void *)record->space);
+					avro_str_free((char *) record->space);
 				}
 				st_foreach(record->fields_byname,
 					   char_datum_free_foreach, 0);
 				st_free_table(record->field_order);
 				st_free_table(record->fields_byname);
-				free(record);
+				avro_freet(struct avro_record_datum_t, record);
 			}
 			break;
 		case AVRO_ENUM:{
 				struct avro_enum_datum_t *enump;
 				enump = avro_datum_to_enum(datum);
-				free((void *)enump->name);
-				free(enump);
+				avro_str_free((char *) enump->name);
+				avro_freet(struct avro_enum_datum_t, enump);
 			}
 			break;
 		case AVRO_FIXED:{
 				struct avro_fixed_datum_t *fixed;
 				fixed = avro_datum_to_fixed(datum);
-				free((void *)fixed->name);
+				avro_str_free((char *) fixed->name);
 				if (fixed->free) {
-					fixed->free((void *)fixed->bytes);
+					fixed->free((void *)fixed->bytes,
+						    fixed->size);
 				}
-				free(fixed);
+				avro_freet(struct avro_fixed_datum_t, fixed);
 			}
 			break;
 		case AVRO_MAP:{
@@ -966,7 +982,7 @@ static void avro_datum_free(avro_datum_t
 					   0);
 				st_free_table(map->map);
 				st_free_table(map->keys_by_index);
-				free(map);
+				avro_freet(struct avro_map_datum_t, map);
 			}
 			break;
 		case AVRO_ARRAY:{
@@ -974,14 +990,14 @@ static void avro_datum_free(avro_datum_t
 				array = avro_datum_to_array(datum);
 				st_foreach(array->els, array_free_foreach, 0);
 				st_free_table(array->els);
-				free(array);
+				avro_freet(struct avro_array_datum_t, array);
 			}
 			break;
 		case AVRO_UNION:{
 				struct avro_union_datum_t *unionp;
 				unionp = avro_datum_to_union(datum);
 				avro_datum_decref(unionp->value);
-				free(unionp);
+				avro_freet(struct avro_union_datum_t, unionp);
 			}
 			break;
 		case AVRO_LINK:{

Modified: avro/trunk/lang/c/src/datum.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/datum.h?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/datum.h (original)
+++ avro/trunk/lang/c/src/datum.h Tue Jan 11 15:07:07 2011
@@ -21,17 +21,21 @@
 #include "avro_private.h"
 #include "st.h"
 
+typedef void
+(*avro_free_func_t)(void *ptr, size_t sz);
+
 struct avro_string_datum_t {
 	struct avro_obj_t obj;
 	char *s;
-	void (*free) (void *ptr);
+	int64_t size;
+	avro_free_func_t  free;
 };
 
 struct avro_bytes_datum_t {
 	struct avro_obj_t obj;
 	char *bytes;
 	int64_t size;
-	void (*free) (void *ptr);
+	avro_free_func_t  free;
 };
 
 struct avro_int32_datum_t {
@@ -64,7 +68,7 @@ struct avro_fixed_datum_t {
 	char *name;
 	char *bytes;
 	int64_t size;
-	void (*free) (void *ptr);
+	avro_free_func_t  free;
 };
 
 struct avro_map_datum_t {

Modified: avro/trunk/lang/c/src/datum_read.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/datum_read.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/datum_read.c (original)
+++ avro/trunk/lang/c/src/datum_read.c Tue Jan 11 15:07:07 2011
@@ -16,6 +16,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
@@ -185,8 +186,9 @@ read_map(avro_reader_t reader, const avr
 		}
 		for (i = 0; i < block_count; i++) {
 			char *key;
+			int64_t key_size;
 			avro_datum_t value;
-			rval = enc->read_string(reader, &key);
+			rval = enc->read_string(reader, &key, &key_size);
 			if (rval) {
 				return rval;
 			}
@@ -197,16 +199,16 @@ read_map(avro_reader_t reader, const avr
 					   avro_schema_to_map(readers_schema)->
 					   values, &value);
 			if (rval) {
-				free(key);
+				avro_free(key, key_size);
 				return rval;
 			}
 			rval = avro_map_set(map, key, value);
 			if (rval) {
-				free(key);
+				avro_free(key, key_size);
 				return rval;
 			}
 			avro_datum_decref(value);
-			free(key);
+			avro_free(key, key_size);
 		}
 		rval = enc->read_long(reader, &block_count);
 		if (rval) {
@@ -326,8 +328,9 @@ avro_read_data(avro_reader_t reader, avr
 
 	case AVRO_STRING:
 		{
+			int64_t len;
 			char *s;
-			rval = enc->read_string(reader, &s);
+			rval = enc->read_string(reader, &s, &len);
 			if (!rval) {
 				*datum = avro_givestring(s);
 			}
@@ -392,7 +395,7 @@ avro_read_data(avro_reader_t reader, avr
 			int64_t size =
 			    avro_schema_to_fixed(writers_schema)->size;
 
-			bytes = malloc(size);
+			bytes = avro_malloc(size);
 			if (!bytes) {
 				return ENOMEM;
 			}

Modified: avro/trunk/lang/c/src/encoding.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/encoding.h?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/encoding.h (original)
+++ avro/trunk/lang/c/src/encoding.h Tue Jan 11 15:07:07 2011
@@ -26,7 +26,7 @@ struct avro_encoding_t {
 	/*
 	 * string 
 	 */
-	int (*read_string) (avro_reader_t reader, char **s);
+	int (*read_string) (avro_reader_t reader, char **s, int64_t *len);
 	int (*skip_string) (avro_reader_t reader);
 	int (*write_string) (avro_writer_t writer, const char *s);
 	 int64_t(*size_string) (avro_writer_t writer, const char *s);

Modified: avro/trunk/lang/c/src/encoding_binary.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/encoding_binary.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/encoding_binary.c (original)
+++ avro/trunk/lang/c/src/encoding_binary.c Tue Jan 11 15:07:07 2011
@@ -16,6 +16,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include "encoding.h"
 #include <stdlib.h>
 #include <limits.h>
@@ -126,11 +127,10 @@ static int read_bytes(avro_reader_t read
 	if (rval) {
 		return rval;
 	}
-	*bytes = malloc(*len + 1);
+	*bytes = avro_malloc(*len);
 	if (!*bytes) {
 		return ENOMEM;
 	}
-	(*bytes)[*len] = '\0';
 	AVRO_READ(reader, *bytes, *len);
 	return 0;
 }
@@ -169,10 +169,21 @@ size_bytes(avro_writer_t writer, const c
 	return size_long(writer, len) + len;
 }
 
-static int read_string(avro_reader_t reader, char **s)
+static int read_string(avro_reader_t reader, char **s, int64_t *len)
 {
-	int64_t len;
-	return read_bytes(reader, s, &len);
+	int64_t  str_len;
+	int rval = read_long(reader, &str_len);
+	if (rval) {
+		return rval;
+	}
+	*len = str_len + 1;
+	*s = avro_malloc(*len);
+	if (!*s) {
+		return ENOMEM;
+	}
+	(*s)[str_len] = '\0';
+	AVRO_READ(reader, *s, str_len);
+	return 0;
 }
 
 static int skip_string(avro_reader_t reader)

Modified: avro/trunk/lang/c/src/io.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/io.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/io.c (original)
+++ avro/trunk/lang/c/src/io.c Tue Jan 11 15:07:07 2011
@@ -16,6 +16,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
@@ -89,7 +90,7 @@ static void writer_init(avro_writer_t wr
 avro_reader_t avro_reader_file(FILE * fp)
 {
 	struct _avro_reader_file_t *file_reader =
-	    malloc(sizeof(struct _avro_reader_file_t));
+	    avro_new(struct _avro_reader_file_t);
 	if (!file_reader) {
 		return NULL;
 	}
@@ -102,7 +103,7 @@ avro_reader_t avro_reader_file(FILE * fp
 avro_writer_t avro_writer_file(FILE * fp)
 {
 	struct _avro_writer_file_t *file_writer =
-	    malloc(sizeof(struct _avro_writer_file_t));
+	    avro_new(struct _avro_writer_file_t);
 	if (!file_writer) {
 		return NULL;
 	}
@@ -114,7 +115,7 @@ avro_writer_t avro_writer_file(FILE * fp
 avro_reader_t avro_reader_memory(const char *buf, int64_t len)
 {
 	struct _avro_reader_memory_t *mem_reader =
-	    malloc(sizeof(struct _avro_reader_memory_t));
+	    avro_new(struct _avro_reader_memory_t);
 	if (!mem_reader) {
 		return NULL;
 	}
@@ -128,7 +129,7 @@ avro_reader_t avro_reader_memory(const c
 avro_writer_t avro_writer_memory(const char *buf, int64_t len)
 {
 	struct _avro_writer_memory_t *mem_writer =
-	    malloc(sizeof(struct _avro_writer_memory_t));
+	    avro_new(struct _avro_writer_memory_t);
 	if (!mem_writer) {
 		return NULL;
 	}
@@ -346,19 +347,19 @@ void avro_reader_dump(avro_reader_t read
 void avro_reader_free(avro_reader_t reader)
 {
 	if (is_memory_io(reader)) {
-		free(avro_reader_to_memory(reader));
+		avro_freet(struct _avro_reader_memory_t, reader);
 	} else if (is_file_io(reader)) {
 		fclose(avro_reader_to_file(reader)->fp);
-		free(avro_reader_to_file(reader));
+		avro_freet(struct _avro_reader_file_t, reader);
 	}
 }
 
 void avro_writer_free(avro_writer_t writer)
 {
 	if (is_memory_io(writer)) {
-		free(avro_writer_to_memory(writer));
+		avro_freet(struct _avro_writer_memory_t, writer);
 	} else if (is_file_io(writer)) {
 		fclose(avro_writer_to_file(writer)->fp);
-		free(avro_writer_to_file(writer));
+		avro_freet(struct _avro_writer_file_t, writer);
 	}
 }

Modified: avro/trunk/lang/c/src/schema.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/schema.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/schema.c (original)
+++ avro/trunk/lang/c/src/schema.c Tue Jan 11 15:07:07 2011
@@ -16,6 +16,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>
@@ -68,9 +69,9 @@ static int record_free_foreach(int i, st
 	AVRO_UNUSED(i);
 	AVRO_UNUSED(arg);
 
-	free(field->name);
+	avro_str_free(field->name);
 	avro_schema_decref(field->type);
-	free(field);
+	avro_freet(struct avro_record_field_t, field);
 	return ST_DELETE;
 }
 
@@ -79,7 +80,7 @@ static int enum_free_foreach(int i, char
 	AVRO_UNUSED(i);
 	AVRO_UNUSED(arg);
 
-	free(sym);
+	avro_str_free(sym);
 	return ST_DELETE;
 }
 
@@ -110,35 +111,35 @@ static void avro_schema_free(avro_schema
 		case AVRO_RECORD:{
 				struct avro_record_schema_t *record;
 				record = avro_schema_to_record(schema);
-				free(record->name);
+				avro_str_free(record->name);
 				if (record->space) {
-					free(record->space);
+					avro_str_free(record->space);
 				}
 				st_foreach(record->fields, record_free_foreach,
 					   0);
 				st_free_table(record->fields_byname);
 				st_free_table(record->fields);
-				free(record);
+				avro_freet(struct avro_record_schema_t, record);
 			}
 			break;
 
 		case AVRO_ENUM:{
 				struct avro_enum_schema_t *enump;
 				enump = avro_schema_to_enum(schema);
-				free(enump->name);
+				avro_str_free(enump->name);
 				st_foreach(enump->symbols, enum_free_foreach,
 					   0);
 				st_free_table(enump->symbols);
 				st_free_table(enump->symbols_byname);
-				free(enump);
+				avro_freet(struct avro_enum_schema_t, enump);
 			}
 			break;
 
 		case AVRO_FIXED:{
 				struct avro_fixed_schema_t *fixed;
 				fixed = avro_schema_to_fixed(schema);
-				free((char *)fixed->name);
-				free(fixed);
+				avro_str_free((char *) fixed->name);
+				avro_freet(struct avro_fixed_schema_t, fixed);
 			}
 			break;
 
@@ -146,7 +147,7 @@ static void avro_schema_free(avro_schema
 				struct avro_map_schema_t *map;
 				map = avro_schema_to_map(schema);
 				avro_schema_decref(map->values);
-				free(map);
+				avro_freet(struct avro_map_schema_t, map);
 			}
 			break;
 
@@ -154,7 +155,7 @@ static void avro_schema_free(avro_schema
 				struct avro_array_schema_t *array;
 				array = avro_schema_to_array(schema);
 				avro_schema_decref(array->items);
-				free(array);
+				avro_freet(struct avro_array_schema_t, array);
 			}
 			break;
 		case AVRO_UNION:{
@@ -164,7 +165,7 @@ static void avro_schema_free(avro_schema
 					   0);
 				st_free_table(unionp->branches);
 				st_free_table(unionp->branches_byname);
-				free(unionp);
+				avro_freet(struct avro_union_schema_t, unionp);
 			}
 			break;
 
@@ -172,7 +173,7 @@ static void avro_schema_free(avro_schema
 				struct avro_link_schema_t *link;
 				link = avro_schema_to_link(schema);
 				avro_schema_decref(link->to);
-				free(link);
+				avro_freet(struct avro_link_schema_t, link);
 			}
 			break;
 		}
@@ -278,14 +279,14 @@ avro_schema_t avro_schema_null(void)
 avro_schema_t avro_schema_fixed(const char *name, const int64_t size)
 {
 	struct avro_fixed_schema_t *fixed =
-	    malloc(sizeof(struct avro_fixed_schema_t));
+	    avro_new(struct avro_fixed_schema_t);
 	if (!fixed) {
 		return NULL;
 	}
 	if (!is_avro_id(name)) {
 		return NULL;
 	}
-	fixed->name = strdup(name);
+	fixed->name = avro_strdup(name);
 	fixed->size = size;
 	avro_schema_init(&fixed->obj, AVRO_FIXED);
 	return &fixed->obj;
@@ -299,20 +300,20 @@ int64_t avro_schema_fixed_size(const avr
 avro_schema_t avro_schema_union(void)
 {
 	struct avro_union_schema_t *schema =
-	    malloc(sizeof(struct avro_union_schema_t));
+	    avro_new(struct avro_union_schema_t);
 	if (!schema) {
 		return NULL;
 	}
 	schema->branches = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!schema->branches) {
-		free(schema);
+		avro_freet(struct avro_union_schema_t, schema);
 		return NULL;
 	}
 	schema->branches_byname =
 	    st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!schema->branches_byname) {
 		st_free_table(schema->branches);
-		free(schema);
+		avro_freet(struct avro_union_schema_t, schema);
 		return NULL;
 	}
 
@@ -372,7 +373,7 @@ avro_schema_t avro_schema_union_branch_b
 avro_schema_t avro_schema_array(const avro_schema_t items)
 {
 	struct avro_array_schema_t *array =
-	    malloc(sizeof(struct avro_array_schema_t));
+	    avro_new(struct avro_array_schema_t);
 	if (!array) {
 		return NULL;
 	}
@@ -389,7 +390,7 @@ avro_schema_t avro_schema_array_items(av
 avro_schema_t avro_schema_map(const avro_schema_t values)
 {
 	struct avro_map_schema_t *map =
-	    malloc(sizeof(struct avro_map_schema_t));
+	    avro_new(struct avro_map_schema_t);
 	if (!map) {
 		return NULL;
 	}
@@ -410,26 +411,26 @@ avro_schema_t avro_schema_enum(const cha
 	if (!is_avro_id(name)) {
 		return NULL;
 	}
-	enump = malloc(sizeof(struct avro_enum_schema_t));
+	enump = avro_new(struct avro_enum_schema_t);
 	if (!enump) {
 		return NULL;
 	}
-	enump->name = strdup(name);
+	enump->name = avro_strdup(name);
 	if (!enump->name) {
-		free(enump);
+		avro_freet(struct avro_enum_schema_t, enump);
 		return NULL;
 	}
 	enump->symbols = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!enump->symbols) {
-		free(enump->name);
-		free(enump);
+		avro_str_free(enump->name);
+		avro_freet(struct avro_enum_schema_t, enump);
 		return NULL;
 	}
 	enump->symbols_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!enump->symbols_byname) {
 		st_free_table(enump->symbols);
-		free(enump->name);
-		free(enump);
+		avro_str_free(enump->name);
+		avro_freet(struct avro_enum_schema_t, enump);
 		return NULL;
 	}
 	avro_schema_init(&enump->obj, AVRO_ENUM);
@@ -473,7 +474,7 @@ avro_schema_enum_symbol_append(const avr
 		return EINVAL;
 	}
 	enump = avro_schema_to_enum(enum_schema);
-	sym = strdup(symbol);
+	sym = avro_strdup(symbol);
 	if (!sym) {
 		return ENOMEM;
 	}
@@ -496,11 +497,11 @@ avro_schema_record_field_append(const av
 		return EINVAL;
 	}
 	record = avro_schema_to_record(record_schema);
-	new_field = malloc(sizeof(struct avro_record_field_t));
+	new_field = avro_new(struct avro_record_field_t);
 	if (!new_field) {
 		return ENOMEM;
 	}
-	new_field->name = strdup(field_name);
+	new_field->name = avro_strdup(field_name);
 	new_field->type = avro_schema_incref(field_schema);
 	st_insert(record->fields, record->fields->num_entries,
 		  (st_data_t) new_field);
@@ -515,35 +516,38 @@ avro_schema_t avro_schema_record(const c
 	if (!is_avro_id(name)) {
 		return NULL;
 	}
-	record = malloc(sizeof(struct avro_record_schema_t));
+	record = avro_new(struct avro_record_schema_t);
 	if (!record) {
 		return NULL;
 	}
-	record->name = strdup(name);
+	record->name = avro_strdup(name);
 	if (!record->name) {
-		free(record);
+		avro_freet(struct avro_record_schema_t, record);
 		return NULL;
 	}
-	record->space = space ? strdup(space) : NULL;
+	record->space = space ? avro_strdup(space) : NULL;
 	if (space && !record->space) {
-		free(record->name);
-		free(record);
+		avro_str_free(record->name);
+		avro_freet(struct avro_record_schema_t, record);
 		return NULL;
 	}
 	record->fields = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!record->fields) {
 		if (record->space) {
-			free(record->space);
+			avro_str_free(record->space);
 		}
-		free(record->name);
-		free(record);
+		avro_str_free(record->name);
+		avro_freet(struct avro_record_schema_t, record);
 		return NULL;
 	}
 	record->fields_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!record->fields_byname) {
 		st_free_table(record->fields);
-		free(record->name);
-		free(record);
+		if (record->space) {
+			avro_str_free(record->space);
+		}
+		avro_str_free(record->name);
+		avro_freet(struct avro_record_schema_t, record);
 		return NULL;
 	}
 
@@ -617,7 +621,7 @@ avro_schema_t avro_schema_link(avro_sche
 	if (!is_avro_named_type(to)) {
 		return NULL;
 	}
-	link = malloc(sizeof(struct avro_link_schema_t));
+	link = avro_new(struct avro_link_schema_t);
 	if (!link) {
 		return NULL;
 	}
@@ -974,7 +978,7 @@ avro_schema_from_json(const char *jsonte
 		return EINVAL;
 	}
 
-	error = malloc(sizeof(struct avro_schema_error_t_));
+	error = avro_new(struct avro_schema_error_t_);
 	if (!error) {
 		return ENOMEM;
 	}
@@ -982,14 +986,14 @@ avro_schema_from_json(const char *jsonte
 
 	error->named_schemas = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
 	if (!error->named_schemas) {
-		free(error);
+		avro_freet(struct avro_schema_error_t_, error);
 		return ENOMEM;
 	}
 
 	root = json_loads(jsontext, &error->json_error);
 	if (!root) {
 		st_free_table(error->named_schemas);
-		free(error);
+		avro_freet(struct avro_schema_error_t_, error);
 		return EINVAL;
 	}
 
@@ -1001,7 +1005,7 @@ avro_schema_from_json(const char *jsonte
 	st_free_table(error->named_schemas);
 	if (rval == 0) {
 		/* no need for an error return */
-		free(error);
+		avro_freet(struct avro_schema_error_t_, error);
 	}
 	return rval;
 }

Modified: avro/trunk/lang/c/src/st.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/st.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/src/st.c (original)
+++ avro/trunk/lang/c/src/st.c Tue Jan 11 15:07:07 2011
@@ -8,6 +8,7 @@
  */
 
 #include "avro_private.h"
+#include "allocation.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -58,8 +59,10 @@ static void rehash(st_table *);
 #define calloc xcalloc
 #endif
 
-#define alloc(type) (type*)malloc((unsigned)sizeof(type))
-#define Calloc(n,s) (char*)calloc((n),(s))
+#define Calloc(n,s) (char*)avro_calloc((n),(s))
+
+#define free_bins(tbl)  \
+	avro_free(tbl->bins, tbl->num_bins * sizeof(st_table_entry *))
 
 #define EQUAL(table,x,y) ((x)==(y) || (*table->type->compare)((x),(y)) == 0)
 
@@ -160,7 +163,7 @@ int size;
 
 	size = new_size(size);	/* round up to prime number */
 
-	tbl = alloc(st_table);
+	tbl = avro_new(st_table);
 	tbl->type = type;
 	tbl->num_entries = 0;
 	tbl->num_bins = size;
@@ -207,12 +210,12 @@ st_table *table;
 		ptr = table->bins[i];
 		while (ptr != 0) {
 			next = ptr->next;
-			free(ptr);
+			avro_freet(st_table_entry, ptr);
 			ptr = next;
 		}
 	}
-	free(table->bins);
-	free(table);
+	free_bins(table);
+	avro_freet(st_table, table);
 }
 
 #define PTR_NOT_EQUAL(table, ptr, hash_val, key) \
@@ -264,7 +267,7 @@ do {\
         bin_pos = hash_val % table->num_bins;\
     }\
     \
-    entry = alloc(st_table_entry);\
+    entry = avro_new(st_table_entry);\
     \
     entry->hash = hash_val;\
     entry->key = key;\
@@ -327,7 +330,7 @@ register st_table *table;
 			ptr = next;
 		}
 	}
-	free(table->bins);
+	free_bins(table);
 	table->num_bins = new_num_bins;
 	table->bins = new_bins;
 }
@@ -339,7 +342,7 @@ st_table *old_table;
 	st_table_entry *ptr, *entry;
 	int i, num_bins = old_table->num_bins;
 
-	new_table = alloc(st_table);
+	new_table = avro_new(st_table);
 	if (new_table == 0) {
 		return 0;
 	}
@@ -349,7 +352,7 @@ st_table *old_table;
 	    Calloc((unsigned)num_bins, sizeof(st_table_entry *));
 
 	if (new_table->bins == 0) {
-		free(new_table);
+		avro_freet(st_table, new_table);
 		return 0;
 	}
 
@@ -357,10 +360,10 @@ st_table *old_table;
 		new_table->bins[i] = 0;
 		ptr = old_table->bins[i];
 		while (ptr != 0) {
-			entry = alloc(st_table_entry);
+			entry = avro_new(st_table_entry);
 			if (entry == 0) {
-				free(new_table->bins);
-				free(new_table);
+				free_bins(new_table);
+				avro_freet(st_table, new_table);
 				return 0;
 			}
 			*entry = *ptr;
@@ -396,7 +399,7 @@ st_data_t *value;
 		if (value != 0)
 			*value = ptr->record;
 		*key = ptr->key;
-		free(ptr);
+		avro_freet(st_table_entry, ptr);
 		return 1;
 	}
 
@@ -408,7 +411,7 @@ st_data_t *value;
 			if (value != 0)
 				*value = tmp->record;
 			*key = tmp->key;
-			free(tmp);
+			avro_freet(st_table_entry, tmp);
 			return 1;
 		}
 	}
@@ -515,7 +518,7 @@ st_data_t arg;
 					last->next = ptr->next;
 				}
 				ptr = ptr->next;
-				free(tmp);
+				avro_freet(st_table_entry, tmp);
 				table->num_entries--;
 			}
 		}

Modified: avro/trunk/lang/c/tests/test_avro_data.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_data.c?rev=1057683&r1=1057682&r2=1057683&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_data.c (original)
+++ avro/trunk/lang/c/tests/test_avro_data.c Tue Jan 11 15:07:07 2011
@@ -28,6 +28,39 @@ avro_writer_t writer;
 
 typedef int (*avro_test) (void);
 
+/*
+ * Use a custom allocator that verifies that the size that we use to
+ * free an object matches the size that we use to allocate it.
+ */
+
+static void *
+test_allocator(void *ud, void *ptr, size_t osize, size_t nsize)
+{
+	AVRO_UNUSED(ud);
+	AVRO_UNUSED(osize);
+
+	if (nsize == 0) {
+		size_t  *size = ((size_t *) ptr) - 1;
+		if (osize != *size) {
+			fprintf(stderr,
+				"Error freeing %p:\n"
+				"Size passed to avro_free (%zu) "
+				"doesn't match size passed to "
+				"avro_malloc (%zu)\n",
+				ptr, osize, *size);
+			exit(EXIT_FAILURE);
+		}
+		free(size);
+		return NULL;
+	} else {
+		size_t  real_size = nsize + sizeof(size_t);
+		size_t  *old_size = ptr? ((size_t *) ptr)-1: NULL;
+		size_t  *size = realloc(old_size, real_size);
+		*size = nsize;
+		return (size + 1);
+	}
+}
+
 void init_rand(void)
 {
 	srand(time(NULL));
@@ -425,6 +458,8 @@ static int test_fixed(void)
 
 int main(void)
 {
+	avro_set_allocator(test_allocator, NULL);
+
 	unsigned int i;
 	struct avro_tests {
 		char *name;



Mime
View raw message