static int avro_datum_value_append(const avro_value_iface_t *iface, void *vself, avro_value_t *child_out, size_t *new_index) { AVRO_UNUSED(iface); avro_datum_t self = (avro_datum_t) vself; check_param(EINVAL, self, "datum instance"); if (!is_avro_array(self)) { avro_set_error("Can only append to array"); return EINVAL; } int rval; avro_schema_t array_schema = avro_datum_get_schema(self); avro_schema_t child_schema = avro_schema_array_items(array_schema); avro_datum_t child_datum = avro_datum_from_schema(child_schema); if (child_datum == NULL) { return ENOMEM; } rval = avro_array_append_datum(self, child_datum); avro_datum_decref(child_datum); if (rval != 0) { return rval; } if (new_index != NULL) { *new_index = avro_array_size(self) - 1; } return avro_datum_as_child_value(child_out, child_datum); }
static avro_datum_t json_t_to_avro_value( const avro_schema_t schema, const json_t *json) { avro_datum_t datum = avro_datum_from_schema(schema); if (datum == NULL) return NULL; int rval = json_t_to_avro_value_helper(schema, json, datum); if (rval) { avro_datum_decref(datum); return NULL; } return datum; }
static int avro_datum_value_add(const avro_value_iface_t *iface, void *vself, const char *key, avro_value_t *child, size_t *index, int *is_new) { AVRO_UNUSED(iface); avro_datum_t self = (avro_datum_t) vself; check_param(EINVAL, self, "datum instance"); if (!is_avro_map(self)) { avro_set_error("Can only add to map"); return EINVAL; } int rval; avro_datum_t child_datum; if (avro_map_get(self, key, &child_datum) == 0) { /* key already exists */ if (is_new != NULL) { *is_new = 0; } if (index != NULL) { int real_index; avro_map_get_index(self, key, &real_index); *index = real_index; } return avro_datum_as_child_value(child, child_datum); } /* key is new */ avro_schema_t map_schema = avro_datum_get_schema(self); avro_schema_t child_schema = avro_schema_map_values(map_schema); child_datum = avro_datum_from_schema(child_schema); if (child_datum == NULL) { return ENOMEM; } rval = avro_map_set(self, key, child_datum); avro_datum_decref(child_datum); if (rval != 0) { return rval; } if (is_new != NULL) { *is_new = 1; } if (index != NULL) { *index = avro_map_size(self) - 1; } return avro_datum_as_child_value(child, child_datum); }
static int test_union(void) { avro_schema_t schema = avro_schema_union(); avro_datum_t union_datum; avro_datum_t datum; avro_datum_t union_datum1; avro_datum_t datum1; avro_schema_union_append(schema, avro_schema_string()); avro_schema_union_append(schema, avro_schema_int()); avro_schema_union_append(schema, avro_schema_null()); datum = avro_givestring("Follow your bliss.", NULL); union_datum = avro_union(schema, 0, datum); if (avro_union_discriminant(union_datum) != 0) { fprintf(stderr, "Unexpected union discriminant\n"); exit(EXIT_FAILURE); } if (avro_union_current_branch(union_datum) != datum) { fprintf(stderr, "Unexpected union branch datum\n"); exit(EXIT_FAILURE); } union_datum1 = avro_datum_from_schema(schema); avro_union_set_discriminant(union_datum1, 0, &datum1); avro_givestring_set(datum1, "Follow your bliss.", NULL); if (!avro_datum_equal(datum, datum1)) { fprintf(stderr, "Union values should be equal\n"); exit(EXIT_FAILURE); } write_read_check(schema, union_datum, NULL, NULL, "union"); test_json(union_datum, "{\"string\": \"Follow your bliss.\"}"); avro_datum_decref(datum); avro_union_set_discriminant(union_datum, 2, &datum); test_json(union_datum, "null"); avro_datum_decref(union_datum); avro_datum_decref(datum); avro_datum_decref(union_datum1); avro_schema_decref(schema); return 0; }
static int test_nested_record(void) { const char *json = "{" " \"type\": \"record\"," " \"name\": \"list\"," " \"fields\": [" " { \"name\": \"x\", \"type\": \"int\" }," " { \"name\": \"y\", \"type\": \"int\" }," " { \"name\": \"next\", \"type\": [\"null\",\"list\"]}" " ]" "}"; int rval; avro_schema_t schema = NULL; avro_schema_error_t error; avro_schema_from_json(json, strlen(json), &schema, &error); avro_datum_t head = avro_datum_from_schema(schema); avro_record_set_field_value(rval, head, int32, "x", 10); avro_record_set_field_value(rval, head, int32, "y", 10); avro_datum_t next = NULL; avro_datum_t tail = NULL; avro_record_get(head, "next", &next); avro_union_set_discriminant(next, 1, &tail); avro_record_set_field_value(rval, tail, int32, "x", 20); avro_record_set_field_value(rval, tail, int32, "y", 20); avro_record_get(tail, "next", &next); avro_union_set_discriminant(next, 0, NULL); write_read_check(schema, head, NULL, NULL, "nested record"); avro_schema_decref(schema); avro_datum_decref(head); return 0; }
avro_datum_t avro_datum_from_schema(const avro_schema_t schema) { check_param(NULL, is_avro_schema(schema), "schema"); switch (avro_typeof(schema)) { case AVRO_STRING: return avro_givestring("", NULL); case AVRO_BYTES: return avro_givebytes("", 0, NULL); case AVRO_INT32: return avro_int32(0); case AVRO_INT64: return avro_int64(0); case AVRO_FLOAT: return avro_float(0); case AVRO_DOUBLE: return avro_double(0); case AVRO_BOOLEAN: return avro_boolean(0); case AVRO_NULL: return avro_null(); case AVRO_RECORD: { const struct avro_record_schema_t *record_schema = avro_schema_to_record(schema); avro_datum_t rec = avro_record(schema); int i; for (i = 0; i < record_schema->fields->num_entries; i++) { union { st_data_t data; struct avro_record_field_t *field; } val; st_lookup(record_schema->fields, i, &val.data); avro_datum_t field = avro_datum_from_schema(val.field->type); avro_record_set(rec, val.field->name, field); avro_datum_decref(field); } return rec; } case AVRO_ENUM: return avro_enum(schema, 0); case AVRO_FIXED: { const struct avro_fixed_schema_t *fixed_schema = avro_schema_to_fixed(schema); return avro_givefixed(schema, NULL, fixed_schema->size, NULL); } case AVRO_MAP: return avro_map(schema); case AVRO_ARRAY: return avro_array(schema); case AVRO_UNION: return avro_union(schema, -1, NULL); case AVRO_LINK: { const struct avro_link_schema_t *link_schema = avro_schema_to_link(schema); return avro_datum_from_schema(link_schema->to); } default: avro_set_error("Unknown schema type"); return NULL; } }