You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by dc...@apache.org on 2011/07/14 04:35:09 UTC

svn commit: r1146546 [4/5] - in /avro/trunk/lang/c: docs/ src/ src/avro/ tests/

Modified: avro/trunk/lang/c/src/resolver.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/resolver.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/src/resolver.c (original)
+++ avro/trunk/lang/c/src/resolver.c Thu Jul 14 02:35:04 2011
@@ -19,11 +19,13 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "avro.h"
+#include "avro/allocation.h"
 #include "avro/consumer.h"
-#include "avro_errors.h"
+#include "avro/data.h"
+#include "avro/errors.h"
+#include "avro/legacy.h"
+#include "avro/schema.h"
 #include "avro_private.h"
-#include "allocation.h"
 #include "st.h"
 
 
@@ -175,55 +177,8 @@ avro_resolver_get_real_dest(avro_resolve
  * Memoized resolvers
  */
 
-static int
-avro_resolver_cmp(avro_resolver_t *a, avro_resolver_t *b)
-{
-	return (a->parent.schema != b->parent.schema) || (a->rschema != b->rschema);
-}
-
-static int
-avro_resolver_hash(avro_resolver_t *a)
-{
-	return ((uintptr_t) a->parent.schema) ^ ((uintptr_t) a->rschema);
-}
-
-static struct st_hash_type  avro_resolver_hash_type = {
-	avro_resolver_cmp,
-	avro_resolver_hash
-};
-
-static void
-save_resolver(st_table *resolvers, avro_resolver_t *resolver)
-{
-	st_insert(resolvers, (st_data_t) resolver, (st_data_t) resolver);
-}
-
-static void
-delete_resolver(st_table *resolvers, avro_resolver_t *resolver)
-{
-	st_delete(resolvers, (st_data_t *) &resolver, (st_data_t *) &resolver);
-}
-
-static avro_resolver_t *
-find_resolver(st_table *resolvers, avro_schema_t wschema, avro_schema_t rschema)
-{
-	avro_resolver_t  dummy;
-	dummy.parent.schema = wschema;
-	dummy.rschema = rschema;
-	union {
-		st_data_t  data;
-		avro_resolver_t  *resolver;
-	} val;
-	if (st_lookup(resolvers, (st_data_t) &dummy, &val.data)) {
-		return val.resolver;
-	} else {
-		return NULL;
-	}
-}
-
-
 static avro_consumer_t *
-avro_resolver_new_memoized(st_table *resolvers,
+avro_resolver_new_memoized(avro_memoize_t *mem,
 			   avro_schema_t wschema, avro_schema_t rschema);
 
 
@@ -347,13 +302,13 @@ avro_resolver_boolean_value(avro_consume
 }
 
 static int
-try_boolean(st_table *resolvers, avro_resolver_t **resolver,
+try_boolean(avro_memoize_t *mem, avro_resolver_t **resolver,
 	    avro_schema_t wschema, avro_schema_t rschema,
 	    avro_schema_t root_rschema)
 {
 	if (is_avro_boolean(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.boolean_value = avro_resolver_boolean_value;
 	}
 	return 0;
@@ -383,13 +338,13 @@ avro_resolver_bytes_value(avro_consumer_
 }
 
 static int
-try_bytes(st_table *resolvers, avro_resolver_t **resolver,
+try_bytes(avro_memoize_t *mem, avro_resolver_t **resolver,
 	  avro_schema_t wschema, avro_schema_t rschema,
 	  avro_schema_t root_rschema)
 {
 	if (is_avro_bytes(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.bytes_value = avro_resolver_bytes_value;
 	}
 	return 0;
@@ -408,13 +363,13 @@ avro_resolver_double_value(avro_consumer
 }
 
 static int
-try_double(st_table *resolvers, avro_resolver_t **resolver,
+try_double(avro_memoize_t *mem, avro_resolver_t **resolver,
 	   avro_schema_t wschema, avro_schema_t rschema,
 	   avro_schema_t root_rschema)
 {
 	if (is_avro_double(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.double_value = avro_resolver_double_value;
 	}
 	return 0;
@@ -444,18 +399,18 @@ avro_resolver_float_double_value(avro_co
 }
 
 static int
-try_float(st_table *resolvers, avro_resolver_t **resolver,
+try_float(avro_memoize_t *mem, avro_resolver_t **resolver,
 	  avro_schema_t wschema, avro_schema_t rschema,
 	  avro_schema_t root_rschema)
 {
 	if (is_avro_float(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.float_value = avro_resolver_float_value;
 	}
 	else if (is_avro_double(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.float_value = avro_resolver_float_double_value;
 	}
 	return 0;
@@ -507,28 +462,28 @@ avro_resolver_int_float_value(avro_consu
 }
 
 static int
-try_int(st_table *resolvers, avro_resolver_t **resolver,
+try_int(avro_memoize_t *mem, avro_resolver_t **resolver,
 	avro_schema_t wschema, avro_schema_t rschema,
 	avro_schema_t root_rschema)
 {
 	if (is_avro_int32(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.int_value = avro_resolver_int_value;
 	}
 	else if (is_avro_int64(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.int_value = avro_resolver_int_long_value;
 	}
 	else if (is_avro_double(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.int_value = avro_resolver_int_double_value;
 	}
 	else if (is_avro_float(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.int_value = avro_resolver_int_float_value;
 	}
 	return 0;
@@ -569,23 +524,23 @@ avro_resolver_long_double_value(avro_con
 }
 
 static int
-try_long(st_table *resolvers, avro_resolver_t **resolver,
+try_long(avro_memoize_t *mem, avro_resolver_t **resolver,
 	 avro_schema_t wschema, avro_schema_t rschema,
 	 avro_schema_t root_rschema)
 {
 	if (is_avro_int64(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.long_value = avro_resolver_long_value;
 	}
 	else if (is_avro_double(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.long_value = avro_resolver_long_double_value;
 	}
 	else if (is_avro_float(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.long_value = avro_resolver_long_float_value;
 	}
 	return 0;
@@ -605,13 +560,13 @@ avro_resolver_null_value(avro_consumer_t
 }
 
 static int
-try_null(st_table *resolvers, avro_resolver_t **resolver,
+try_null(avro_memoize_t *mem, avro_resolver_t **resolver,
 	 avro_schema_t wschema, avro_schema_t rschema,
 	 avro_schema_t root_rschema)
 {
 	if (is_avro_null(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.null_value = avro_resolver_null_value;
 	}
 	return 0;
@@ -628,17 +583,17 @@ avro_resolver_string_value(avro_consumer
 	avro_datum_t  ud_dest = user_data;
 	avro_datum_t  dest = avro_resolver_get_real_dest(resolver, ud_dest);
 	debug("Storing \"%s\" into %p", (const char *) value, dest);
-	return avro_givestring_set(dest, value, avro_alloc_free);
+	return avro_givestring_set(dest, value, avro_alloc_free_func);
 }
 
 static int
-try_string(st_table *resolvers, avro_resolver_t **resolver,
+try_string(avro_memoize_t *mem, avro_resolver_t **resolver,
 	   avro_schema_t wschema, avro_schema_t rschema,
 	   avro_schema_t root_rschema)
 {
 	if (is_avro_string(rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.string_value = avro_resolver_string_value;
 	}
 	return 0;
@@ -703,7 +658,7 @@ avro_resolver_array_element(avro_consume
 }
 
 static int
-try_array(st_table *resolvers, avro_resolver_t **resolver,
+try_array(avro_memoize_t *mem, avro_resolver_t **resolver,
 	  avro_schema_t wschema, avro_schema_t rschema,
 	  avro_schema_t root_rschema)
 {
@@ -722,15 +677,15 @@ try_array(st_table *resolvers, avro_reso
 	 */
 
 	*resolver = avro_resolver_create(wschema, root_rschema);
-	save_resolver(resolvers, *resolver);
+	avro_memoize_set(mem, wschema, root_rschema, *resolver);
 
 	avro_schema_t  witems = avro_schema_array_items(wschema);
 	avro_schema_t  ritems = avro_schema_array_items(rschema);
 
 	avro_consumer_t  *item_consumer =
-	    avro_resolver_new_memoized(resolvers, witems, ritems);
+	    avro_resolver_new_memoized(mem, witems, ritems);
 	if (!item_consumer) {
-		delete_resolver(resolvers, *resolver);
+		avro_memoize_delete(mem, wschema, root_rschema);
 		avro_consumer_free(&(*resolver)->parent);
 		avro_prefix_error("Array values aren't compatible: ");
 		return EINVAL;
@@ -772,7 +727,7 @@ avro_resolver_enum_value(avro_consumer_t
 }
 
 static int
-try_enum(st_table *resolvers, avro_resolver_t **resolver,
+try_enum(avro_memoize_t *mem, avro_resolver_t **resolver,
 	 avro_schema_t wschema, avro_schema_t rschema,
 	 avro_schema_t root_rschema)
 {
@@ -787,7 +742,7 @@ try_enum(st_table *resolvers, avro_resol
 
 		if (!strcmp(wname, rname)) {
 			*resolver = avro_resolver_create(wschema, root_rschema);
-			save_resolver(resolvers, *resolver);
+			avro_memoize_set(mem, wschema, root_rschema, *resolver);
 			(*resolver)->parent.enum_value = avro_resolver_enum_value;
 		}
 	}
@@ -808,11 +763,11 @@ avro_resolver_fixed_value(avro_consumer_
 	avro_datum_t  ud_dest = user_data;
 	avro_datum_t  dest = avro_resolver_get_real_dest(resolver, ud_dest);
 	debug("Storing (fixed) %zu bytes into %p", value_len, dest);
-	return avro_givefixed_set(dest, value, value_len, avro_alloc_free);
+	return avro_givefixed_set(dest, value, value_len, avro_alloc_free_func);
 }
 
 static int
-try_fixed(st_table *resolvers, avro_resolver_t **resolver,
+try_fixed(avro_memoize_t *mem, avro_resolver_t **resolver,
 	  avro_schema_t wschema, avro_schema_t rschema,
 	  avro_schema_t root_rschema)
 {
@@ -822,7 +777,7 @@ try_fixed(st_table *resolvers, avro_reso
 
 	if (avro_schema_equal(wschema, rschema)) {
 		*resolver = avro_resolver_create(wschema, root_rschema);
-		save_resolver(resolvers, *resolver);
+		avro_memoize_set(mem, wschema, root_rschema, *resolver);
 		(*resolver)->parent.fixed_value = avro_resolver_fixed_value;
 	}
 	return 0;
@@ -888,7 +843,7 @@ avro_resolver_map_element(avro_consumer_
 }
 
 static int
-try_map(st_table *resolvers, avro_resolver_t **resolver,
+try_map(avro_memoize_t *mem, avro_resolver_t **resolver,
 	avro_schema_t wschema, avro_schema_t rschema,
 	avro_schema_t root_rschema)
 {
@@ -907,15 +862,15 @@ try_map(st_table *resolvers, avro_resolv
 	 */
 
 	*resolver = avro_resolver_create(wschema, root_rschema);
-	save_resolver(resolvers, *resolver);
+	avro_memoize_set(mem, wschema, root_rschema, *resolver);
 
 	avro_schema_t  wvalues = avro_schema_map_values(wschema);
 	avro_schema_t  rvalues = avro_schema_map_values(rschema);
 
 	avro_consumer_t  *value_consumer =
-	    avro_resolver_new_memoized(resolvers, wvalues, rvalues);
+	    avro_resolver_new_memoized(mem, wvalues, rvalues);
 	if (!value_consumer) {
-		delete_resolver(resolvers, *resolver);
+		avro_memoize_delete(mem, wschema, root_rschema);
 		avro_consumer_free(&(*resolver)->parent);
 		avro_prefix_error("Map values aren't compatible: ");
 		return EINVAL;
@@ -1002,7 +957,7 @@ avro_resolver_record_field(avro_consumer
 }
 
 static int
-try_record(st_table *resolvers, avro_resolver_t **resolver,
+try_record(avro_memoize_t *mem, avro_resolver_t **resolver,
 	   avro_schema_t wschema, avro_schema_t rschema,
 	   avro_schema_t root_rschema)
 {
@@ -1042,7 +997,7 @@ try_record(st_table *resolvers, avro_res
 	 */
 
 	*resolver = avro_resolver_create(wschema, root_rschema);
-	save_resolver(resolvers, *resolver);
+	avro_memoize_set(mem, wschema, root_rschema, *resolver);
 
 	size_t  wfields = avro_schema_record_size(wschema);
 	size_t  rfields = avro_schema_record_size(rschema);
@@ -1089,7 +1044,7 @@ try_record(st_table *resolvers, avro_res
 		avro_schema_t  wfield =
 		    avro_schema_record_field_get_by_index(wschema, wi);
 		avro_consumer_t  *field_resolver =
-		    avro_resolver_new_memoized(resolvers, wfield, rfield);
+		    avro_resolver_new_memoized(mem, wfield, rfield);
 
 		if (!field_resolver) {
 			avro_prefix_error("Field %s isn't compatible: ", field_name);
@@ -1123,7 +1078,7 @@ error:
 	 * Clean up any consumer we might have already created.
 	 */
 
-	delete_resolver(resolvers, *resolver);
+	avro_memoize_delete(mem, wschema, root_rschema);
 	avro_consumer_free(&(*resolver)->parent);
 
 	{
@@ -1178,7 +1133,7 @@ avro_resolver_union_branch(avro_consumer
 }
 
 static avro_consumer_t *
-try_union(st_table *resolvers, avro_schema_t wschema, avro_schema_t rschema)
+try_union(avro_memoize_t *mem, avro_schema_t wschema, avro_schema_t rschema)
 {
 	/*
 	 * For a writer union, we recursively try to resolve each branch
@@ -1204,7 +1159,7 @@ try_union(st_table *resolvers, avro_sche
 	debug("Checking %zu-branch writer union schema", num_branches);
 
 	avro_resolver_t  *resolver = avro_resolver_create(wschema, rschema);
-	save_resolver(resolvers, resolver);
+	avro_memoize_set(mem, wschema, rschema, resolver);
 
 	avro_consumer_t  **child_resolvers =
 	    avro_calloc(num_branches, sizeof(avro_consumer_t *));
@@ -1227,7 +1182,7 @@ try_union(st_table *resolvers, avro_sche
 		 */
 
 		child_resolvers[i] =
-		    avro_resolver_new_memoized(resolvers, branch_schema, rschema);
+		    avro_resolver_new_memoized(mem, branch_schema, rschema);
 		if (child_resolvers[i]) {
 			debug("Found match for writer union branch %u", i);
 			some_branch_compatible = 1;
@@ -1260,7 +1215,7 @@ error:
 	 * Clean up any consumer we might have already created.
 	 */
 
-	delete_resolver(resolvers, resolver);
+	avro_memoize_delete(mem, wschema, rschema);
 	avro_consumer_free(&resolver->parent);
 
 	for (i = 0; i < num_branches; i++) {
@@ -1279,7 +1234,7 @@ error:
  */
 
 static avro_consumer_t *
-avro_resolver_new_memoized(st_table *resolvers,
+avro_resolver_new_memoized(avro_memoize_t *mem,
 			   avro_schema_t wschema, avro_schema_t rschema)
 {
 	check_param(NULL, is_avro_schema(wschema), "writer schema");
@@ -1293,8 +1248,8 @@ avro_resolver_new_memoized(st_table *res
 	 * just return that resolver.
 	 */
 
-	avro_resolver_t  *saved = find_resolver(resolvers, wschema, rschema);
-	if (saved) {
+	avro_resolver_t  *saved = NULL;
+	if (avro_memoize_get(mem, wschema, rschema, (void **) &saved)) {
 		debug("Already resolved %s and %s",
 		      avro_schema_type_name(wschema),
 		      avro_schema_type_name(rschema));
@@ -1308,59 +1263,59 @@ avro_resolver_new_memoized(st_table *res
 	switch (avro_typeof(wschema))
 	{
 		case AVRO_BOOLEAN:
-			check_simple_writer(resolvers, wschema, rschema, boolean);
+			check_simple_writer(mem, wschema, rschema, boolean);
 			return NULL;
 
 		case AVRO_BYTES:
-			check_simple_writer(resolvers, wschema, rschema, bytes);
+			check_simple_writer(mem, wschema, rschema, bytes);
 			return NULL;
 
 		case AVRO_DOUBLE:
-			check_simple_writer(resolvers, wschema, rschema, double);
+			check_simple_writer(mem, wschema, rschema, double);
 			return NULL;
 
 		case AVRO_FLOAT:
-			check_simple_writer(resolvers, wschema, rschema, float);
+			check_simple_writer(mem, wschema, rschema, float);
 			return NULL;
 
 		case AVRO_INT32:
-			check_simple_writer(resolvers, wschema, rschema, int);
+			check_simple_writer(mem, wschema, rschema, int);
 			return NULL;
 
 		case AVRO_INT64:
-			check_simple_writer(resolvers, wschema, rschema, long);
+			check_simple_writer(mem, wschema, rschema, long);
 			return NULL;
 
 		case AVRO_NULL:
-			check_simple_writer(resolvers, wschema, rschema, null);
+			check_simple_writer(mem, wschema, rschema, null);
 			return NULL;
 
 		case AVRO_STRING:
-			check_simple_writer(resolvers, wschema, rschema, string);
+			check_simple_writer(mem, wschema, rschema, string);
 			return NULL;
 
 		case AVRO_ARRAY:
-			check_simple_writer(resolvers, wschema, rschema, array);
+			check_simple_writer(mem, wschema, rschema, array);
 			return NULL;
 
 		case AVRO_ENUM:
-			check_simple_writer(resolvers, wschema, rschema, enum);
+			check_simple_writer(mem, wschema, rschema, enum);
 			return NULL;
 
 		case AVRO_FIXED:
-			check_simple_writer(resolvers, wschema, rschema, fixed);
+			check_simple_writer(mem, wschema, rschema, fixed);
 			return NULL;
 
 		case AVRO_MAP:
-			check_simple_writer(resolvers, wschema, rschema, map);
+			check_simple_writer(mem, wschema, rschema, map);
 			return NULL;
 
 		case AVRO_RECORD:
-			check_simple_writer(resolvers, wschema, rschema, record);
+			check_simple_writer(mem, wschema, rschema, record);
 			return NULL;
 
 		case AVRO_UNION:
-			return try_union(resolvers, wschema, rschema);
+			return try_union(mem, wschema, rschema);
 
 		default:
 			avro_set_error("Unknown schema type");
@@ -1374,9 +1329,10 @@ avro_resolver_new_memoized(st_table *res
 avro_consumer_t *
 avro_resolver_new(avro_schema_t wschema, avro_schema_t rschema)
 {
-	st_table  *resolvers = st_init_table(&avro_resolver_hash_type);
+	avro_memoize_t  mem;
+	avro_memoize_init(&mem);
 	avro_consumer_t  *result =
-	    avro_resolver_new_memoized(resolvers, wschema, rschema);
-	st_free_table(resolvers);
+	    avro_resolver_new_memoized(&mem, wschema, rschema);
+	avro_memoize_done(&mem);
 	return result;
 }

Modified: avro/trunk/lang/c/src/schema.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/schema.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/src/schema.c (original)
+++ avro/trunk/lang/c/src/schema.c Thu Jul 14 02:35:04 2011
@@ -15,10 +15,13 @@
  * permissions and limitations under the License. 
  */
 
+#include "avro/allocation.h"
 #include "avro/refcount.h"
-#include "avro_errors.h"
+#include "avro/errors.h"
+#include "avro/io.h"
+#include "avro/legacy.h"
+#include "avro/schema.h"
 #include "avro_private.h"
-#include "allocation.h"
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>

Modified: avro/trunk/lang/c/src/schema.h
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/schema.h?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/src/schema.h (original)
+++ avro/trunk/lang/c/src/schema.h Thu Jul 14 02:35:04 2011
@@ -14,10 +14,12 @@
  * implied.  See the License for the specific language governing
  * permissions and limitations under the License. 
  */
-#ifndef AVRO_SCHEMA_H
-#define AVRO_SCHEMA_H
+#ifndef AVRO_SCHEMA_PRIV_H
+#define AVRO_SCHEMA_PRIV_H
 
-#include "avro.h"
+#include <stdint.h>
+#include "avro/basics.h"
+#include "avro/schema.h"
 #include "avro_private.h"
 #include "st.h"
 

Modified: avro/trunk/lang/c/src/schema_specific.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/schema_specific.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/src/schema_specific.c (original)
+++ avro/trunk/lang/c/src/schema_specific.c Thu Jul 14 02:35:04 2011
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+
 #include "schema.h"
 
 enum specific_state {

Modified: avro/trunk/lang/c/src/st.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/st.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/src/st.c (original)
+++ avro/trunk/lang/c/src/st.c Thu Jul 14 02:35:04 2011
@@ -8,7 +8,7 @@
  */
 
 #include "avro_private.h"
-#include "allocation.h"
+#include "avro/allocation.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

Added: avro/trunk/lang/c/src/string.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/string.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/src/string.c (added)
+++ avro/trunk/lang/c/src/string.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,253 @@
+/*
+ * 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 <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avro_private.h"
+#include "avro/data.h"
+#include "avro/allocation.h"
+#include "avro/errors.h"
+
+
+/*
+ * A resizable wrapped buffer implementation.  This implementation makes
+ * actual copies in its copy method; if we wanted a zero-copy solution
+ * here, then we'd have to keep track of all copies of the buffer, so
+ * that we can update pointers whenever the buffer is resized (since
+ * this might change the location of the memory region).
+ */
+
+struct avro_wrapped_resizable {
+	size_t  buf_size;
+};
+
+#define avro_wrapped_resizable_size(sz) \
+	(sizeof(struct avro_wrapped_resizable) + (sz))
+
+static void
+avro_wrapped_resizable_free(avro_wrapped_buffer_t *self)
+{
+	struct avro_wrapped_resizable  *resizable = self->user_data;
+	avro_free(resizable, avro_wrapped_resizable_size(resizable->buf_size));
+}
+
+static int
+avro_wrapped_resizable_resize(avro_wrapped_buffer_t *self, size_t desired)
+{
+	struct avro_wrapped_resizable  *resizable = self->user_data;
+
+	size_t  new_buf_size = resizable->buf_size * 2;
+	if (desired > new_buf_size) {
+		new_buf_size = desired;
+	}
+
+	struct avro_wrapped_resizable  *new_resizable =
+	    avro_realloc(resizable,
+		         avro_wrapped_resizable_size(resizable->buf_size),
+			 avro_wrapped_resizable_size(new_buf_size));
+	if (new_resizable == NULL) {
+		return ENOMEM;
+	}
+
+	new_resizable->buf_size = new_buf_size;
+
+	void  *old_buf = resizable;
+	void  *new_buf = new_resizable;
+
+	ptrdiff_t  offset = self->buf - old_buf;
+	self->buf = new_buf + offset;
+	self->user_data = new_resizable;
+	return 0;
+}
+
+static int
+avro_wrapped_resizable_new(avro_wrapped_buffer_t *dest, size_t buf_size)
+{
+	size_t  allocated_size = avro_wrapped_resizable_size(buf_size);
+	struct avro_wrapped_resizable  *resizable =
+	    avro_malloc(allocated_size);
+	if (resizable == NULL) {
+		return ENOMEM;
+	}
+
+	resizable->buf_size = buf_size;
+
+	dest->buf = ((void *) resizable) + sizeof(struct avro_wrapped_resizable);
+	dest->size = buf_size;
+	dest->user_data = resizable;
+	dest->free = avro_wrapped_resizable_free;
+	dest->copy = NULL;
+	dest->slice = NULL;
+	return 0;
+}
+
+#define is_resizable(buf) \
+	((buf).free == avro_wrapped_resizable_free)
+
+
+
+void
+avro_raw_string_init(avro_raw_string_t *str)
+{
+	memset(str, 0, sizeof(avro_raw_string_t));
+}
+
+
+void
+avro_raw_string_clear(avro_raw_string_t *str)
+{
+	/*
+	 * If the string's buffer is one that we control, then we don't
+	 * free it; that lets us reuse the storage on the next call to
+	 * avro_raw_string_set[_length].
+	 */
+
+	if (is_resizable(str->wrapped)) {
+		str->wrapped.size = 0;
+	} else {
+		avro_wrapped_buffer_free(&str->wrapped);
+		avro_raw_string_init(str);
+	}
+}
+
+
+void
+avro_raw_string_done(avro_raw_string_t *str)
+{
+	avro_wrapped_buffer_free(&str->wrapped);
+	avro_raw_string_init(str);
+}
+
+
+/**
+ * Makes sure that the string's buffer is one that we allocated
+ * ourselves, and that the buffer is big enough to hold a string of the
+ * given length.
+ */
+
+static int
+avro_raw_string_ensure_buf(avro_raw_string_t *str, size_t length)
+{
+	int  rval;
+
+	if (is_resizable(str->wrapped)) {
+		/*
+		 * If we've already got a resizable buffer, just have it
+		 * resize itself.
+		 */
+
+		return avro_wrapped_resizable_resize(&str->wrapped, length);
+	} else {
+		/*
+		 * Stash a copy of the old wrapped buffer, and then
+		 * create a new resizable buffer to store our content
+		 * in.
+		 */
+
+		avro_wrapped_buffer_t  orig = str->wrapped;
+		check(rval, avro_wrapped_resizable_new(&str->wrapped, length));
+
+		/*
+		 * If there was any content in the old wrapped buffer,
+		 * copy it into the new resizable one.
+		 */
+
+		if (orig.size > 0) {
+			size_t  to_copy =
+			    (orig.size < length)? orig.size: length;
+			memcpy((void *) str->wrapped.buf, orig.buf, to_copy);
+		}
+		avro_wrapped_buffer_free(&orig);
+
+		return 0;
+	}
+}
+
+
+void
+avro_raw_string_set_length(avro_raw_string_t *str,
+			   const void *src, size_t length)
+{
+	avro_raw_string_ensure_buf(str, length+1);
+	memcpy((void *) str->wrapped.buf, src, length);
+	((char *) str->wrapped.buf)[length] = '\0';
+	str->wrapped.size = length;
+}
+
+
+void
+avro_raw_string_set(avro_raw_string_t *str, const char *src)
+{
+	size_t  length = strlen(src);
+	avro_raw_string_ensure_buf(str, length+1);
+	memcpy((void *) str->wrapped.buf, src, length+1);
+	str->wrapped.size = length+1;
+}
+
+
+void
+avro_raw_string_append(avro_raw_string_t *str, const char *src)
+{
+	if (avro_raw_string_length(str) == 0) {
+		return avro_raw_string_set(str, src);
+	}
+
+	/* Assume that str->wrapped.size includes a NUL terminator */
+	size_t  length = strlen(src);
+	avro_raw_string_ensure_buf(str, str->wrapped.size+length);
+	memcpy((void *) str->wrapped.buf + str->wrapped.size - 1, src, length+1);
+	str->wrapped.size += length;
+}
+
+
+void
+avro_raw_string_give(avro_raw_string_t *str,
+		     avro_wrapped_buffer_t *src)
+{
+	avro_wrapped_buffer_free(&str->wrapped);
+	avro_wrapped_buffer_move(&str->wrapped, src);
+}
+
+int
+avro_raw_string_grab(const avro_raw_string_t *str,
+		     avro_wrapped_buffer_t *dest)
+{
+	return avro_wrapped_buffer_copy(dest, &str->wrapped, 0, str->wrapped.size);
+}
+
+
+int
+avro_raw_string_equals(const avro_raw_string_t *str1,
+		       const avro_raw_string_t *str2)
+{
+	if (str1 == str2) {
+		return 1;
+	}
+
+	if (!str1 || !str2) {
+		return 0;
+	}
+
+	if (str1->wrapped.size != str2->wrapped.size) {
+		return 0;
+	}
+
+	return (memcmp(str1->wrapped.buf, str2->wrapped.buf,
+		       str1->wrapped.size) == 0);
+}

Added: avro/trunk/lang/c/src/value-read.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/value-read.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/src/value-read.c (added)
+++ avro/trunk/lang/c/src/value-read.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,381 @@
+/*
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avro/allocation.h"
+#include "avro/basics.h"
+#include "avro/data.h"
+#include "avro/io.h"
+#include "avro/value.h"
+#include "avro_private.h"
+#include "encoding.h"
+
+
+/*
+ * Forward declaration; this is basically the same as avro_value_read,
+ * but it doesn't reset dest first.  (Since it will have already been
+ * reset in avro_value_read itself).
+ */
+
+static int
+read_value(avro_reader_t reader, avro_value_t *dest);
+
+
+static int
+read_array_value(avro_reader_t reader, avro_value_t *dest)
+{
+	int  rval;
+	size_t  i;          /* index within the current block */
+	size_t  index = 0;  /* index within the entire array */
+	int64_t  block_count;
+	int64_t  block_size;
+
+	check_prefix(rval, avro_binary_encoding.
+		     read_long(reader, &block_count),
+		     "Cannot read array block count: ");
+
+	while (block_count != 0) {
+		if (block_count < 0) {
+			block_count = block_count * -1;
+			check_prefix(rval, avro_binary_encoding.
+				     read_long(reader, &block_size),
+				     "Cannot read array block size: ");
+		}
+
+		for (i = 0; i < (size_t) block_count; i++, index++) {
+			avro_value_t  child;
+
+			check(rval, avro_value_append(dest, &child, NULL));
+			check(rval, read_value(reader, &child));
+		}
+
+		check_prefix(rval, avro_binary_encoding.
+			     read_long(reader, &block_count),
+			     "Cannot read array block count: ");
+	}
+
+	return 0;
+}
+
+
+static int
+read_map_value(avro_reader_t reader, avro_value_t *dest)
+{
+	int  rval;
+	size_t  i;          /* index within the current block */
+	size_t  index = 0;  /* index within the entire array */
+	int64_t  block_count;
+	int64_t  block_size;
+
+	check_prefix(rval, avro_binary_encoding.read_long(reader, &block_count),
+		     "Cannot read map block count: ");
+
+	while (block_count != 0) {
+		if (block_count < 0) {
+			block_count = block_count * -1;
+			check_prefix(rval, avro_binary_encoding.
+				     read_long(reader, &block_size),
+				     "Cannot read map block size: ");
+		}
+
+		for (i = 0; i < (size_t) block_count; i++, index++) {
+			char *key;
+			int64_t key_size;
+			avro_value_t  child;
+
+			check_prefix(rval, avro_binary_encoding.
+				     read_string(reader, &key, &key_size),
+				     "Cannot read map key: ");
+
+			rval = avro_value_add(dest, key, &child, NULL, NULL);
+			if (rval) {
+				avro_free(key, key_size);
+				return rval;
+			}
+
+			rval = read_value(reader, &child);
+			if (rval) {
+				avro_free(key, key_size);
+				return rval;
+			}
+
+			avro_free(key, key_size);
+		}
+
+		check_prefix(rval, avro_binary_encoding.
+			     read_long(reader, &block_count),
+			     "Cannot read map block count: ");
+	}
+
+	return 0;
+}
+
+
+static int
+read_record_value(avro_reader_t reader, avro_value_t *dest)
+{
+	int  rval;
+	size_t  field_count;
+	size_t  i;
+
+	avro_schema_t  record_schema = avro_value_get_schema(dest);
+
+	check(rval, avro_value_get_size(dest, &field_count));
+	for (i = 0; i < field_count; i++) {
+		avro_value_t  field;
+
+		rval = avro_value_get_by_index(dest, i, &field, NULL);
+		if (rval == 0) {
+			check(rval, read_value(reader, &field));
+		} else {
+			avro_schema_t  field_schema =
+			    avro_schema_record_field_get_by_index(record_schema, i);
+			check(rval, avro_skip_data(reader, field_schema));
+		}
+	}
+
+	return 0;
+}
+
+
+static int
+read_union_value(avro_reader_t reader, avro_value_t *dest)
+{
+	int rval;
+	int64_t discriminant;
+	avro_value_t  branch;
+
+	check_prefix(rval, avro_binary_encoding.
+		     read_long(reader, &discriminant),
+		     "Cannot read union discriminant: ");
+	check(rval, avro_value_set_branch(dest, discriminant, &branch));
+	check(rval, read_value(reader, &branch));
+	return 0;
+}
+
+
+/*
+ * A wrapped buffer implementation that takes control of a buffer
+ * allocated using avro_malloc.
+ */
+
+struct avro_wrapped_alloc {
+	const void  *original;
+	size_t  allocated_size;
+};
+
+static void
+avro_wrapped_alloc_free(avro_wrapped_buffer_t *self)
+{
+	struct avro_wrapped_alloc  *alloc = self->user_data;
+	avro_free((void *) alloc->original, alloc->allocated_size);
+	avro_freet(struct avro_wrapped_alloc, alloc);
+}
+
+static int
+avro_wrapped_alloc_new(avro_wrapped_buffer_t *dest,
+		       const void *buf, size_t length)
+{
+	struct avro_wrapped_alloc  *alloc = avro_new(struct avro_wrapped_alloc);
+	if (alloc == NULL) {
+		return ENOMEM;
+	}
+
+	dest->buf = buf;
+	dest->size = length;
+	dest->user_data = alloc;
+	dest->free = avro_wrapped_alloc_free;
+	dest->copy = NULL;
+	dest->slice = NULL;
+
+	alloc->original = buf;
+	alloc->allocated_size = length;
+	return 0;
+}
+
+
+static int
+read_value(avro_reader_t reader, avro_value_t *dest)
+{
+	int  rval;
+
+	switch (avro_value_get_type(dest)) {
+		case AVRO_BOOLEAN:
+		{
+			int8_t  val;
+			check_prefix(rval, avro_binary_encoding.
+				     read_boolean(reader, &val),
+				     "Cannot read boolean value: ");
+			return avro_value_set_boolean(dest, val);
+		}
+
+		case AVRO_BYTES:
+		{
+			char  *bytes;
+			int64_t  len;
+			check_prefix(rval, avro_binary_encoding.
+				     read_bytes(reader, &bytes, &len),
+				     "Cannot read bytes value: ");
+
+			/*
+			 * read_bytes allocates an extra byte to always
+			 * ensure that the data is NUL terminated, but
+			 * that byte isn't included in the length.  We
+			 * include that extra byte in the allocated
+			 * size, but not in the length of the buffer.
+			 */
+
+			avro_wrapped_buffer_t  buf;
+			check(rval, avro_wrapped_alloc_new(&buf, bytes, len+1));
+			buf.size--;
+			return avro_value_give_bytes(dest, &buf);
+		}
+
+		case AVRO_DOUBLE:
+		{
+			double  val;
+			check_prefix(rval, avro_binary_encoding.
+				     read_double(reader, &val),
+				     "Cannot read double value: ");
+			return avro_value_set_double(dest, val);
+		}
+
+		case AVRO_FLOAT:
+		{
+			float  val;
+			check_prefix(rval, avro_binary_encoding.
+				     read_float(reader, &val),
+				     "Cannot read float value: ");
+			return avro_value_set_float(dest, val);
+		}
+
+		case AVRO_INT32:
+		{
+			int32_t  val;
+			check_prefix(rval, avro_binary_encoding.
+				     read_int(reader, &val),
+				     "Cannot read int value: ");
+			return avro_value_set_int(dest, val);
+		}
+
+		case AVRO_INT64:
+		{
+			int64_t  val;
+			check_prefix(rval, avro_binary_encoding.
+				     read_long(reader, &val),
+				     "Cannot read long value: ");
+			return avro_value_set_long(dest, val);
+		}
+
+		case AVRO_NULL:
+		{
+			check_prefix(rval, avro_binary_encoding.
+				     read_null(reader),
+				     "Cannot read null value: ");
+			return avro_value_set_null(dest);
+		}
+
+		case AVRO_STRING:
+		{
+			char  *str;
+			int64_t  size;
+
+			/*
+			 * read_string returns a size that includes the
+			 * NUL terminator, and the free function will be
+			 * called with a size that also includes the NUL
+			 */
+
+			check_prefix(rval, avro_binary_encoding.
+				     read_string(reader, &str, &size),
+				     "Cannot read string value: ");
+
+			avro_wrapped_buffer_t  buf;
+			check(rval, avro_wrapped_alloc_new(&buf, str, size));
+			return avro_value_give_string_len(dest, &buf);
+		}
+
+		case AVRO_ARRAY:
+			return read_array_value(reader, dest);
+
+		case AVRO_ENUM:
+		{
+			int64_t  val;
+			check_prefix(rval, avro_binary_encoding.
+				     read_long(reader, &val),
+				     "Cannot read enum value: ");
+			return avro_value_set_enum(dest, val);
+		}
+
+		case AVRO_FIXED:
+		{
+			avro_schema_t  schema = avro_value_get_schema(dest);
+			char *bytes;
+			int64_t size = avro_schema_fixed_size(schema);
+
+			bytes = avro_malloc(size);
+			if (!bytes) {
+				avro_prefix_error("Cannot allocate new fixed value");
+				return ENOMEM;
+			}
+			rval = avro_read(reader, bytes, size);
+			if (rval) {
+				avro_prefix_error("Cannot read fixed value: ");
+				avro_free(bytes, size);
+				return rval;
+			}
+
+			avro_wrapped_buffer_t  buf;
+			rval = avro_wrapped_alloc_new(&buf, bytes, size);
+			if (rval != 0) {
+				avro_free(bytes, size);
+				return rval;
+			}
+
+			return avro_value_give_fixed(dest, &buf);
+		}
+
+		case AVRO_MAP:
+			return read_map_value(reader, dest);
+
+		case AVRO_RECORD:
+			return read_record_value(reader, dest);
+
+		case AVRO_UNION:
+			return read_union_value(reader, dest);
+
+		default:
+		{
+			avro_set_error("Unknown schema type");
+			return EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int
+avro_value_read(avro_reader_t reader, avro_value_t *dest)
+{
+	int  rval;
+	check(rval, avro_value_reset(dest));
+	return read_value(reader, dest);
+}

Added: avro/trunk/lang/c/src/value-sizeof.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/value-sizeof.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/src/value-sizeof.c (added)
+++ avro/trunk/lang/c/src/value-sizeof.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,231 @@
+/*
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "avro/basics.h"
+#include "avro/io.h"
+#include "avro/value.h"
+#include "avro_private.h"
+#include "encoding.h"
+
+
+/*
+ * Forward declaration; this is basically the same as avro_value_sizeof,
+ * but it doesn't initialize size first.  (Since it will have already
+ * been initialized in avro_value_sizeof itself).
+ */
+
+static int
+sizeof_value(avro_value_t *src, size_t *size);
+
+
+static int
+sizeof_array_value(avro_value_t *src, size_t *size)
+{
+	int  rval;
+	size_t  element_count;
+	check(rval, avro_value_get_size(src, &element_count));
+
+	if (element_count > 0) {
+		*size += avro_binary_encoding.size_long(NULL, element_count);
+
+		size_t  i;
+		for (i = 0; i < element_count; i++) {
+			avro_value_t  child;
+			check(rval, avro_value_get_by_index(src, i, &child, NULL));
+			check(rval, sizeof_value(&child, size));
+		}
+	}
+
+	*size += avro_binary_encoding.size_long(NULL, 0);
+	return 0;
+}
+
+
+static int
+sizeof_map_value(avro_value_t *src, size_t *size)
+{
+	int  rval;
+	size_t  element_count;
+	check(rval, avro_value_get_size(src, &element_count));
+
+	if (element_count > 0) {
+		*size += avro_binary_encoding.size_long(NULL, element_count);
+
+		size_t  i;
+		for (i = 0; i < element_count; i++) {
+			avro_value_t  child;
+			const char  *key;
+			check(rval, avro_value_get_by_index(src, i, &child, &key));
+			*size += avro_binary_encoding.size_string(NULL, key);
+			check(rval, sizeof_value(&child, size));
+		}
+	}
+
+	*size += avro_binary_encoding.size_long(NULL, 0);
+	return 0;
+}
+
+static int
+sizeof_record_value(avro_value_t *src, size_t *size)
+{
+	int  rval;
+	size_t  field_count;
+	check(rval, avro_value_get_size(src, &field_count));
+
+	size_t  i;
+	for (i = 0; i < field_count; i++) {
+		avro_value_t  field;
+		check(rval, avro_value_get_by_index(src, i, &field, NULL));
+		check(rval, sizeof_value(&field, size));
+	}
+
+	return 0;
+}
+
+static int
+sizeof_union_value(avro_value_t *src, size_t *size)
+{
+	int  rval;
+	int  discriminant;
+	avro_value_t  branch;
+
+	check(rval, avro_value_get_discriminant(src, &discriminant));
+	check(rval, avro_value_get_current_branch(src, &branch));
+	*size += avro_binary_encoding.size_long(NULL, discriminant);
+	return sizeof_value(&branch, size);
+}
+
+static int
+sizeof_value(avro_value_t *src, size_t *size)
+{
+	int  rval;
+
+	switch (avro_value_get_type(src)) {
+		case AVRO_BOOLEAN:
+		{
+			bool  val;
+			check(rval, avro_value_get_boolean(src, &val));
+			*size += avro_binary_encoding.size_boolean(NULL, val);
+			return 0;
+		}
+
+		case AVRO_BYTES:
+		{
+			const void  *buf;
+			size_t  sz;
+			check(rval, avro_value_get_bytes(src, &buf, &sz));
+			*size += avro_binary_encoding.size_bytes(NULL, buf, sz);
+			return 0;
+		}
+
+		case AVRO_DOUBLE:
+		{
+			double  val;
+			check(rval, avro_value_get_double(src, &val));
+			*size += avro_binary_encoding.size_double(NULL, val);
+			return 0;
+		}
+
+		case AVRO_FLOAT:
+		{
+			float  val;
+			check(rval, avro_value_get_float(src, &val));
+			*size += avro_binary_encoding.size_float(NULL, val);
+			return 0;
+		}
+
+		case AVRO_INT32:
+		{
+			int32_t  val;
+			check(rval, avro_value_get_int(src, &val));
+			*size += avro_binary_encoding.size_long(NULL, val);
+			return 0;
+		}
+
+		case AVRO_INT64:
+		{
+			int64_t  val;
+			check(rval, avro_value_get_long(src, &val));
+			*size += avro_binary_encoding.size_long(NULL, val);
+			return 0;
+		}
+
+		case AVRO_NULL:
+		{
+			check(rval, avro_value_get_null(src));
+			*size += avro_binary_encoding.size_null(NULL);
+			return 0;
+		}
+
+		case AVRO_STRING:
+		{
+			const char  *str;
+			size_t  sz;
+			check(rval, avro_value_get_string(src, &str, &sz));
+			*size += avro_binary_encoding.size_bytes(NULL, str, sz-1);
+			return 0;
+		}
+
+		case AVRO_ARRAY:
+			return sizeof_array_value(src, size);
+
+		case AVRO_ENUM:
+		{
+			int  val;
+			check(rval, avro_value_get_enum(src, &val));
+			*size += avro_binary_encoding.size_long(NULL, val);
+			return 0;
+		}
+
+		case AVRO_FIXED:
+		{
+			size_t  sz;
+			check(rval, avro_value_get_fixed(src, NULL, &sz));
+			*size += sz;
+			return 0;
+		}
+
+		case AVRO_MAP:
+			return sizeof_map_value(src, size);
+
+		case AVRO_RECORD:
+			return sizeof_record_value(src, size);
+
+		case AVRO_UNION:
+			return sizeof_union_value(src, size);
+
+		default:
+		{
+			avro_set_error("Unknown schema type");
+			return EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int
+avro_value_sizeof(avro_value_t *src, size_t *size)
+{
+	check_param(EINVAL, size, "size pointer");
+	*size = 0;
+	return sizeof_value(src, size);
+}

Added: avro/trunk/lang/c/src/value-write.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/value-write.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/src/value-write.c (added)
+++ avro/trunk/lang/c/src/value-write.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,210 @@
+/*
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "avro/basics.h"
+#include "avro/io.h"
+#include "avro/value.h"
+#include "avro_private.h"
+#include "encoding.h"
+
+
+static int
+write_array_value(avro_writer_t writer, avro_value_t *src)
+{
+	int  rval;
+	size_t  element_count;
+	check(rval, avro_value_get_size(src, &element_count));
+
+	if (element_count > 0) {
+		check_prefix(rval, avro_binary_encoding.write_long
+			     (writer, element_count),
+			     "Cannot write array block count: ");
+
+		size_t  i;
+		for (i = 0; i < element_count; i++) {
+			avro_value_t  child;
+			check(rval, avro_value_get_by_index(src, i, &child, NULL));
+			check(rval, avro_value_write(writer, &child));
+		}
+	}
+
+	check_prefix(rval, avro_binary_encoding.write_long(writer, 0),
+		     "Cannot write array block count: ");
+	return 0;
+}
+
+
+static int
+write_map_value(avro_writer_t writer, avro_value_t *src)
+{
+	int  rval;
+	size_t  element_count;
+	check(rval, avro_value_get_size(src, &element_count));
+
+	if (element_count > 0) {
+		check_prefix(rval, avro_binary_encoding.write_long
+			     (writer, element_count),
+			     "Cannot write map block count: ");
+
+		size_t  i;
+		for (i = 0; i < element_count; i++) {
+			avro_value_t  child;
+			const char  *key;
+			check(rval, avro_value_get_by_index(src, i, &child, &key));
+			check(rval, avro_binary_encoding.write_string(writer, key));
+			check(rval, avro_value_write(writer, &child));
+		}
+	}
+
+	check_prefix(rval, avro_binary_encoding.write_long(writer, 0),
+		     "Cannot write map block count: ");
+	return 0;
+}
+
+static int
+write_record_value(avro_writer_t writer, avro_value_t *src)
+{
+	int  rval;
+	size_t  field_count;
+	check(rval, avro_value_get_size(src, &field_count));
+
+	size_t  i;
+	for (i = 0; i < field_count; i++) {
+		avro_value_t  field;
+		check(rval, avro_value_get_by_index(src, i, &field, NULL));
+		check(rval, avro_value_write(writer, &field));
+	}
+
+	return 0;
+}
+
+static int
+write_union_value(avro_writer_t writer, avro_value_t *src)
+{
+	int  rval;
+	int  discriminant;
+	avro_value_t  branch;
+
+	check(rval, avro_value_get_discriminant(src, &discriminant));
+	check(rval, avro_value_get_current_branch(src, &branch));
+	check(rval, avro_binary_encoding.write_long(writer, discriminant));
+	return avro_value_write(writer, &branch);
+}
+
+int
+avro_value_write(avro_writer_t writer, avro_value_t *src)
+{
+	int  rval;
+
+	switch (avro_value_get_type(src)) {
+		case AVRO_BOOLEAN:
+		{
+			bool  val;
+			check(rval, avro_value_get_boolean(src, &val));
+			return avro_binary_encoding.write_boolean(writer, val);
+		}
+
+		case AVRO_BYTES:
+		{
+			const void  *buf;
+			size_t  size;
+			check(rval, avro_value_get_bytes(src, &buf, &size));
+			return avro_binary_encoding.write_bytes(writer, buf, size);
+		}
+
+		case AVRO_DOUBLE:
+		{
+			double  val;
+			check(rval, avro_value_get_double(src, &val));
+			return avro_binary_encoding.write_double(writer, val);
+		}
+
+		case AVRO_FLOAT:
+		{
+			float  val;
+			check(rval, avro_value_get_float(src, &val));
+			return avro_binary_encoding.write_float(writer, val);
+		}
+
+		case AVRO_INT32:
+		{
+			int32_t  val;
+			check(rval, avro_value_get_int(src, &val));
+			return avro_binary_encoding.write_long(writer, val);
+		}
+
+		case AVRO_INT64:
+		{
+			int64_t  val;
+			check(rval, avro_value_get_long(src, &val));
+			return avro_binary_encoding.write_long(writer, val);
+		}
+
+		case AVRO_NULL:
+		{
+			check(rval, avro_value_get_null(src));
+			return avro_binary_encoding.write_null(writer);
+		}
+
+		case AVRO_STRING:
+		{
+			const char  *str;
+			size_t  size;
+			check(rval, avro_value_get_string(src, &str, &size));
+			return avro_binary_encoding.write_bytes(writer, str, size-1);
+		}
+
+		case AVRO_ARRAY:
+			return write_array_value(writer, src);
+
+		case AVRO_ENUM:
+		{
+			int  val;
+			check(rval, avro_value_get_enum(src, &val));
+			return avro_binary_encoding.write_long(writer, val);
+		}
+
+		case AVRO_FIXED:
+		{
+			const void  *buf;
+			size_t  size;
+			check(rval, avro_value_get_fixed(src, &buf, &size));
+			return avro_write(writer, (void *) buf, size);
+		}
+
+		case AVRO_MAP:
+			return write_map_value(writer, src);
+
+		case AVRO_RECORD:
+			return write_record_value(writer, src);
+
+		case AVRO_UNION:
+			return write_union_value(writer, src);
+
+		default:
+		{
+			avro_set_error("Unknown schema type");
+			return EINVAL;
+		}
+	}
+
+	return 0;
+}

Added: avro/trunk/lang/c/src/value.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/value.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/src/value.c (added)
+++ avro/trunk/lang/c/src/value.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,472 @@
+/*
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avro/allocation.h"
+#include "avro/data.h"
+#include "avro/errors.h"
+#include "avro/value.h"
+#include "avro_private.h"
+
+int
+avro_value_new(const avro_value_iface_t *cls, avro_value_t *val)
+{
+	int  rval;
+
+	val->iface = cls;
+
+	size_t  instance_size = avro_value_instance_size(cls);
+	if (instance_size == 0) {
+		val->iface = NULL;
+		avro_set_error("Value class doesn't declare instance_size");
+		return EINVAL;
+	}
+
+	val->self = avro_malloc(instance_size);
+	if (val->self == NULL) {
+		avro_set_error(strerror(ENOMEM));
+		return ENOMEM;
+	}
+
+	rval = avro_value_init(cls, val->self);
+	if (rval) {
+		avro_free(val->self, instance_size);
+		val->self = NULL;
+		return rval;
+	}
+
+	return 0;
+}
+
+void
+avro_value_free(avro_value_t *val)
+{
+	if (val->self != NULL) {
+		avro_value_done(val);
+		avro_free(val->self, avro_value_instance_size(val->iface));
+	}
+}
+
+#define check_return(retval, call) \
+	do { \
+		int  rval = call; \
+		if (rval != 0) { return (retval); } \
+	} while (0)
+
+bool
+avro_value_equal_fast(avro_value_t *val1, avro_value_t *val2)
+{
+	avro_type_t  type1 = avro_value_get_type(val1);
+	avro_type_t  type2 = avro_value_get_type(val2);
+	if (type1 != type2) {
+		return false;
+	}
+
+	switch (type1) {
+		case AVRO_BOOLEAN:
+		{
+			bool  v1;
+			bool  v2;
+			check_return(false, avro_value_get_boolean(val1, &v1));
+			check_return(false, avro_value_get_boolean(val2, &v2));
+			return (v1 == v2);
+		}
+
+		case AVRO_BYTES:
+		{
+			const void  *buf1;
+			const void  *buf2;
+			size_t  size1;
+			size_t  size2;
+			check_return(false, avro_value_get_bytes(val1, &buf1, &size1));
+			check_return(false, avro_value_get_bytes(val2, &buf2, &size2));
+			if (size1 != size2) {
+				return false;
+			}
+			return (memcmp(buf1, buf2, size1) == 0);
+		}
+
+		case AVRO_DOUBLE:
+		{
+			double  v1;
+			double  v2;
+			check_return(false, avro_value_get_double(val1, &v1));
+			check_return(false, avro_value_get_double(val2, &v2));
+			return (v1 == v2);
+		}
+
+		case AVRO_FLOAT:
+		{
+			float  v1;
+			float  v2;
+			check_return(false, avro_value_get_float(val1, &v1));
+			check_return(false, avro_value_get_float(val2, &v2));
+			return (v1 == v2);
+		}
+
+		case AVRO_INT32:
+		{
+			int32_t  v1;
+			int32_t  v2;
+			check_return(false, avro_value_get_int(val1, &v1));
+			check_return(false, avro_value_get_int(val2, &v2));
+			return (v1 == v2);
+		}
+
+		case AVRO_INT64:
+		{
+			int64_t  v1;
+			int64_t  v2;
+			check_return(false, avro_value_get_long(val1, &v1));
+			check_return(false, avro_value_get_long(val2, &v2));
+			return (v1 == v2);
+		}
+
+		case AVRO_NULL:
+		{
+			check_return(false, avro_value_get_null(val1));
+			check_return(false, avro_value_get_null(val2));
+			return true;
+		}
+
+		case AVRO_STRING:
+		{
+			const char  *buf1;
+			const char  *buf2;
+			size_t  size1;
+			size_t  size2;
+			check_return(false, avro_value_get_string(val1, &buf1, &size1));
+			check_return(false, avro_value_get_string(val2, &buf2, &size2));
+			if (size1 != size2) {
+				return false;
+			}
+			return (memcmp(buf1, buf2, size1) == 0);
+		}
+
+		case AVRO_ARRAY:
+		{
+			size_t  count1;
+			size_t  count2;
+			check_return(false, avro_value_get_size(val1, &count1));
+			check_return(false, avro_value_get_size(val2, &count2));
+			if (count1 != count2) {
+				return false;
+			}
+
+			size_t  i;
+			for (i = 0; i < count1; i++) {
+				avro_value_t  child1;
+				avro_value_t  child2;
+				check_return(false, avro_value_get_by_index
+					     (val1, i, &child1, NULL));
+				check_return(false, avro_value_get_by_index
+					     (val2, i, &child2, NULL));
+				if (!avro_value_equal_fast(&child1, &child2)) {
+					return false;
+				}
+			}
+
+			return true;
+		}
+
+		case AVRO_ENUM:
+		{
+			int  v1;
+			int  v2;
+			check_return(false, avro_value_get_enum(val1, &v1));
+			check_return(false, avro_value_get_enum(val2, &v2));
+			return (v1 == v2);
+		}
+
+		case AVRO_FIXED:
+		{
+			const void  *buf1;
+			const void  *buf2;
+			size_t  size1;
+			size_t  size2;
+			check_return(false, avro_value_get_fixed(val1, &buf1, &size1));
+			check_return(false, avro_value_get_fixed(val2, &buf2, &size2));
+			if (size1 != size2) {
+				return false;
+			}
+			return (memcmp(buf1, buf2, size1) == 0);
+		}
+
+		case AVRO_MAP:
+		{
+			size_t  count1;
+			size_t  count2;
+			check_return(false, avro_value_get_size(val1, &count1));
+			check_return(false, avro_value_get_size(val2, &count2));
+			if (count1 != count2) {
+				return false;
+			}
+
+			size_t  i;
+			for (i = 0; i < count1; i++) {
+				avro_value_t  child1;
+				avro_value_t  child2;
+				const char  *key1;
+				check_return(false, avro_value_get_by_index
+					     (val1, i, &child1, &key1));
+				check_return(false, avro_value_get_by_name
+					     (val2, key1, &child2, NULL));
+				if (!avro_value_equal_fast(&child1, &child2)) {
+					return false;
+				}
+			}
+
+			return true;
+		}
+
+		case AVRO_RECORD:
+		{
+			size_t  count1;
+			check_return(false, avro_value_get_size(val1, &count1));
+
+			size_t  i;
+			for (i = 0; i < count1; i++) {
+				avro_value_t  child1;
+				avro_value_t  child2;
+				check_return(false, avro_value_get_by_index
+					     (val1, i, &child1, NULL));
+				check_return(false, avro_value_get_by_index
+					     (val2, i, &child2, NULL));
+				if (!avro_value_equal_fast(&child1, &child2)) {
+					return false;
+				}
+			}
+
+			return true;
+		}
+
+		case AVRO_UNION:
+		{
+			int  disc1;
+			int  disc2;
+			check_return(false, avro_value_get_discriminant(val1, &disc1));
+			check_return(false, avro_value_get_discriminant(val2, &disc2));
+			if (disc1 != disc2) {
+				return false;
+			}
+
+			avro_value_t  branch1;
+			avro_value_t  branch2;
+			check_return(false, avro_value_get_current_branch(val1, &branch1));
+			check_return(false, avro_value_get_current_branch(val2, &branch2));
+			return avro_value_equal_fast(&branch1, &branch2);
+		}
+
+		default:
+			return false;
+	}
+}
+
+bool
+avro_value_equal(avro_value_t *val1, avro_value_t *val2)
+{
+	avro_schema_t  schema1 = avro_value_get_schema(val1);
+	avro_schema_t  schema2 = avro_value_get_schema(val2);
+	if (!avro_schema_equal(schema1, schema2)) {
+		return false;
+	}
+
+	return avro_value_equal_fast(val1, val2);
+}
+
+
+int
+avro_value_copy_fast(avro_value_t *dest, const avro_value_t *src)
+{
+	avro_type_t  dest_type = avro_value_get_type(dest);
+	avro_type_t  src_type = avro_value_get_type(src);
+	if (dest_type != src_type) {
+		return false;
+	}
+
+	int  rval;
+	check(rval, avro_value_reset(dest));
+
+	switch (dest_type) {
+		case AVRO_BOOLEAN:
+		{
+			bool  val;
+			check(rval, avro_value_get_boolean(src, &val));
+			return avro_value_set_boolean(dest, val);
+		}
+
+		case AVRO_BYTES:
+		{
+			avro_wrapped_buffer_t  val;
+			check(rval, avro_value_grab_bytes(src, &val));
+			return avro_value_give_bytes(dest, &val);
+		}
+
+		case AVRO_DOUBLE:
+		{
+			double  val;
+			check(rval, avro_value_get_double(src, &val));
+			return avro_value_set_double(dest, val);
+		}
+
+		case AVRO_FLOAT:
+		{
+			float  val;
+			check(rval, avro_value_get_float(src, &val));
+			return avro_value_set_float(dest, val);
+		}
+
+		case AVRO_INT32:
+		{
+			int32_t  val;
+			check(rval, avro_value_get_int(src, &val));
+			return avro_value_set_int(dest, val);
+		}
+
+		case AVRO_INT64:
+		{
+			int64_t  val;
+			check(rval, avro_value_get_long(src, &val));
+			return avro_value_set_long(dest, val);
+		}
+
+		case AVRO_NULL:
+		{
+			check(rval, avro_value_get_null(src));
+			return avro_value_set_null(dest);
+		}
+
+		case AVRO_STRING:
+		{
+			avro_wrapped_buffer_t  val;
+			check(rval, avro_value_grab_string(src, &val));
+			return avro_value_give_string_len(dest, &val);
+		}
+
+		case AVRO_ARRAY:
+		{
+			size_t  count;
+			check(rval, avro_value_get_size(src, &count));
+
+			size_t  i;
+			for (i = 0; i < count; i++) {
+				avro_value_t  src_child;
+				avro_value_t  dest_child;
+
+				check(rval, avro_value_get_by_index
+				      (src, i, &src_child, NULL));
+				check(rval, avro_value_append
+				      (dest, &dest_child, NULL));
+				check(rval, avro_value_copy_fast
+				      (&dest_child, &src_child));
+			}
+
+			return 0;
+		}
+
+		case AVRO_ENUM:
+		{
+			int  val;
+			check(rval, avro_value_get_enum(src, &val));
+			return avro_value_set_enum(dest, val);
+		}
+
+		case AVRO_FIXED:
+		{
+			avro_wrapped_buffer_t  val;
+			check(rval, avro_value_grab_fixed(src, &val));
+			return avro_value_give_fixed(dest, &val);
+		}
+
+		case AVRO_MAP:
+		{
+			size_t  count;
+			check(rval, avro_value_get_size(src, &count));
+
+			size_t  i;
+			for (i = 0; i < count; i++) {
+				avro_value_t  src_child;
+				avro_value_t  dest_child;
+				const char  *key;
+
+				check(rval, avro_value_get_by_index
+				      (src, i, &src_child, &key));
+				check(rval, avro_value_add
+				      (dest, key, &dest_child, NULL, NULL));
+				check(rval, avro_value_copy_fast
+				      (&dest_child, &src_child));
+			}
+
+			return 0;
+		}
+
+		case AVRO_RECORD:
+		{
+			size_t  count;
+			check(rval, avro_value_get_size(src, &count));
+
+			size_t  i;
+			for (i = 0; i < count; i++) {
+				avro_value_t  src_child;
+				avro_value_t  dest_child;
+
+				check(rval, avro_value_get_by_index
+				      (src, i, &src_child, NULL));
+				check(rval, avro_value_get_by_index
+				      (dest, i, &dest_child, NULL));
+				check(rval, avro_value_copy_fast
+				      (&dest_child, &src_child));
+			}
+
+			return 0;
+		}
+
+		case AVRO_UNION:
+		{
+			int  disc;
+			check(rval, avro_value_get_discriminant(src, &disc));
+
+			avro_value_t  src_branch;
+			avro_value_t  dest_branch;
+
+			check(rval, avro_value_get_current_branch(src, &src_branch));
+			check(rval, avro_value_set_branch(dest, disc, &dest_branch));
+
+			return avro_value_copy_fast(&dest_branch, &src_branch);
+		}
+
+		default:
+			return 0;
+	}
+}
+
+
+int
+avro_value_copy(avro_value_t *dest, const avro_value_t *src)
+{
+	avro_schema_t  dest_schema = avro_value_get_schema(dest);
+	avro_schema_t  src_schema = avro_value_get_schema(src);
+	if (!avro_schema_equal(dest_schema, src_schema)) {
+		avro_set_error("Schemas don't match");
+		return EINVAL;
+	}
+
+	return avro_value_copy_fast(dest, src);
+}

Added: avro/trunk/lang/c/src/wrapped-buffer.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/src/wrapped-buffer.c?rev=1146546&view=auto
==============================================================================
--- avro/trunk/lang/c/src/wrapped-buffer.c (added)
+++ avro/trunk/lang/c/src/wrapped-buffer.c Thu Jul 14 02:35:04 2011
@@ -0,0 +1,124 @@
+/*
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avro_private.h"
+#include "avro/allocation.h"
+#include "avro/data.h"
+
+struct avro_wrapped_copy {
+	size_t  allocated_size;
+};
+
+static void
+avro_wrapped_copy_free(avro_wrapped_buffer_t *self)
+{
+	struct avro_wrapped_copy  *copy = self->user_data;
+	avro_free(copy, copy->allocated_size);
+}
+
+int
+avro_wrapped_buffer_new_copy(avro_wrapped_buffer_t *dest,
+			     const void *buf, size_t length)
+{
+	size_t  allocated_size = sizeof(struct avro_wrapped_copy) + length;
+	struct avro_wrapped_copy  *copy = avro_malloc(allocated_size);
+	if (copy == NULL) {
+		return ENOMEM;
+	}
+
+	dest->buf = ((void *) copy) + sizeof(struct avro_wrapped_copy);
+	dest->size = length;
+	dest->user_data = copy;
+	dest->free = avro_wrapped_copy_free;
+	dest->copy = NULL;
+	dest->slice = NULL;
+
+	copy->allocated_size = allocated_size;
+	memcpy((void *) dest->buf, buf, length);
+	return 0;
+}
+
+int
+avro_wrapped_buffer_new(avro_wrapped_buffer_t *dest,
+			const void *buf, size_t length)
+{
+	dest->buf = buf;
+	dest->size = length;
+	dest->user_data = NULL;
+	dest->free = NULL;
+	dest->copy = NULL;
+	dest->slice = NULL;
+	return 0;
+}
+
+
+void
+avro_wrapped_buffer_move(avro_wrapped_buffer_t *dest,
+			 avro_wrapped_buffer_t *src)
+{
+	memcpy(dest, src, sizeof(avro_wrapped_buffer_t));
+	memset(src, 0, sizeof(avro_wrapped_buffer_t));
+}
+
+int
+avro_wrapped_buffer_copy(avro_wrapped_buffer_t *dest,
+			 const avro_wrapped_buffer_t *src,
+			 size_t offset, size_t length)
+{
+	if (offset >= src->size) {
+		avro_set_error("Invalid offset when slicing buffer");
+		return EINVAL;
+	}
+
+	if ((offset+length) > src->size) {
+		avro_set_error("Invalid length when slicing buffer");
+		return EINVAL;
+	}
+
+	if (src->copy == NULL) {
+		return avro_wrapped_buffer_new_copy(dest, src->buf + offset, length);
+	} else {
+		return src->copy(dest, src, offset, length);
+	}
+}
+
+int
+avro_wrapped_buffer_slice(avro_wrapped_buffer_t *self,
+			  size_t offset, size_t length)
+{
+	if (offset >= self->size) {
+		avro_set_error("Invalid offset when slicing buffer");
+		return EINVAL;
+	}
+
+	if ((offset+length) > self->size) {
+		avro_set_error("Invalid length when slicing buffer");
+		return EINVAL;
+	}
+
+	if (self->slice == NULL) {
+		self->buf += offset;
+		self->size = length;
+		return 0;
+	} else {
+		return self->slice(self, offset, length);
+	}
+}

Modified: avro/trunk/lang/c/tests/.gitignore
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/.gitignore?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/.gitignore (original)
+++ avro/trunk/lang/c/tests/.gitignore Thu Jul 14 02:35:04 2011
@@ -3,5 +3,7 @@ performance
 test_avro_data
 test_avro_schema
 test_avro_schema_names
+test_avro_values
 test_cpp
+test_data_structures
 test_interop_data

Modified: avro/trunk/lang/c/tests/CMakeLists.txt
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/CMakeLists.txt?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/CMakeLists.txt (original)
+++ avro/trunk/lang/c/tests/CMakeLists.txt Thu Jul 14 02:35:04 2011
@@ -26,6 +26,10 @@ target_link_libraries(performance avro-s
 add_executable(test_interop_data test_interop_data.c)
 target_link_libraries(test_interop_data avro-static)
 
+add_executable(test_data_structures test_data_structures.c)
+target_link_libraries(test_data_structures avro-static)
+add_test(test_data_structures ${CMAKE_COMMAND} -E chdir ${AvroC_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/test_data_structures)
+
 add_executable(test_avro_schema test_avro_schema.c)
 target_link_libraries(test_avro_schema avro-static)
 add_test(test_avro_schema ${CMAKE_COMMAND} -E chdir ${AvroC_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/test_avro_schema)
@@ -34,6 +38,10 @@ add_executable(test_avro_schema_names te
 target_link_libraries(test_avro_schema_names avro-static)
 add_test(test_avro_schema_names ${CMAKE_COMMAND} -E chdir ${AvroC_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/test_avro_schema_names)
 
+add_executable(test_avro_values test_avro_values.c)
+target_link_libraries(test_avro_values avro-static)
+add_test(test_avro_values ${CMAKE_COMMAND} -E chdir ${AvroC_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/test_avro_values)
+
 add_executable(test_avro_data test_avro_data.c)
 target_link_libraries(test_avro_data avro-static)
 add_test(test_avro_data ${CMAKE_COMMAND} -E chdir ${AvroC_SOURCE_DIR}/tests ${CMAKE_CURRENT_BINARY_DIR}/test_avro_data)

Modified: avro/trunk/lang/c/tests/Makefile.am
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/Makefile.am?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/Makefile.am (original)
+++ avro/trunk/lang/c/tests/Makefile.am Thu Jul 14 02:35:04 2011
@@ -5,18 +5,26 @@ ACLOCAL_AMFLAGS=-I m4
 
 EXTRA_DIST=schema_tests test_valgrind
 
-check_PROGRAMS=test_avro_schema test_avro_schema_names test_avro_data test_cpp
+check_PROGRAMS=test_avro_schema test_avro_schema_names test_avro_data test_cpp \
+test_avro_values \
+test_data_structures
 
 noinst_PROGRAMS=generate_interop_data test_interop_data performance
 
 test_LDADD=$(top_builddir)/src/libavro.la
 
+test_data_structures_SOURCES=test_data_structures.c
+test_data_structures_LDADD=$(test_LDADD)
+
 test_avro_schema_SOURCES=test_avro_schema.c
 test_avro_schema_LDADD=$(test_LDADD)
 
 test_avro_schema_names_SOURCES=test_avro_schema_names.c
 test_avro_schema_names_LDADD=$(test_LDADD)
 
+test_avro_values_SOURCES=test_avro_values.c
+test_avro_values_LDADD=$(test_LDADD)
+
 test_avro_data_SOURCES=test_avro_data.c
 test_avro_data_LDADD=$(test_LDADD)
 

Modified: avro/trunk/lang/c/tests/generate_interop_data.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/generate_interop_data.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/generate_interop_data.c (original)
+++ avro/trunk/lang/c/tests/generate_interop_data.c Thu Jul 14 02:35:04 2011
@@ -15,6 +15,7 @@
  * permissions and limitations under the License. 
  */
 
+#include "avro.h"
 #include "avro_private.h"
 #include <stdio.h>
 #include <stdlib.h>

Modified: avro/trunk/lang/c/tests/performance.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/performance.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/performance.c (original)
+++ avro/trunk/lang/c/tests/performance.c Thu Jul 14 02:35:04 2011
@@ -28,7 +28,7 @@
  */
 
 typedef void
-(*test_func_t)(void);
+(*test_func_t)(unsigned long);
 
 
 void init_rand(void)
@@ -60,13 +60,12 @@ int32_t rand_int32(void)
  */
 
 static void
-test_refcount(void)
+test_refcount(unsigned long num_tests)
 {
-	const unsigned long  NUM_TESTS = 100000000;
 	unsigned long  i;
 
 	avro_datum_t  datum = avro_int32(42);
-	for (i = 0; i < NUM_TESTS; i++) {
+	for (i = 0; i < num_tests; i++) {
 		avro_datum_incref(datum);
 		avro_datum_decref(datum);
 	}
@@ -76,11 +75,11 @@ test_refcount(void)
 
 /**
  * Tests the performance of serializing and deserializing a somewhat
- * complex record type.
+ * complex record type using the legacy datum API.
  */
 
 static void
-test_nested_record(void)
+test_nested_record_datum(unsigned long num_tests)
 {
 	static const char  *schema_json =
 		"{"
@@ -123,12 +122,11 @@ test_nested_record(void)
 	avro_schema_from_json(schema_json, strlen(schema_json),
 			      &schema, &error);
 
-	const unsigned long  NUM_TESTS = 100000;
 	unsigned long  i;
 
 	avro_datum_t  in = avro_datum_from_schema(schema);
 
-	for (i = 0; i < NUM_TESTS; i++) {
+	for (i = 0; i < num_tests; i++) {
 		avro_record_set_field_value(rc, in, int32, "i", rand_int32());
 		avro_record_set_field_value(rc, in, int64, "l", rand_int64());
 		avro_record_set_field_value(rc, in, givestring, "s",
@@ -154,6 +152,207 @@ test_nested_record(void)
 	}
 
 	avro_datum_decref(in);
+	avro_schema_decref(schema);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record fields
+ * by index.
+ */
+
+static void
+test_nested_record_value_by_index(unsigned long num_tests)
+{
+	static const char  *schema_json =
+		"{"
+		"  \"type\": \"record\","
+		"  \"name\": \"test\","
+		"  \"fields\": ["
+		"    { \"name\": \"i\", \"type\": \"int\" },"
+		"    { \"name\": \"l\", \"type\": \"long\" },"
+		"    { \"name\": \"s\", \"type\": \"string\" },"
+		"    {"
+		"      \"name\": \"subrec\","
+		"      \"type\": {"
+		"        \"type\": \"record\","
+		"        \"name\": \"sub\","
+		"        \"fields\": ["
+		"          { \"name\": \"f\", \"type\": \"float\" },"
+		"          { \"name\": \"d\", \"type\": \"double\" }"
+		"        ]"
+		"      }"
+		"    }"
+		"  ]"
+		"}";
+
+	static char *strings[] = {
+		"Four score and seven years ago",
+		"our father brought forth on this continent",
+		"a new nation", "conceived in Liberty",
+		"and dedicated to the proposition that all men are created equal."
+	};
+	static const unsigned int  NUM_STRINGS =
+	    sizeof(strings) / sizeof(strings[0]);
+
+	static char  buf[4096];
+	avro_reader_t  reader;
+	avro_writer_t  writer;
+
+	avro_schema_t  schema = NULL;
+	avro_schema_error_t  error = NULL;
+	avro_schema_from_json(schema_json, strlen(schema_json),
+			      &schema, &error);
+
+	unsigned long  i;
+
+	avro_value_iface_t  *iface = avro_generic_class_from_schema(schema);
+
+	avro_value_t  val;
+	avro_value_new(iface, &val);
+
+	avro_value_t  out;
+	avro_value_new(iface, &out);
+
+	for (i = 0; i < num_tests; i++) {
+		avro_value_t  field;
+
+		avro_value_get_by_index(&val, 0, &field, NULL);
+		avro_value_set_int(&field, rand_int32());
+
+		avro_value_get_by_index(&val, 1, &field, NULL);
+		avro_value_set_long(&field, rand_int64());
+
+		avro_wrapped_buffer_t  wbuf;
+		avro_wrapped_buffer_new_string(&wbuf, strings[i % NUM_STRINGS]);
+		avro_value_get_by_index(&val, 2, &field, NULL);
+		avro_value_give_string_len(&field, &wbuf);
+
+		avro_value_t  subrec;
+		avro_value_get_by_index(&val, 3, &subrec, NULL);
+
+		avro_value_get_by_index(&subrec, 0, &field, NULL);
+		avro_value_set_float(&field, rand_number(-1e10, 1e10));
+
+		avro_value_get_by_index(&subrec, 1, &field, NULL);
+		avro_value_set_double(&field, rand_number(-1e10, 1e10));
+
+		writer = avro_writer_memory(buf, sizeof(buf));
+		avro_value_write(writer, &val);
+		avro_writer_free(writer);
+
+		reader = avro_reader_memory(buf, sizeof(buf));
+		avro_value_read(reader, &out);
+		avro_reader_free(reader);
+
+		avro_value_equal_fast(&val, &out);
+	}
+
+	avro_value_free(&val);
+	avro_value_free(&out);
+	avro_value_iface_decref(iface);
+	avro_schema_decref(schema);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record fields
+ * by name.
+ */
+
+static void
+test_nested_record_value_by_name(unsigned long num_tests)
+{
+	static const char  *schema_json =
+		"{"
+		"  \"type\": \"record\","
+		"  \"name\": \"test\","
+		"  \"fields\": ["
+		"    { \"name\": \"i\", \"type\": \"int\" },"
+		"    { \"name\": \"l\", \"type\": \"long\" },"
+		"    { \"name\": \"s\", \"type\": \"string\" },"
+		"    {"
+		"      \"name\": \"subrec\","
+		"      \"type\": {"
+		"        \"type\": \"record\","
+		"        \"name\": \"sub\","
+		"        \"fields\": ["
+		"          { \"name\": \"f\", \"type\": \"float\" },"
+		"          { \"name\": \"d\", \"type\": \"double\" }"
+		"        ]"
+		"      }"
+		"    }"
+		"  ]"
+		"}";
+
+	static char *strings[] = {
+		"Four score and seven years ago",
+		"our father brought forth on this continent",
+		"a new nation", "conceived in Liberty",
+		"and dedicated to the proposition that all men are created equal."
+	};
+	static const unsigned int  NUM_STRINGS =
+	    sizeof(strings) / sizeof(strings[0]);
+
+	static char  buf[4096];
+	avro_reader_t  reader;
+	avro_writer_t  writer;
+
+	avro_schema_t  schema = NULL;
+	avro_schema_error_t  error = NULL;
+	avro_schema_from_json(schema_json, strlen(schema_json),
+			      &schema, &error);
+
+	unsigned long  i;
+
+	avro_value_iface_t  *iface = avro_generic_class_from_schema(schema);
+
+	avro_value_t  val;
+	avro_value_new(iface, &val);
+
+	avro_value_t  out;
+	avro_value_new(iface, &out);
+
+	for (i = 0; i < num_tests; i++) {
+		avro_value_t  field;
+
+		avro_value_get_by_name(&val, "i", &field, NULL);
+		avro_value_set_int(&field, rand_int32());
+
+		avro_value_get_by_name(&val, "l", &field, NULL);
+		avro_value_set_long(&field, rand_int64());
+
+		avro_wrapped_buffer_t  wbuf;
+		avro_wrapped_buffer_new_string(&wbuf, strings[i % NUM_STRINGS]);
+		avro_value_get_by_name(&val, "s", &field, NULL);
+		avro_value_give_string_len(&field, &wbuf);
+
+		avro_value_t  subrec;
+		avro_value_get_by_name(&val, "subrec", &subrec, NULL);
+
+		avro_value_get_by_name(&subrec, "f", &field, NULL);
+		avro_value_set_float(&field, rand_number(-1e10, 1e10));
+
+		avro_value_get_by_name(&subrec, "d", &field, NULL);
+		avro_value_set_double(&field, rand_number(-1e10, 1e10));
+
+		writer = avro_writer_memory(buf, sizeof(buf));
+		avro_value_write(writer, &val);
+		avro_writer_free(writer);
+
+		reader = avro_reader_memory(buf, sizeof(buf));
+		avro_value_read(reader, &out);
+		avro_reader_free(reader);
+
+		avro_value_equal_fast(&val, &out);
+	}
+
+	avro_value_free(&val);
+	avro_value_free(&out);
+	avro_value_iface_decref(iface);
+	avro_schema_decref(schema);
 }
 
 
@@ -174,14 +373,22 @@ main(int argc, char **argv)
 	unsigned int  i;
 	struct avro_tests {
 		const char  *name;
+		unsigned long  num_tests;
 		test_func_t  func;
 	} tests[] = {
-		{ "refcount", test_refcount },
-		{ "nested record", test_nested_record }
+		{ "refcount", 100000000,
+		  test_refcount },
+		{ "nested record (legacy)", 100000,
+		  test_nested_record_datum },
+		{ "nested record (value by index)", 1000000,
+		  test_nested_record_value_by_index },
+		{ "nested record (value by name)", 1000000,
+		  test_nested_record_value_by_name },
 	};
 
 	for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
-		fprintf(stderr, "**** Running %s ****\n", tests[i].name);
+		fprintf(stderr, "**** Running %s ****\n  %lu tests per run\n",
+			tests[i].name, tests[i].num_tests);
 		unsigned int  run;
 
 		double  sum = 0.0;
@@ -190,13 +397,15 @@ main(int argc, char **argv)
 			fprintf(stderr, "  Run %u\n", run);
 
 			clock_t  before = clock();
-			tests[i].func();
+			tests[i].func(tests[i].num_tests);
 			clock_t  after = clock();
 			double  secs = ((double) after-before) / CLOCKS_PER_SEC;
 			sum += secs;
 		}
 
-		fprintf(stderr, "  Average time: %.03lf seconds\n", sum / NUM_RUNS);
+		fprintf(stderr, "  Average time: %.03lfs\n", sum / NUM_RUNS);
+		fprintf(stderr, "  Tests/sec:    %.0lf\n",
+			tests[i].num_tests / (sum / NUM_RUNS));
 	}
 
 	return EXIT_SUCCESS;

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=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_data.c (original)
+++ avro/trunk/lang/c/tests/test_avro_data.c Thu Jul 14 02:35:04 2011
@@ -15,6 +15,7 @@
  * permissions and limitations under the License. 
  */
 
+#include "avro.h"
 #include "avro_private.h"
 #include <inttypes.h>
 #include <limits.h>
@@ -101,8 +102,8 @@ write_read_check(avro_schema_t writers_s
 		/* Validating read/write */
 		if (avro_write_data
 		    (writer, validate ? writers_schema : NULL, datum)) {
-			fprintf(stderr, "Unable to write %s validate=%d\n",
-				type, validate);
+			fprintf(stderr, "Unable to write %s validate=%d\n  %s\n",
+				type, validate, avro_strerror());
 			exit(EXIT_FAILURE);
 		}
 		int64_t size =
@@ -110,21 +111,23 @@ write_read_check(avro_schema_t writers_s
 				   datum);
 		if (size != avro_writer_tell(writer)) {
 			fprintf(stderr,
-				"Unable to calculate size %s validate=%d (%"PRId64" != %"PRId64")\n",
-				type, validate, size, avro_writer_tell(writer));
+				"Unable to calculate size %s validate=%d "
+				"(%"PRId64" != %"PRId64")\n  %s\n",
+				type, validate, size, avro_writer_tell(writer),
+				avro_strerror());
 			exit(EXIT_FAILURE);
 		}
 		if (avro_read_data
 		    (reader, writers_schema, readers_schema, &datum_out)) {
-			fprintf(stderr, "Unable to read %s validate=%d\n", type,
-				validate);
+			fprintf(stderr, "Unable to read %s validate=%d\n  %s\n",
+				type, validate, avro_strerror());
 			fprintf(stderr, "  %s\n", avro_strerror());
 			exit(EXIT_FAILURE);
 		}
 		if (!avro_datum_equal(expected, datum_out)) {
 			fprintf(stderr,
-				"Unable to encode/decode %s validate=%d\n",
-				type, validate);
+				"Unable to encode/decode %s validate=%d\n  %s\n",
+				type, validate, avro_strerror());
 			exit(EXIT_FAILURE);
 		}
 
@@ -536,6 +539,21 @@ static int test_map(void)
 		exit(EXIT_FAILURE);
 	}
 
+	int  index;
+	if (avro_map_get_index(datum, "two", &index)) {
+		fprintf(stderr, "Can't get index for key \"two\": %s\n",
+			avro_strerror());
+		exit(EXIT_FAILURE);
+	}
+	if (index != 2) {
+		fprintf(stderr, "Unexpected index for key \"two\"\n");
+		exit(EXIT_FAILURE);
+	}
+	if (!avro_map_get_index(datum, "foobar", &index)) {
+		fprintf(stderr, "Unexpected index for key \"foobar\"\n");
+		exit(EXIT_FAILURE);
+	}
+
 	write_read_check(schema, datum, NULL, NULL, "map");
 	test_json(datum,
 		  "{\"zero\": 0, \"one\": 1, \"two\": 2, \"three\": 3, "

Modified: avro/trunk/lang/c/tests/test_avro_schema.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_schema.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_schema.c (original)
+++ avro/trunk/lang/c/tests/test_avro_schema.c Thu Jul 14 02:35:04 2011
@@ -15,6 +15,7 @@
  * permissions and limitations under the License. 
  */
 
+#include "avro.h"
 #include "avro_private.h"
 #include <stdio.h>
 #include <stdlib.h>

Modified: avro/trunk/lang/c/tests/test_avro_schema_names.c
URL: http://svn.apache.org/viewvc/avro/trunk/lang/c/tests/test_avro_schema_names.c?rev=1146546&r1=1146545&r2=1146546&view=diff
==============================================================================
--- avro/trunk/lang/c/tests/test_avro_schema_names.c (original)
+++ avro/trunk/lang/c/tests/test_avro_schema_names.c Thu Jul 14 02:35:04 2011
@@ -15,6 +15,7 @@
  * permissions and limitations under the License. 
  */
 
+#include "avro.h"
 #include "avro_private.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -130,5 +131,7 @@ int main(int argc, char *argv[])
 
  test_record_schema_01();
 
+ test_union_schema_01();
+
  return EXIT_SUCCESS;
 }