Code

data: Added helper functions to copy and free data.
authorSebastian Harl <sh@tokkee.org>
Wed, 29 Jan 2014 20:41:18 +0000 (21:41 +0100)
committerSebastian Harl <sh@tokkee.org>
Wed, 29 Jan 2014 20:41:18 +0000 (21:41 +0100)
src/Makefile.am
src/core/data.c [new file with mode: 0644]
src/include/core/data.h
t/Makefile.am
t/core/data_test.c [new file with mode: 0644]
t/libsysdb_test.c
t/libsysdb_test.h

index cdadd60a80932f37df8a0dddf987ecbcb045249e..873694874bc06645af68624bb93bbdb23204d875 100644 (file)
@@ -66,7 +66,7 @@ libsysdb_la_SOURCES = \
                core/object.c include/core/object.h \
                core/plugin.c include/core/plugin.h \
                core/store.c include/core/store.h \
-               include/core/data.h \
+               core/data.c include/core/data.h \
                frontend/connection.c include/frontend/connection.h \
                frontend/connection-private.h \
                frontend/parser.c include/frontend/parser.h \
diff --git a/src/core/data.c b/src/core/data.c
new file mode 100644 (file)
index 0000000..c71e363
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * SysDB - src/core/data.c
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "core/data.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * public API
+ */
+
+int
+sdb_data_copy(sdb_data_t *dst, const sdb_data_t *src)
+{
+       sdb_data_t tmp;
+
+       if ((! dst) || (! src))
+               return -1;
+
+       tmp = *src;
+       switch (src->type) {
+               case SDB_TYPE_STRING:
+                       tmp.data.string = strdup(src->data.string);
+                       if (! tmp.data.string)
+                               return -1;
+                       break;
+               case SDB_TYPE_BINARY:
+                       tmp.data.binary.datum = malloc(src->data.binary.length);
+                       if (! tmp.data.binary.datum)
+                               return -1;
+                       memcpy(tmp.data.binary.datum, src->data.binary.datum,
+                                       src->data.binary.length);
+                       break;
+       }
+
+       *dst = tmp;
+       return 0;
+} /* sdb_data_copy */
+
+void
+sdb_data_free_datum(sdb_data_t *datum)
+{
+       if (! datum)
+               return;
+
+       switch (datum->type) {
+               case SDB_TYPE_STRING:
+                       if (datum->data.string)
+                               free(datum->data.string);
+                       datum->data.string = NULL;
+                       break;
+               case SDB_TYPE_BINARY:
+                       if (datum->data.binary.datum)
+                               free(datum->data.binary.datum);
+                       datum->data.binary.datum = NULL;
+                       datum->data.binary.length = 0;
+                       break;
+       }
+} /* sdb_data_free_datum */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
index b657486b794b16cdb9bc00560cb0b2f4ab2090dc..a5438a2c8e76d4821b29e1b6ae40aa638aea0bb8 100644 (file)
@@ -67,6 +67,30 @@ typedef struct {
        } data;
 } sdb_data_t;
 
+/*
+ * sdb_data_copy:
+ * Copy the datum stored in 'src' to the memory location pointed to by 'dst'.
+ * Any dynamic data (strings, binary data) is copied to newly allocated
+ * memory. Use, for example, sdb_data_free_datum() to free any dynamic memory
+ * stored in a datum.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - a negative value else
+ */
+int
+sdb_data_copy(sdb_data_t *dst, const sdb_data_t *src);
+
+/*
+ * sdb_data_free_datum:
+ * Free any dynamic memory referenced by the specified datum. Does not free
+ * the memory allocated for the sdb_data_t object itself. This function must
+ * not be used if any static or stack memory is referenced from the data
+ * object.
+ */
+void
+sdb_data_free_datum(sdb_data_t *datum);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 6adf484bf9ab8acca0761c7a93c8a7ea5f35a095..3c13ad556b78c35b04b3907f223106dd0925e69e 100644 (file)
@@ -10,6 +10,7 @@ check_PROGRAMS = libsysdb_test libsysdb_net_test
 
 libsysdb_test_SOURCES = \
                libsysdb_test.c libsysdb_test.h \
+               core/data_test.c \
                core/object_test.c \
                core/store_test.c \
                frontend/parser_test.c \
