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;
}