Exemple #1
0
static PyObject *
record_to_python_object(ConvertInfo *info, avro_value_t *value)
{
    size_t field_count;
    size_t i;

    avro_schema_t schema = avro_value_get_schema(value);
    PyObject *type = get_python_obj_type(info->types, schema);

    AvroRecord *obj = (AvroRecord *)PyObject_CallFunctionObjArgs(type, NULL);

    Py_DECREF(type);

    avro_value_get_size(value, &field_count);

    for (i = 0; i < field_count; i++) {
        avro_value_t field_value;
        PyObject *pyelement_value;

        avro_value_get_by_index(value, i, &field_value, NULL);

        pyelement_value = avro_to_python(info, &field_value);

        obj->fields[i] = pyelement_value;
    }

    return (PyObject *)obj;
}
Exemple #2
0
static PyObject *
map_to_python(ConvertInfo *info, avro_value_t *value)
{
    size_t  element_count;
    PyObject *result = PyDict_New();
    size_t  i;

    avro_value_get_size(value, &element_count);

    for (i = 0; i < element_count; i++) {
        const char  *key;
        avro_value_t  element_value;
        PyObject *pykey;
        PyObject *pyelement_value;

        avro_value_get_by_index(value, i, &element_value, &key);

        pykey = (PyObject *)PyString_FromString(key);
        pyelement_value = avro_to_python(info, &element_value);

        /* increfs key and value */
        PyDict_SetItem(result, pykey, pyelement_value);

        Py_DECREF(pykey);
        Py_DECREF(pyelement_value);
    }

    return result;
}
Exemple #3
0
static PyObject *
array_to_python(ConvertInfo *info, avro_value_t *value)
{
    size_t  element_count;
    PyObject *result;
    size_t  i;

    avro_value_get_size(value, &element_count);

    result = PyList_New(element_count);

    for (i = 0; i < element_count; i++) {
        avro_value_t  element_value;
        PyObject *pyelement_value;

        avro_value_get_by_index(value, i, &element_value, NULL);

        pyelement_value = avro_to_python(info, &element_value);

        /* steals a ref to pyelement_value */
        PyList_SET_ITEM(result, i, pyelement_value);
    }

    return result;
}
int process_frame_table_schema(avro_value_t *record_val, frame_reader_t reader, uint64_t wal_pos) {
    int err = 0, key_schema_present;
    avro_value_t relid_val, hash_val, key_schema_val, row_schema_val, branch_val;
    int64_t relid;
    const void *hash;
    const char *key_schema_json = NULL, *row_schema_json;
    size_t hash_len, key_schema_len = 1, row_schema_len;
    avro_schema_t key_schema = NULL, row_schema;

    check(err, avro_value_get_by_index(record_val, 0, &relid_val,      NULL));
    check(err, avro_value_get_by_index(record_val, 1, &hash_val,       NULL));
    check(err, avro_value_get_by_index(record_val, 2, &key_schema_val, NULL));
    check(err, avro_value_get_by_index(record_val, 3, &row_schema_val, NULL));
    check(err, avro_value_get_long(&relid_val, &relid));
    check(err, avro_value_get_fixed(&hash_val, &hash, &hash_len));
    check(err, avro_value_get_discriminant(&key_schema_val, &key_schema_present));
    check(err, avro_value_get_string(&row_schema_val, &row_schema_json, &row_schema_len));
    check(err, avro_schema_from_json_length(row_schema_json, row_schema_len - 1, &row_schema));

    schema_list_entry *entry = schema_list_replace(reader, relid);
    entry->relid = relid;
    entry->hash = *((uint64_t *) hash);
    entry->row_schema = row_schema;
    entry->row_iface = avro_generic_class_from_schema(row_schema);
    avro_generic_value_new(entry->row_iface, &entry->row_value);
    avro_generic_value_new(entry->row_iface, &entry->old_value);
    entry->avro_reader = avro_reader_memory(NULL, 0);

    if (key_schema_present) {
        check(err, avro_value_get_current_branch(&key_schema_val, &branch_val));
        check(err, avro_value_get_string(&branch_val, &key_schema_json, &key_schema_len));
        check(err, avro_schema_from_json_length(key_schema_json, key_schema_len - 1, &key_schema));
        entry->key_schema = key_schema;
        entry->key_iface = avro_generic_class_from_schema(key_schema);
        avro_generic_value_new(entry->key_iface, &entry->key_value);
    } else {
        entry->key_schema = NULL;
    }

    if (reader->on_table_schema) {
        check(err, reader->on_table_schema(reader->cb_context, wal_pos, relid,
                                           key_schema_json, key_schema_len - 1, key_schema,
                                           row_schema_json, row_schema_len - 1, row_schema));
    }
    return err;
}
int process_frame_update(avro_value_t *record_val, frame_reader_t reader, uint64_t wal_pos) {
    int err = 0, key_present, old_present;
    avro_value_t relid_val, key_val, old_val, new_val, branch_val;
    int64_t relid;
    const void *key_bin = NULL, *old_bin = NULL, *new_bin = NULL;
    size_t key_len = 0, old_len = 0, new_len = 0;

    check(err, avro_value_get_by_index(record_val, 0, &relid_val, NULL));
    check(err, avro_value_get_by_index(record_val, 1, &key_val,   NULL));
    check(err, avro_value_get_by_index(record_val, 2, &old_val,   NULL));
    check(err, avro_value_get_by_index(record_val, 3, &new_val,   NULL));
    check(err, avro_value_get_long(&relid_val, &relid));
    check(err, avro_value_get_discriminant(&key_val, &key_present));
    check(err, avro_value_get_discriminant(&old_val, &old_present));
    check(err, avro_value_get_bytes(&new_val, &new_bin, &new_len));

    schema_list_entry *entry = schema_list_lookup(reader, relid);
    if (!entry) {
        avro_set_error("Received update for unknown relid %u", relid);
        return EINVAL;
    }

    if (key_present) {
        check(err, avro_value_get_current_branch(&key_val, &branch_val));
        check(err, avro_value_get_bytes(&branch_val, &key_bin, &key_len));
        check(err, read_entirely(&entry->key_value, entry->avro_reader, key_bin, key_len));
    }

    if (old_present) {
        check(err, avro_value_get_current_branch(&old_val, &branch_val));
        check(err, avro_value_get_bytes(&branch_val, &old_bin, &old_len));
        check(err, read_entirely(&entry->old_value, entry->avro_reader, old_bin, old_len));
    }

    check(err, read_entirely(&entry->row_value, entry->avro_reader, new_bin, new_len));

    if (reader->on_update_row) {
        check(err, reader->on_update_row(reader->cb_context, wal_pos, relid,
                                         key_bin, key_len, key_bin ? &entry->key_value : NULL,
                                         old_bin, old_len, old_bin ? &entry->old_value : NULL,
                                         new_bin, new_len, &entry->row_value));
    }
    return err;
}
/* Populates a wire protocol message for an insert event. */
int update_frame_with_insert_raw(avro_value_t *frame_val, Oid relid, bytea *key_bin, bytea *new_bin) {
    int err = 0;
    avro_value_t msg_val, union_val, record_val, relid_val, key_val, newrow_val, branch_val;

    check(err, avro_value_get_by_index(frame_val, 0, &msg_val, NULL));
    check(err, avro_value_append(&msg_val, &union_val, NULL));
    check(err, avro_value_set_branch(&union_val, PROTOCOL_MSG_INSERT, &record_val));
    check(err, avro_value_get_by_index(&record_val, 0, &relid_val,  NULL));
    check(err, avro_value_get_by_index(&record_val, 1, &key_val,    NULL));
    check(err, avro_value_get_by_index(&record_val, 2, &newrow_val, NULL));
    check(err, avro_value_set_long(&relid_val, relid));
    check(err, avro_value_set_bytes(&newrow_val, VARDATA(new_bin), VARSIZE(new_bin) - VARHDRSZ));

    if (key_bin) {
        check(err, avro_value_set_branch(&key_val, 1, &branch_val));
        check(err, avro_value_set_bytes(&branch_val, VARDATA(key_bin), VARSIZE(key_bin) - VARHDRSZ));
    } else {
        check(err, avro_value_set_branch(&key_val, 0, NULL));
    }
    return err;
}
int process_frame_commit_txn(avro_value_t *record_val, frame_reader_t reader, uint64_t wal_pos) {
    int err = 0;
    avro_value_t xid_val;
    int64_t xid;

    check(err, avro_value_get_by_index(record_val, 0, &xid_val, NULL));
    check(err, avro_value_get_long(&xid_val, &xid));

    if (reader->on_commit_txn) {
        check(err, reader->on_commit_txn(reader->cb_context, wal_pos, (uint32_t) xid));
    }
    return err;
}
int process_frame(avro_value_t *frame_val, frame_reader_t reader, uint64_t wal_pos) {
    int err = 0, msg_type;
    size_t num_messages;
    avro_value_t msg_val, union_val, record_val;

    check(err, avro_value_get_by_index(frame_val, 0, &msg_val, NULL));
    check(err, avro_value_get_size(&msg_val, &num_messages));

    for (int i = 0; i < num_messages; i++) {
        check(err, avro_value_get_by_index(&msg_val, i, &union_val, NULL));
        check(err, avro_value_get_discriminant(&union_val, &msg_type));
        check(err, avro_value_get_current_branch(&union_val, &record_val));

        switch (msg_type) {
        case PROTOCOL_MSG_BEGIN_TXN:
            check(err, process_frame_begin_txn(&record_val, reader, wal_pos));
            break;
        case PROTOCOL_MSG_COMMIT_TXN:
            check(err, process_frame_commit_txn(&record_val, reader, wal_pos));
            break;
        case PROTOCOL_MSG_TABLE_SCHEMA:
            check(err, process_frame_table_schema(&record_val, reader, wal_pos));
            break;
        case PROTOCOL_MSG_INSERT:
            check(err, process_frame_insert(&record_val, reader, wal_pos));
            break;
        case PROTOCOL_MSG_UPDATE:
            check(err, process_frame_update(&record_val, reader, wal_pos));
            break;
        case PROTOCOL_MSG_DELETE:
            check(err, process_frame_delete(&record_val, reader, wal_pos));
            break;
        default:
            avro_set_error("Unknown message type %d", msg_type);
            return EINVAL;
        }
    }
    return err;
}
Exemple #9
0
static int read_data() {
	int rval;
	int records_read = 0;

	avro_file_reader_t reader;
	avro_value_iface_t *iface;
	avro_value_t value;

	fprintf(stderr, "\nReading...\n");

	rval = avro_file_reader(filename, &reader);

	if (rval) {
		fprintf(stderr, "Error: %s\n", avro_strerror());
		return -1;
	}

	avro_schema_t schema = avro_file_reader_get_writer_schema(reader);

	iface = avro_generic_class_from_schema(schema);
	avro_generic_value_new(iface, &value);

	while ((rval = avro_file_reader_read_value(reader, &value)) == 0) {
		avro_value_t field;
		int32_t val;
		avro_value_get_by_index(&value, 0, &field, NULL);
		avro_value_get_int(&field, &val);
		fprintf(stderr, "value = %d\n", val);
		records_read++;
		avro_value_reset(&value);
	}

	avro_value_decref(&value);
	avro_value_iface_decref(iface);
	avro_schema_decref(schema);
	avro_file_reader_close(reader);

	fprintf(stderr, "read %d records.\n", records_read);

	if (rval != EOF) {
		fprintf(stderr, "Error: %s\n", avro_strerror());
		return -1;
	}

	return records_read;
}
Exemple #10
0
static int write_data(int n_records) {
	int  i;
	avro_schema_t schema;
	avro_schema_error_t error;
	avro_file_writer_t writer;
	avro_value_iface_t *iface;
	avro_value_t value;

	fprintf(stderr, "\nWriting...\n");

	if (avro_schema_from_json(PERSON_SCHEMA, 0, &schema, &error)) {
		fprintf(stderr, "Unable to parse schema\n");
		return -1;
	}

	if (avro_file_writer_create(filename, schema, &writer)) {
		fprintf(stderr, "There was an error creating file: %s\n", avro_strerror());
		return -1;
	}

	iface = avro_generic_class_from_schema(schema);
	avro_generic_value_new(iface, &value);

	avro_value_t field;

	avro_value_get_by_index(&value, 0, &field, NULL);
	avro_value_set_int(&field, 123);

	for (i = 0; i < n_records; i++) {
		if (avro_file_writer_append_value(writer, &value)) {
			fprintf(stderr, "There was an error writing file: %s\n", avro_strerror());
			return -1;
		}
	}

	if (avro_file_writer_close(writer)) {
		fprintf(stderr, "There was an error creating file: %s\n", avro_strerror());
		return -1;
	}

	avro_value_decref(&value);
	avro_value_iface_decref(iface);
	avro_schema_decref(schema);

	return n_records;
}
Exemple #11
0
int schema_traverse(const avro_schema_t schema, json_t *json, json_t *dft,
                    avro_value_t *current_val, int quiet, int strjson, size_t max_str_sz) {

    json = json ? json : dft;
    if (!json) {
        fprintf(stderr, "ERROR: Avro schema does not match JSON\n");
        return 1;
    }

    switch (schema->type) {
    case AVRO_RECORD:
    {
        if (!json_is_object(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON object for Avro record, got something else\n");
            return 1;
        }

        int len = avro_schema_record_size(schema), i;
        for (i=0; i<len; i++) {

            const char *name = avro_schema_record_field_name(schema, i);
            avro_schema_t field_schema = avro_schema_record_field_get_by_index(schema, i);

            json_t *json_val = json_object_get(json, name);
            json_t *dft = avro_schema_record_field_default_get_by_index(schema, i);

            avro_value_t field;
            avro_value_get_by_index(current_val, i, &field, NULL);

            if (schema_traverse(field_schema, json_val, dft, &field, quiet, strjson, max_str_sz))
                return 1;
        }
    } break;

    case AVRO_LINK:
        /* TODO */
        fprintf(stderr, "ERROR: AVRO_LINK is not implemented\n");
        return 1;
        break;

    case AVRO_STRING:
        if (!json_is_string(json)) {
            if (json && strjson) {
                /* -j specified, just dump the remaining json as string */
                char * js = json_dumps(json, JSON_COMPACT|JSON_SORT_KEYS|JSON_ENCODE_ANY);
                if (max_str_sz && (strlen(js) > max_str_sz))
                    js[max_str_sz] = 0; /* truncate the string - this will result in invalid JSON! */
                avro_value_set_string(current_val, js);
                free(js);
                break;
            }
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON string for Avro string, got something else\n");
            return 1;
        } else {
            const char *js = json_string_value(json);
            if (max_str_sz && (strlen(js) > max_str_sz)) {
                /* truncate the string */
                char *jst = malloc(strlen(js));
                strcpy(jst, js);
                jst[max_str_sz] = 0;
                avro_value_set_string(current_val, jst);
                free(jst);
            } else
                avro_value_set_string(current_val, js);
        }
        break;

    case AVRO_BYTES:
        if (!json_is_string(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON string for Avro string, got something else\n");
            return 1;
        }
        /* NB: Jansson uses null-terminated strings, so embedded nulls are NOT
           supported, not even escaped ones */
        const char *s = json_string_value(json);
        avro_value_set_bytes(current_val, (void *)s, strlen(s));
        break;

    case AVRO_INT32:
        if (!json_is_integer(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON integer for Avro int, got something else\n");
            return 1;
        }
        avro_value_set_int(current_val, json_integer_value(json));
        break;

    case AVRO_INT64:
        if (!json_is_integer(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON integer for Avro long, got something else\n");
            return 1;
        }
        avro_value_set_long(current_val, json_integer_value(json));
        break;

    case AVRO_FLOAT:
        if (!json_is_number(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON number for Avro float, got something else\n");
            return 1;
        }
        avro_value_set_float(current_val, json_number_value(json));
        break;

    case AVRO_DOUBLE:
        if (!json_is_number(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON number for Avro double, got something else\n");
            return 1;
        }
        avro_value_set_double(current_val, json_number_value(json));
        break;

    case AVRO_BOOLEAN:
        if (!json_is_boolean(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON boolean for Avro boolean, got something else\n");
            return 1;
        }
        avro_value_set_boolean(current_val, json_is_true(json));
        break;

    case AVRO_NULL:
        if (!json_is_null(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON null for Avro null, got something else\n");
            return 1;
        }
        avro_value_set_null(current_val);
        break;

    case AVRO_ENUM:
        // TODO ???
        break;

    case AVRO_ARRAY:
        if (!json_is_array(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON array for Avro array, got something else\n");
            return 1;
        } else {
            int i, len = json_array_size(json);
            avro_schema_t items = avro_schema_array_items(schema);
            avro_value_t val;
            for (i=0; i<len; i++) {
                avro_value_append(current_val, &val, NULL);
                if (schema_traverse(items, json_array_get(json, i), NULL, &val, quiet, strjson, max_str_sz))
                    return 1;
            }
        }
        break;

    case AVRO_MAP:
        if (!json_is_object(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON object for Avro map, got something else\n");
            return 1;
        } else {
            avro_schema_t values = avro_schema_map_values(schema);
            void *iter = json_object_iter(json);
            avro_value_t val;
            while (iter) {
                avro_value_add(current_val, json_object_iter_key(iter), &val, 0, 0);
                if (schema_traverse(values, json_object_iter_value(iter), NULL, &val, quiet, strjson, max_str_sz))
                    return 1;
                iter = json_object_iter_next(json, iter);
            }
        }
        break;

    case AVRO_UNION:
    {
        int i;
        avro_value_t branch;
        for (i=0; i<avro_schema_union_size(schema); i++) {
            avro_value_set_branch(current_val, i, &branch);
            avro_schema_t type = avro_schema_union_branch(schema, i);
            if (!schema_traverse(type, json, NULL, &branch, 1, strjson, max_str_sz))
                break;
        }
        if (i==avro_schema_union_size(schema)) {
            fprintf(stderr, "ERROR: No type in the Avro union matched the JSON type we got\n");
            return 1;
        }
        break;
    }
    case AVRO_FIXED:
        if (!json_is_string(json)) {
            if (!quiet)
                fprintf(stderr, "ERROR: Expecting JSON string for Avro fixed, got something else\n");
            return 1;
        }
        /* NB: Jansson uses null-terminated strings, so embedded nulls are NOT
           supported, not even escaped ones */
        const char *f = json_string_value(json);
        if (avro_value_set_fixed(current_val, (void *)f, strlen(f))) {
            fprintf(stderr, "ERROR: Setting Avro fixed value FAILED\n");
            return 1;
        }
        break;

    default:
        fprintf(stderr, "ERROR: Unknown type: %d\n", schema->type);
        return 1;
    }
    return 0;
}
Exemple #12
0
int
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 0;
	}

	switch (type1) {
		case AVRO_BOOLEAN:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_boolean(val1, &v1));
			check_return(0, 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(0, avro_value_get_bytes(val1, &buf1, &size1));
			check_return(0, avro_value_get_bytes(val2, &buf2, &size2));
			if (size1 != size2) {
				return 0;
			}
			return (memcmp(buf1, buf2, size1) == 0);
		}

		case AVRO_DOUBLE:
		{
			double  v1;
			double  v2;
			check_return(0, avro_value_get_double(val1, &v1));
			check_return(0, avro_value_get_double(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_FLOAT:
		{
			float  v1;
			float  v2;
			check_return(0, avro_value_get_float(val1, &v1));
			check_return(0, avro_value_get_float(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_INT32:
		{
			int32_t  v1;
			int32_t  v2;
			check_return(0, avro_value_get_int(val1, &v1));
			check_return(0, avro_value_get_int(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_INT64:
		{
			int64_t  v1;
			int64_t  v2;
			check_return(0, avro_value_get_long(val1, &v1));
			check_return(0, avro_value_get_long(val2, &v2));
			return (v1 == v2);
		}

		case AVRO_NULL:
		{
			check_return(0, avro_value_get_null(val1));
			check_return(0, avro_value_get_null(val2));
			return 1;
		}

		case AVRO_STRING:
		{
			const char  *buf1;
			const char  *buf2;
			size_t  size1;
			size_t  size2;
			check_return(0, avro_value_get_string(val1, &buf1, &size1));
			check_return(0, avro_value_get_string(val2, &buf2, &size2));
			if (size1 != size2) {
				return 0;
			}
			return (memcmp(buf1, buf2, size1) == 0);
		}

		case AVRO_ARRAY:
		{
			size_t  count1;
			size_t  count2;
			check_return(0, avro_value_get_size(val1, &count1));
			check_return(0, avro_value_get_size(val2, &count2));
			if (count1 != count2) {
				return 0;
			}

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				if (!avro_value_equal_fast(&child1, &child2)) {
					return 0;
				}
			}

			return 1;
		}

		case AVRO_ENUM:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_enum(val1, &v1));
			check_return(0, 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(0, avro_value_get_fixed(val1, &buf1, &size1));
			check_return(0, avro_value_get_fixed(val2, &buf2, &size2));
			if (size1 != size2) {
				return 0;
			}
			return (memcmp(buf1, buf2, size1) == 0);
		}

		case AVRO_MAP:
		{
			size_t  count1;
			size_t  count2;
			check_return(0, avro_value_get_size(val1, &count1));
			check_return(0, avro_value_get_size(val2, &count2));
			if (count1 != count2) {
				return 0;
			}

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				const char  *key1;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, &key1));
				check_return(0, avro_value_get_by_name
					     (val2, key1, &child2, NULL));
				if (!avro_value_equal_fast(&child1, &child2)) {
					return 0;
				}
			}

			return 1;
		}

		case AVRO_RECORD:
		{
			size_t  count1;
			check_return(0, 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(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				if (!avro_value_equal_fast(&child1, &child2)) {
					return 0;
				}
			}

			return 1;
		}

		case AVRO_UNION:
		{
			int  disc1;
			int  disc2;
			check_return(0, avro_value_get_discriminant(val1, &disc1));
			check_return(0, avro_value_get_discriminant(val2, &disc2));
			if (disc1 != disc2) {
				return 0;
			}

			avro_value_t  branch1;
			avro_value_t  branch2;
			check_return(0, avro_value_get_current_branch(val1, &branch1));
			check_return(0, avro_value_get_current_branch(val2, &branch2));
			return avro_value_equal_fast(&branch1, &branch2);
		}

		default:
			return 0;
	}
}
Exemple #13
0
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 0;
	}

	int  rval;
	check(rval, avro_value_reset(dest));

	switch (dest_type) {
		case AVRO_BOOLEAN:
		{
			int  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;
	}
}
Exemple #14
0
int
avro_value_cmp_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 -1;
	}

	switch (type1) {
		case AVRO_BOOLEAN:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_boolean(val1, &v1));
			check_return(0, avro_value_get_boolean(val2, &v2));
			return cmp(!!v1, !!v2);
		}

		case AVRO_BYTES:
		{
			const void  *buf1;
			const void  *buf2;
			size_t  size1;
			size_t  size2;
			size_t  min_size;
			int  result;

			check_return(0, avro_value_get_bytes(val1, &buf1, &size1));
			check_return(0, avro_value_get_bytes(val2, &buf2, &size2));

			min_size = (size1 < size2)? size1: size2;
			result = memcmp(buf1, buf2, min_size);
			if (result != 0) {
				return result;
			} else {
				return cmp(size1, size2);
			}
		}

		case AVRO_DOUBLE:
		{
			double  v1;
			double  v2;
			check_return(0, avro_value_get_double(val1, &v1));
			check_return(0, avro_value_get_double(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_FLOAT:
		{
			float  v1;
			float  v2;
			check_return(0, avro_value_get_float(val1, &v1));
			check_return(0, avro_value_get_float(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_INT32:
		{
			int32_t  v1;
			int32_t  v2;
			check_return(0, avro_value_get_int(val1, &v1));
			check_return(0, avro_value_get_int(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_INT64:
		{
			int64_t  v1;
			int64_t  v2;
			check_return(0, avro_value_get_long(val1, &v1));
			check_return(0, avro_value_get_long(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_NULL:
		{
			check_return(0, avro_value_get_null(val1));
			check_return(0, avro_value_get_null(val2));
			return 0;
		}

		case AVRO_STRING:
		{
			const char  *buf1;
			const char  *buf2;
			size_t  size1;
			size_t  size2;
			size_t  min_size;
			int  result;
			check_return(0, avro_value_get_string(val1, &buf1, &size1));
			check_return(0, avro_value_get_string(val2, &buf2, &size2));

			min_size = (size1 < size2)? size1: size2;
			result = memcmp(buf1, buf2, min_size);
			if (result != 0) {
				return result;
			} else {
				return cmp(size1, size2);
			}
		}

		case AVRO_ARRAY:
		{
			size_t  count1;
			size_t  count2;
			size_t  min_count;
			size_t  i;
			check_return(0, avro_value_get_size(val1, &count1));
			check_return(0, avro_value_get_size(val2, &count2));

			min_count = (count1 < count2)? count1: count2;
			for (i = 0; i < min_count; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				int  result;
				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				result = avro_value_cmp_fast(&child1, &child2);
				if (result != 0) {
					return result;
				}
			}

			return cmp(count1, count2);
		}

		case AVRO_ENUM:
		{
			int  v1;
			int  v2;
			check_return(0, avro_value_get_enum(val1, &v1));
			check_return(0, avro_value_get_enum(val2, &v2));
			return cmp(v1, v2);
		}

		case AVRO_FIXED:
		{
			const void  *buf1;
			const void  *buf2;
			size_t  size1;
			size_t  size2;
			check_return(0, avro_value_get_fixed(val1, &buf1, &size1));
			check_return(0, avro_value_get_fixed(val2, &buf2, &size2));
			if (size1 != size2) {
				return -1;
			}
			return memcmp(buf1, buf2, size1);
		}

		case AVRO_MAP:
		{
			return -1;
		}

		case AVRO_RECORD:
		{
			size_t  count1;
			check_return(0, avro_value_get_size(val1, &count1));

			size_t  i;
			for (i = 0; i < count1; i++) {
				avro_value_t  child1;
				avro_value_t  child2;
				int  result;

				check_return(0, avro_value_get_by_index
					     (val1, i, &child1, NULL));
				check_return(0, avro_value_get_by_index
					     (val2, i, &child2, NULL));
				result = avro_value_cmp_fast(&child1, &child2);
				if (result != 0) {
					return result;
				}
			}

			return 0;
		}

		case AVRO_UNION:
		{
			int  disc1;
			int  disc2;
			check_return(0, avro_value_get_discriminant(val1, &disc1));
			check_return(0, avro_value_get_discriminant(val2, &disc2));

			if (disc1 == disc2) {
				avro_value_t  branch1;
				avro_value_t  branch2;
				check_return(0, avro_value_get_current_branch(val1, &branch1));
				check_return(0, avro_value_get_current_branch(val2, &branch2));
				return avro_value_cmp_fast(&branch1, &branch2);
			} else {
				return cmp(disc1, disc2);
			}
		}

		default:
			return 0;
	}
}