diff --git a/t/core/data_test.c b/t/core/data_test.c
new file mode 100644 (file)
index 0000000..7efa554
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * SysDB - t/core/data_test.c
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "core/data.h"
+#include "libsysdb_test.h"
+
+#include <check.h>
+
+START_TEST(test_data)
+{
+       sdb_data_t d1, d2;
+       int check;
+
+       d2.type = SDB_TYPE_INTEGER;
+       d2.data.integer = 4711;
+       check = sdb_data_copy(&d1, &d2);
+       fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
+       fail_unless(d1.type == d2.type,
+                       "sdb_data_copy() didn't copy type; got: %i; expected: %i",
+                       d1.type, d2.type);
+       fail_unless(d1.data.integer == d2.data.integer,
+                       "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
+                       d1.data.integer, d2.data.integer);
+
+       d2.type = SDB_TYPE_DECIMAL;
+       d2.data.decimal = 47.11;
+       check = sdb_data_copy(&d1, &d2);
+       fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
+       fail_unless(d1.type == d2.type,
+                       "sdb_data_copy() didn't copy type; got: %i; expected: %i",
+                       d1.type, d2.type);
+       fail_unless(d1.data.decimal == d2.data.decimal,
+                       "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
+                       d1.data.decimal, d2.data.decimal);
+
+       d2.type = SDB_TYPE_STRING;
+       d2.data.string = "some string";
+       check = sdb_data_copy(&d1, &d2);
+       fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
+       fail_unless(d1.type == d2.type,
+                       "sdb_data_copy() didn't copy type; got: %i; expected: %i",
+                       d1.type, d2.type);
+       fail_unless(!strcmp(d1.data.string, d2.data.string),
+                       "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
+                       d1.data.string, d2.data.string);
+
+       sdb_data_free_datum(&d1);
+       fail_unless(d1.data.string == NULL,
+                       "sdb_data_free_datum() didn't free string data");
+
+       d2.type = SDB_TYPE_DATETIME;
+       d2.data.datetime = 4711;
+       check = sdb_data_copy(&d1, &d2);
+       fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
+       fail_unless(d1.type == d2.type,
+                       "sdb_data_copy() didn't copy type; got: %i; expected: %i",
+                       d1.type, d2.type);
+       fail_unless(d1.data.datetime == d2.data.datetime,
+                       "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
+                       d1.data.datetime, d2.data.datetime);
+
+       d2.type = SDB_TYPE_BINARY;
+       d2.data.binary.datum = (unsigned char *)"some string";
+       d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
+       check = sdb_data_copy(&d1, &d2);
+       fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
+       fail_unless(d1.type == d2.type,
+                       "sdb_data_copy() didn't copy type; got: %i; expected: %i",
+                       d1.type, d2.type);
+       fail_unless(d1.data.binary.length == d2.data.binary.length,
+                       "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
+                       d1.data.binary.length, d2.data.binary.length);
+       fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
+                               d2.data.binary.length),
+                       "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
+                       d1.data.string, d2.data.string);
+
+       sdb_data_free_datum(&d1);
+       fail_unless(d1.data.binary.length == 0,
+                       "sdb_data_free_datum() didn't reset binary datum length");
+       fail_unless(d1.data.binary.datum == NULL,
+                       "sdb_data_free_datum() didn't free binary datum");
+}
+END_TEST
+
+Suite *
+core_data_suite(void)
+{
+       Suite *s = suite_create("core::data");
+       TCase *tc;
+
+       tc = tcase_create("core");
+       tcase_add_test(tc, test_data);
+       suite_add_tcase(s, tc);
+
+       return s;
+} /* core_data_suite */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
index 2fa83dc6af7f4dcbd758e19459cc8b37e37a7cde..c7787e4466bfc5fee7ec4e9869e7f42ddefe934e 100644 (file)
@@ -38,6 +38,7 @@ main(void)
        size_t i;
 
        suite_creator_t creators[] = {
+               { core_data_suite, NULL },
                { core_object_suite, NULL },
                { core_store_suite, NULL },
                { fe_parser_suite, NULL },
index 64558cdadebfb2861f3c6f0fb459d7307c28eb65..5539d63290e54a258350c05a6846819820ae27d7 100644 (file)
@@ -59,6 +59,10 @@ typedef struct {
  * test suites
  */
 
+/* t/core/data_test */
+Suite *
+core_data_suite(void);
+
 /* t/core/object_test */
 Suite *
 core_object_suite(void);