From: Sebastian Harl Date: Wed, 29 Jan 2014 20:41:18 +0000 (+0100) Subject: data: Added helper functions to copy and free data. X-Git-Tag: sysdb-0.1.0~231 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=9527aa99f9f515e01993406607e1267cb49921f2 data: Added helper functions to copy and free data. --- diff --git a/src/Makefile.am b/src/Makefile.am index cdadd60..8736948 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000..c71e363 --- /dev/null +++ b/src/core/data.c @@ -0,0 +1,87 @@ +/* + * SysDB - src/core/data.c + * Copyright (C) 2014 Sebastian 'tokkee' Harl + * 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 +#include + +/* + * 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 : */ + diff --git a/src/include/core/data.h b/src/include/core/data.h index b657486..a5438a2 100644 --- a/src/include/core/data.h +++ b/src/include/core/data.h @@ -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 diff --git a/t/Makefile.am b/t/Makefile.am index 6adf484..3c13ad5 100644 --- a/t/Makefile.am +++ b/t/Makefile.am @@ -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 index 0000000..7efa554 --- /dev/null +++ b/t/core/data_test.c @@ -0,0 +1,124 @@ +/* + * SysDB - t/core/data_test.c + * Copyright (C) 2014 Sebastian 'tokkee' Harl + * 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 + +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 : */ + diff --git a/t/libsysdb_test.c b/t/libsysdb_test.c index 2fa83dc..c7787e4 100644 --- a/t/libsysdb_test.c +++ b/t/libsysdb_test.c @@ -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 }, diff --git a/t/libsysdb_test.h b/t/libsysdb_test.h index 64558cd..5539d63 100644 --- a/t/libsysdb_test.h +++ b/t/libsysdb_test.h @@ -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);