From c603d51e4ad3adea8d3f3afc8b796e49c180030b Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Tue, 19 May 2015 22:11:50 +0200 Subject: [PATCH 1/1] utils/proto: Support boolean values. They are encoded as a single byte on the wire. --- src/utils/proto.c | 44 +++++++++++++++++++++++++++++++++++---- t/unit/utils/proto_test.c | 35 +++++++++++++++++++++++++------ 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/utils/proto.c b/src/utils/proto.c index af47cdf..f8265d6 100644 --- a/src/utils/proto.c +++ b/src/utils/proto.c @@ -80,6 +80,30 @@ memdup(const unsigned char *d, size_t length) * return the number of bytes that would have been written if enough space had * been available. */ +static ssize_t +marshal_bool(char *buf, size_t buf_len, bool v) +{ + uint8_t t; + if (buf_len >= sizeof(t)) { + t = v ? 1 : 0; + memcpy(buf, &t, sizeof(t)); + } + return sizeof(t); +} /* marshal_bool */ + +static ssize_t +unmarshal_bool(const char *buf, size_t len, bool *v) +{ + uint8_t t; + if (len < sizeof(t)) + return -1; + if (v) { + memcpy(&t, buf, sizeof(t)); + *v = t != 0; + } + return sizeof(t); +} /* unmarshal_bool */ + static ssize_t marshal_int64(char *buf, size_t buf_len, int64_t v) { @@ -298,7 +322,9 @@ sdb_proto_marshal_data(char *buf, size_t buf_len, const sdb_data_t *datum) if (datum->type == SDB_TYPE_NULL) return len; - if (datum->type == SDB_TYPE_INTEGER) + if (datum->type == SDB_TYPE_BOOLEAN) + n = marshal_bool(buf, buf_len, datum->data.boolean); + else if (datum->type == SDB_TYPE_INTEGER) n = marshal_int64(buf, buf_len, datum->data.integer); else if (datum->type == SDB_TYPE_DECIMAL) n = marshal_double(buf, buf_len, datum->data.decimal); @@ -335,7 +361,11 @@ sdb_proto_marshal_data(char *buf, size_t buf_len, const sdb_data_t *datum) type = datum->type & 0xff; for (i = 0; i < datum->data.array.length; ++i) { - if (type == SDB_TYPE_INTEGER) { + if (type == SDB_TYPE_BOOLEAN) { + bool *v = datum->data.array.values; + n = marshal_bool(buf, buf_len, v[i]); + } + else if (type == SDB_TYPE_INTEGER) { int64_t *v = datum->data.array.values; n = marshal_int64(buf, buf_len, v[i]); } @@ -547,7 +577,9 @@ sdb_proto_unmarshal_data(const char *buf, size_t len, sdb_data_t *datum) /* Don't populate 'd' if 'datum' is NULL. */ #define D(field) (datum ? &d.data.field : NULL) - if (d.type == SDB_TYPE_INTEGER) + if (d.type == SDB_TYPE_BOOLEAN) + n = unmarshal_bool(buf, len, D(boolean)); + else if (d.type == SDB_TYPE_INTEGER) n = unmarshal_int64(buf, len, D(integer)); else if (d.type == SDB_TYPE_DECIMAL) n = unmarshal_double(buf, len, D(decimal)); @@ -605,7 +637,11 @@ sdb_proto_unmarshal_data(const char *buf, size_t len, sdb_data_t *datum) d.data.array.values = calloc(d.data.array.length, sdb_data_sizeof(d.type & 0xff)); for (i = 0; i < d.data.array.length; ++i) { - if ((d.type & 0xff) == SDB_TYPE_INTEGER) { + if ((d.type & 0xff) == SDB_TYPE_BOOLEAN) { + bool *v = d.data.array.values; + n = unmarshal_bool(buf, len, V()); + } + else if ((d.type & 0xff) == SDB_TYPE_INTEGER) { int64_t *v = d.data.array.values; n = unmarshal_int64(buf, len, V()); } diff --git a/t/unit/utils/proto_test.c b/t/unit/utils/proto_test.c index fa6bfcf..7e2e9b9 100644 --- a/t/unit/utils/proto_test.c +++ b/t/unit/utils/proto_test.c @@ -48,6 +48,7 @@ streq(const char *s1, const char *s2) START_TEST(test_marshal_data) { +#define BOOL_TYPE "\0\0\0\1" #define INT_TYPE "\0\0\0\2" #define DECIMAL_TYPE "\0\0\0\3" #define STRING_TYPE "\0\0\0\4" @@ -55,6 +56,7 @@ START_TEST(test_marshal_data) #define BINARY_TYPE "\0\0\0\6" #define REGEX_TYPE "\0\0\0\7" +#define BOOL_ARRAY "\0\0\1\1" #define NULL_ARRAY "\0\0\1\0" #define INT_ARRAY "\0\0\1\2" #define DECIMAL_ARRAY "\0\0\1\3" @@ -64,6 +66,7 @@ START_TEST(test_marshal_data) #define REGEX_ARRAY "\0\0\1\7" regex_t dummy_re; + bool bool_values[] = { true, false }; int64_t int_values[] = { 47, 11, 23 }; double dec_values[] = { 47.11, .5 }; char *string_values[] = { "foo", "abcd" }; @@ -91,6 +94,14 @@ START_TEST(test_marshal_data) { SDB_TYPE_NULL, { .integer = 0 } }, 4, "\0\0\0\0", }, + { + { SDB_TYPE_BOOLEAN, { .boolean = true } }, + 5, BOOL_TYPE "\1", + }, + { + { SDB_TYPE_BOOLEAN, { .boolean = false } }, + 5, BOOL_TYPE "\0", + }, { { SDB_TYPE_INTEGER, { .integer = 4711 } }, 12, INT_TYPE "\0\0\0\0\0\0\x12\x67", @@ -116,38 +127,50 @@ START_TEST(test_marshal_data) { SDB_TYPE_REGEX, { .re = { "dummy", dummy_re } } }, 10, REGEX_TYPE "dummy\0", }, + { + { SDB_TYPE_BOOLEAN | SDB_TYPE_ARRAY, { .array = { + SDB_STATIC_ARRAY_LEN(bool_values), bool_values, + } } }, + 10, BOOL_ARRAY "\0\0\0\x2" "\1\0" + }, { { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = { - 3, int_values } } }, + SDB_STATIC_ARRAY_LEN(int_values), int_values, + } } }, 32, INT_ARRAY "\0\0\0\x3" "\0\0\0\0\0\0\0\x2f" "\0\0\0\0\0\0\0\xb" "\0\0\0\0\0\0\0\x17" }, { { SDB_TYPE_DECIMAL | SDB_TYPE_ARRAY, { .array = { - 2, dec_values } } }, + SDB_STATIC_ARRAY_LEN(dec_values), dec_values, + } } }, 24, DECIMAL_ARRAY "\0\0\0\x2" "\x40\x47\x8e\x14\x7a\xe1\x47\xae" "\x3f\xe0\0\0\0\0\0\0" }, { { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = { - 2, string_values } } }, + SDB_STATIC_ARRAY_LEN(string_values), string_values, + } } }, 17, STRING_ARRAY "\0\0\0\x2" "foo\0" "abcd\0" }, { { SDB_TYPE_DATETIME | SDB_TYPE_ARRAY, { .array = { - 2, datetime_values } } }, + SDB_STATIC_ARRAY_LEN(datetime_values), datetime_values, + } } }, 24, DATETIME_ARRAY "\0\0\0\x2" "\0\0\0\0\0\0\x12\x67" "\x11\x22\x10\xf4\x7d\xe9\x81\x15" }, { { SDB_TYPE_BINARY | SDB_TYPE_ARRAY, { .array = { - 2, binary_values } } }, + SDB_STATIC_ARRAY_LEN(binary_values), binary_values, + } } }, 23, BINARY_ARRAY "\0\0\0\x2" "\0\0\0\x3" "\x1\x2\x3" "\0\0\0\4" "\x42\x0\xa\x1b" }, { { SDB_TYPE_REGEX | SDB_TYPE_ARRAY, { .array = { - 1, regex_values } } }, + SDB_STATIC_ARRAY_LEN(regex_values), regex_values, + } } }, 20, REGEX_ARRAY "\0\0\0\1" "dummy regex\0" }, }; -- 2.30.2