blob: 068dbda9918ef40705b2b8efec51be3c824fd5ec [file] [log] [blame]
/*
* 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 "avro_private.h"
#include <string.h>
#include "datum.h"
static int
array_equal(struct avro_array_datum_t *a, struct avro_array_datum_t *b)
{
if (!avro_schema_equal(a->schema, b->schema)) {
return 0;
}
long i;
if (a->els->num_entries != b->els->num_entries) {
return 0;
}
for (i = 0; i < a->els->num_entries; i++) {
union {
st_data_t data;
avro_datum_t datum;
} ael, bel;
st_lookup(a->els, i, &ael.data);
st_lookup(b->els, i, &bel.data);
if (!avro_datum_equal(ael.datum, bel.datum)) {
return 0;
}
}
return 1;
}
struct st_equal_args {
int rval;
st_table *st;
};
static int
st_equal_foreach(char *key, avro_datum_t datum, struct st_equal_args *args)
{
union {
avro_datum_t datum_other;
st_data_t data;
} val;
if (!st_lookup(args->st, (st_data_t) key, &(val.data))) {
args->rval = 0;
return ST_STOP;
}
if (!avro_datum_equal(datum, val.datum_other)) {
args->rval = 0;
return ST_STOP;
}
return ST_CONTINUE;
}
static int map_equal(struct avro_map_datum_t *a, struct avro_map_datum_t *b)
{
if (!avro_schema_equal(a->schema, b->schema)) {
return 0;
}
struct st_equal_args args = { 1, b->map };
if (a->map->num_entries != b->map->num_entries) {
return 0;
}
st_foreach(a->map, HASH_FUNCTION_CAST st_equal_foreach, (st_data_t) & args);
return args.rval;
}
static int record_equal(struct avro_record_datum_t *a,
struct avro_record_datum_t *b)
{
if (!avro_schema_equal(a->schema, b->schema)) {
return 0;
}
struct st_equal_args args = { 1, b->fields_byname };
if (a->fields_byname->num_entries != b->fields_byname->num_entries) {
return 0;
}
st_foreach(a->fields_byname, HASH_FUNCTION_CAST st_equal_foreach, (st_data_t) & args);
return args.rval;
}
static int enum_equal(struct avro_enum_datum_t *a, struct avro_enum_datum_t *b)
{
return avro_schema_equal(a->schema, b->schema) && a->value == b->value;
}
static int fixed_equal(struct avro_fixed_datum_t *a,
struct avro_fixed_datum_t *b)
{
if (!avro_schema_equal(a->schema, b->schema)) {
return 0;
}
return a->size == b->size && memcmp(a->bytes, b->bytes, a->size) == 0;
}
static int union_equal(struct avro_union_datum_t *a,
struct avro_union_datum_t *b)
{
if (!avro_schema_equal(a->schema, b->schema)) {
return 0;
}
return a->discriminant == b->discriminant && avro_datum_equal(a->value, b->value);
}
int avro_datum_equal(const avro_datum_t a, const avro_datum_t b)
{
if (!(is_avro_datum(a) && is_avro_datum(b))) {
return 0;
}
if (avro_typeof(a) != avro_typeof(b)) {
return 0;
}
switch (avro_typeof(a)) {
case AVRO_STRING:
return strcmp(avro_datum_to_string(a)->s,
avro_datum_to_string(b)->s) == 0;
case AVRO_BYTES:
return (avro_datum_to_bytes(a)->size ==
avro_datum_to_bytes(b)->size)
&& memcmp(avro_datum_to_bytes(a)->bytes,
avro_datum_to_bytes(b)->bytes,
avro_datum_to_bytes(a)->size) == 0;
case AVRO_INT32:
return avro_datum_to_int32(a)->i32 ==
avro_datum_to_int32(b)->i32;
case AVRO_INT64:
return avro_datum_to_int64(a)->i64 ==
avro_datum_to_int64(b)->i64;
case AVRO_FLOAT:
return avro_datum_to_float(a)->f == avro_datum_to_float(b)->f;
case AVRO_DOUBLE:
return avro_datum_to_double(a)->d == avro_datum_to_double(b)->d;
case AVRO_BOOLEAN:
return avro_datum_to_boolean(a)->i ==
avro_datum_to_boolean(b)->i;
case AVRO_NULL:
return 1;
case AVRO_ARRAY:
return array_equal(avro_datum_to_array(a),
avro_datum_to_array(b));
case AVRO_MAP:
return map_equal(avro_datum_to_map(a), avro_datum_to_map(b));
case AVRO_RECORD:
return record_equal(avro_datum_to_record(a),
avro_datum_to_record(b));
case AVRO_ENUM:
return enum_equal(avro_datum_to_enum(a), avro_datum_to_enum(b));
case AVRO_FIXED:
return fixed_equal(avro_datum_to_fixed(a),
avro_datum_to_fixed(b));
case AVRO_UNION:
return union_equal(avro_datum_to_union(a),
avro_datum_to_union(b));
case AVRO_LINK:
/*
* TODO
*/
return 0;
}
return 0;
}