From 4f8a84025ecb0d230407d54743186c2b4d1941c9 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Thu, 30 Jan 2014 18:53:29 +0100 Subject: [PATCH] core/data: Added sdb_data_format() function. This function creates a string representation of a datum using a default format. --- src/core/data.c | 46 +++++++++++++++++++++++++ src/include/core/data.h | 13 +++++++ t/core/data_test.c | 76 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) diff --git a/src/core/data.c b/src/core/data.c index c71e363..1bb5400 100644 --- a/src/core/data.c +++ b/src/core/data.c @@ -27,6 +27,8 @@ #include "core/data.h" +#include + #include #include @@ -83,5 +85,49 @@ sdb_data_free_datum(sdb_data_t *datum) } } /* sdb_data_free_datum */ +int +sdb_data_format(sdb_data_t *datum, sdb_strbuf_t *buf) +{ + if ((! datum) || (! buf)) + return -1; + + switch (datum->type) { + case SDB_TYPE_INTEGER: + sdb_strbuf_append(buf, "%"PRIi64, datum->data.integer); + break; + case SDB_TYPE_DECIMAL: + sdb_strbuf_append(buf, "%a", datum->data.decimal); + break; + case SDB_TYPE_STRING: + /* TODO: escape special characters */ + sdb_strbuf_append(buf, "\"%s\"", datum->data.string); + break; + case SDB_TYPE_DATETIME: + { + char tmp[64]; + if (! sdb_strftime(tmp, sizeof(tmp), "%F %T %z", + datum->data.datetime)) + return -1; + tmp[sizeof(tmp) - 1] = '\0'; + sdb_strbuf_append(buf, "%s", tmp); + } + break; + case SDB_TYPE_BINARY: + { + size_t i; + /* TODO: improve this! */ + sdb_strbuf_append(buf, "%s", "\""); + for (i = 0; i < datum->data.binary.length; ++i) + sdb_strbuf_append(buf, "\\%x", + (int)datum->data.binary.datum[i]); + sdb_strbuf_append(buf, "%s", "\""); + } + break; + default: + return -1; + } + return 0; +} /* sdb_data_format */ + /* vim: set tw=78 sw=4 ts=4 noexpandtab : */ diff --git a/src/include/core/data.h b/src/include/core/data.h index 53b6819..58e92cd 100644 --- a/src/include/core/data.h +++ b/src/include/core/data.h @@ -29,6 +29,7 @@ #define SDB_CORE_DATA_H 1 #include "core/time.h" +#include "utils/strbuf.h" #include #include @@ -87,6 +88,18 @@ sdb_data_copy(sdb_data_t *dst, const sdb_data_t *src); void sdb_data_free_datum(sdb_data_t *datum); +/* + * sdb_data_format: + * Append the specified datum to the specified string buffer using a default + * format. + * + * Returns: + * - 0 on success + * - a negative value else + */ +int +sdb_data_format(sdb_data_t *datum, sdb_strbuf_t *buf); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/t/core/data_test.c b/t/core/data_test.c index 7efa554..fb3b114 100644 --- a/t/core/data_test.c +++ b/t/core/data_test.c @@ -107,6 +107,81 @@ START_TEST(test_data) } END_TEST +START_TEST(test_format) +{ + sdb_data_t datum; + sdb_strbuf_t *buf; + const char *string; + const char *expected; + + int check; + + buf = sdb_strbuf_create(1024); + fail_unless(buf != NULL, + "INTERNAL ERROR: Failed to allocate string buffer"); + + datum.type = SDB_TYPE_INTEGER; + datum.data.integer = 4711; + check = sdb_data_format(&datum, buf); + fail_unless(! check, + "sdb_data_format(INTEGER) = %d; expected: 0", check); + string = sdb_strbuf_string(buf); + expected = "4711"; + fail_unless(! strcmp(string, expected), + "sdb_data_format() used wrong format: %s; expected: %s", + string, expected); + + datum.type = SDB_TYPE_DECIMAL; + datum.data.decimal = 65536.0; + sdb_strbuf_clear(buf); + check = sdb_data_format(&datum, buf); + fail_unless(! check, + "sdb_data_format(DECIMAL) = %d; expected: 0", check); + string = sdb_strbuf_string(buf); + expected = "0x1p+16"; + fail_unless(! strcmp(string, expected), + "sdb_data_format() used wrong format: %s; expected: %s", + string, expected); + + datum.type = SDB_TYPE_STRING; + datum.data.string = "this is a test"; + sdb_strbuf_clear(buf); + check = sdb_data_format(&datum, buf); + fail_unless(! check, + "sdb_data_format(STRING) = %d; expected: 0", check); + string = sdb_strbuf_string(buf); + expected = "\"this is a test\""; + fail_unless(! strcmp(string, expected), + "sdb_data_format() used wrong format: %s; expected: %s", + string, expected); + + datum.type = SDB_TYPE_DATETIME; + datum.data.datetime = 471147114711471100; + sdb_strbuf_clear(buf); + check = sdb_data_format(&datum, buf); + fail_unless(! check, + "sdb_data_format(DATETIME) = %d; expected: 0", check); + string = sdb_strbuf_string(buf); + expected = "1984-12-06 02:11:54 +0000"; + fail_unless(! strcmp(string, expected), + "sdb_data_format() used wrong format: %s; expected: %s", + string, expected); + + datum.type = SDB_TYPE_BINARY; + datum.data.binary.datum = (unsigned char *)"binary\0crap\x42"; + datum.data.binary.length = 12; + sdb_strbuf_clear(buf); + check = sdb_data_format(&datum, buf); + fail_unless(! check, + "sdb_data_format(BINARY) = %d; expected: 0", check); + string = sdb_strbuf_string(buf); + expected = "\"\\62\\69\\6e\\61\\72\\79\\0\\63\\72\\61\\70\\42\""; + fail_unless(! strcmp(string, expected), + "sdb_data_format() used wrong format: %s; expected: %s", + string, expected); +} +END_TEST + Suite * core_data_suite(void) { @@ -115,6 +190,7 @@ core_data_suite(void) tc = tcase_create("core"); tcase_add_test(tc, test_data); + tcase_add_test(tc, test_format); suite_add_tcase(s, tc); return s; -- 2.30.2