summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5e20183)
raw | patch | inline | side by side (parent: 5e20183)
author | Sebastian Harl <sh@tokkee.org> | |
Wed, 12 Nov 2014 19:55:10 +0000 (20:55 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Wed, 12 Nov 2014 19:55:10 +0000 (20:55 +0100) |
This check returns true if all elements of the first array are included in the
second array where order does not matter.
second array where order does not matter.
src/core/data.c | patch | blob | history | |
src/include/core/data.h | patch | blob | history | |
t/unit/core/data_test.c | patch | blob | history |
diff --git a/src/core/data.c b/src/core/data.c
index 27c7aa1452de6aaaeb09f47c5ccd4ea1ee018415..88c7f8246953d58f1af76a01a04e1919eb96f8c2 100644 (file)
--- a/src/core/data.c
+++ b/src/core/data.c
_Bool
sdb_data_inarray(const sdb_data_t *value, const sdb_data_t *array)
{
- size_t i;
+ const void *values;
+ size_t length, i;
+ int type = value->type & 0xff;
if (sdb_data_isnull(value) || sdb_data_isnull(array))
return 0;
- if ((value->type & SDB_TYPE_ARRAY) || (! (array->type & SDB_TYPE_ARRAY)))
+ if (! (array->type & SDB_TYPE_ARRAY))
return 0;
- if (value->type != (array->type & 0xff))
+ if ((value->type & 0xff) != (array->type & 0xff))
return 0;
- if (value->type == SDB_TYPE_INTEGER) {
- int64_t *v = array->data.array.values;
- for (i = 0; i < array->data.array.length; ++i)
- if (value->data.integer == v[i])
- return 1;
- }
- else if (value->type == SDB_TYPE_DECIMAL) {
- double *v = array->data.array.values;
- for (i = 0; i < array->data.array.length; ++i)
- if (value->data.decimal == v[i])
- return 1;
- }
- else if (value->type == SDB_TYPE_STRING) {
- char **v = array->data.array.values;
- for (i = 0; i < array->data.array.length; ++i)
- if (!strcasecmp(value->data.string, v[i]))
- return 1;
+ if (value->type & SDB_TYPE_ARRAY) {
+ values = value->data.array.values;
+ length = value->data.array.length;
}
else {
- /* TODO */
- errno = ENOTSUP;
- return 0;
+ values = &value->data;
+ length = 1;
}
- return 0;
+
+ for (i = 0; i < length; ++i) {
+ size_t j;
+
+ if (type == SDB_TYPE_INTEGER) {
+ int64_t *v = array->data.array.values;
+ for (j = 0; j < array->data.array.length; ++j)
+ if (((const int64_t *)values)[i] == v[j])
+ break;
+ }
+ else if (type == SDB_TYPE_DECIMAL) {
+ double *v = array->data.array.values;
+ for (j = 0; j < array->data.array.length; ++j)
+ if (((const double *)values)[i] == v[j])
+ break;
+ }
+ else if (type == SDB_TYPE_STRING) {
+ char **v = array->data.array.values;
+ for (j = 0; j < array->data.array.length; ++j)
+ if (!strcasecmp(((const char * const*)values)[i], v[j]))
+ break;
+ }
+ else {
+ /* TODO */
+ errno = ENOTSUP;
+ return 0;
+ }
+
+ if (j >= array->data.array.length)
+ /* value not found */
+ return 0;
+ }
+ return 1;
} /* sdb_data_inarray */
int
index c03c0c1b6210b730dc0790693f642d45b4012886..997cf9f0a320c616af5074c86f749a03b1dca8b1 100644 (file)
--- a/src/include/core/data.h
+++ b/src/include/core/data.h
* sdb_data_inarray:
* Determine whether a datum is included in an array based on the usual
* comparison function of the value's type. The element type of the array has
- * to match the type of the value.
+ * to match the type of the value. The value may be another array. In that
+ * case, the element types have to match and the function returns true if all
+ * elements of the first array are included in the second where order does not
+ * matter.
*/
_Bool
sdb_data_inarray(const sdb_data_t *value, const sdb_data_t *array);
index 2baa6a15876d05ff53b1b98283379cf7d1f50f1a..956cf3108c0a5d598afcb5eb75e72f938f61c3d8 100644 (file)
--- a/t/unit/core/data_test.c
+++ b/t/unit/core/data_test.c
START_TEST(test_inarray)
{
int64_t int_values[] = { 47, 11, 64 };
+ int64_t int_values2[] = { 64, 11 };
+ int64_t int_values3[] = { 47, 11, 42 };
double dec_values[] = { 12.3, 47.11, 64.0 };
+ double dec_values2[] = { 12.3, 47.11 };
+ double dec_values3[] = { 2.3, 47.11 };
char *string_values[] = { "foo", "bar", "qux", "baz" };
+ char *string_values2[] = { "qux", "bar" };
+ char *string_values3[] = { "foo", "bar", "qux", "baz", "bay" };
sdb_data_t int_array = {
SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
{ .array = { SDB_STATIC_ARRAY_LEN(int_values), int_values } }
};
+ sdb_data_t int_array2 = {
+ SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
+ { .array = { SDB_STATIC_ARRAY_LEN(int_values2), int_values2 } }
+ };
+ sdb_data_t int_array3 = {
+ SDB_TYPE_ARRAY | SDB_TYPE_INTEGER,
+ { .array = { SDB_STATIC_ARRAY_LEN(int_values3), int_values3 } }
+ };
sdb_data_t dec_array = {
SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
{ .array = { SDB_STATIC_ARRAY_LEN(dec_values), dec_values } }
};
+ sdb_data_t dec_array2 = {
+ SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
+ { .array = { SDB_STATIC_ARRAY_LEN(dec_values2), dec_values2 } }
+ };
+ sdb_data_t dec_array3 = {
+ SDB_TYPE_ARRAY | SDB_TYPE_DECIMAL,
+ { .array = { SDB_STATIC_ARRAY_LEN(dec_values3), dec_values3 } }
+ };
sdb_data_t string_array = {
SDB_TYPE_ARRAY | SDB_TYPE_STRING,
{ .array = { SDB_STATIC_ARRAY_LEN(string_values), string_values } }
};
+ sdb_data_t string_array2 = {
+ SDB_TYPE_ARRAY | SDB_TYPE_STRING,
+ { .array = { SDB_STATIC_ARRAY_LEN(string_values2), string_values2 } }
+ };
+ sdb_data_t string_array3 = {
+ SDB_TYPE_ARRAY | SDB_TYPE_STRING,
+ { .array = { SDB_STATIC_ARRAY_LEN(string_values3), string_values3 } }
+ };
struct {
sdb_data_t value;
{ { SDB_TYPE_INTEGER, { .integer = 64 } }, int_array, 1 },
{ { SDB_TYPE_INTEGER, { .integer = 65 } }, int_array, 0 },
{ { SDB_TYPE_NULL, { .integer = 0 } }, int_array, 0 },
- { int_array, { SDB_TYPE_INTEGER, { .integer = 47 } }, 0 },
- { int_array, int_array, 0 },
{ { SDB_TYPE_DECIMAL, { .decimal = 12.3 } }, dec_array, 1 },
{ { SDB_TYPE_DECIMAL, { .decimal = 47.11 } }, dec_array, 1 },
{ { SDB_TYPE_DECIMAL, { .decimal = 64.0 } }, dec_array, 1 },
{ { SDB_TYPE_STRING, { .string = "ba" } }, string_array, 0 },
{ { SDB_TYPE_STRING, { .string = "abc" } }, string_array, 0 },
{ { SDB_TYPE_NULL, { .integer = 0 } }, string_array, 0 },
+ { int_array, { SDB_TYPE_INTEGER, { .integer = 47 } }, 0 },
+ { int_array, int_array, 1 },
+ { int_array2, int_array, 1 },
+ { int_array3, int_array, 0 },
+ { dec_array2, int_array, 0 },
+ { string_array2, int_array, 0 },
+ { dec_array, dec_array, 1 },
+ { dec_array2, dec_array, 1 },
+ { dec_array3, dec_array, 0 },
+ { int_array2, dec_array, 0 },
+ { string_array2, dec_array, 0 },
+ { string_array, string_array, 1 },
+ { string_array2, string_array, 1 },
+ { string_array3, string_array, 0 },
+ { int_array2, string_array, 0 },
+ { dec_array2, string_array, 0 },
};
size_t i;