From cf9afde062d7ba9373d04c2ecd530e417744358b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 22 Jun 2011 16:04:54 +0300 Subject: [PATCH] gobex: Add header creation functions --- gobex/gobex.c | 79 ++++++++++++++++++++ gobex/gobex.h | 6 ++ unit/test-gobex.c | 178 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 233 insertions(+), 30 deletions(-) diff --git a/gobex/gobex.c b/gobex/gobex.c index 7e6cf52f7..685db4062 100644 --- a/gobex/gobex.c +++ b/gobex/gobex.c @@ -230,6 +230,85 @@ void g_obex_header_free(GObexHeader *header) g_free(header); } +GObexHeader *g_obex_header_unicode(uint8_t id, const char *str) +{ + GObexHeader *header; + size_t len; + + if (G_OBEX_HDR_TYPE(id) != G_OBEX_HDR_TYPE_UNICODE) + return NULL; + + header = g_new0(GObexHeader, 1); + + header->id = id; + + len = g_utf8_strlen(str, -1); + + header->vlen = len; + header->hlen = 3 + ((len + 1) * 2); + header->v.string = g_strdup(str); + + return header; +} + +GObexHeader *g_obex_header_bytes(uint8_t id, void *data, size_t len, + gboolean copy_data) +{ + GObexHeader *header; + + if (G_OBEX_HDR_TYPE(id) != G_OBEX_HDR_TYPE_BYTES) + return NULL; + + header = g_new0(GObexHeader, 1); + + header->id = id; + header->vlen = len; + header->hlen = len + 3; + + if (copy_data) + header->v.data = g_memdup(data, len); + else { + header->extdata = TRUE; + header->v.extdata = data; + } + + return header; +} + +GObexHeader *g_obex_header_uint8(uint8_t id, uint8_t val) +{ + GObexHeader *header; + + if (G_OBEX_HDR_TYPE(id) != G_OBEX_HDR_TYPE_UINT8) + return NULL; + + header = g_new0(GObexHeader, 1); + + header->id = id; + header->vlen = 1; + header->hlen = 2; + header->v.u8 = val; + + return header; +} + +GObexHeader *g_obex_header_uint32(uint8_t id, uint32_t val) +{ + GObexHeader *header; + + if (G_OBEX_HDR_TYPE(id) != G_OBEX_HDR_TYPE_UINT32) + return NULL; + + header = g_new0(GObexHeader, 1); + + header->id = id; + header->vlen = 4; + header->hlen = 5; + header->v.u32 = val; + + return header; +} + gboolean g_obex_request_add_header(GObexRequest *req, GObexHeader *header) { req->headers = g_slist_append(req->headers, header); diff --git a/gobex/gobex.h b/gobex/gobex.h index df95ede76..7040f7816 100644 --- a/gobex/gobex.h +++ b/gobex/gobex.h @@ -66,6 +66,12 @@ typedef struct _GObex GObex; typedef struct _GObexRequest GObexRequest; typedef struct _GObexHeader GObexHeader; +GObexHeader *g_obex_header_unicode(uint8_t id, const char *str); +GObexHeader *g_obex_header_bytes(uint8_t id, void *data, size_t len, + gboolean copy_data); +GObexHeader *g_obex_header_uint8(uint8_t id, uint8_t val); +GObexHeader *g_obex_header_uint32(uint8_t id, uint32_t val); + size_t g_obex_header_encode(GObexHeader *header, void *hdr_ptr, size_t buf_len); GObexHeader *g_obex_header_parse(const void *data, size_t len, gboolean copy, size_t *parsed); diff --git a/unit/test-gobex.c b/unit/test-gobex.c index e7c56f2d1..ab3c7dc59 100644 --- a/unit/test-gobex.c +++ b/unit/test-gobex.c @@ -25,8 +25,10 @@ #include static uint8_t hdr_connid[] = { G_OBEX_HDR_ID_CONNECTION, 1, 2, 3, 4 }; -static uint8_t hdr_name[] = { G_OBEX_HDR_ID_NAME, 0x00, 0x0b, +static uint8_t hdr_name_ascii[] = { G_OBEX_HDR_ID_NAME, 0x00, 0x0b, 0x00, 'f', 0x00, 'o', 0x00, 'o', 0x00, 0x00 }; +static uint8_t hdr_name_umlaut[] = { G_OBEX_HDR_ID_NAME, 0x00, 0x0b, + 0x00, 0xe5, 0x00, 0xe4, 0x00, 0xf6, 0x00, 0x00 }; static uint8_t hdr_body[] = { G_OBEX_HDR_ID_BODY, 0x00, 0x07, 1, 2, 3, 4 }; static uint8_t hdr_actionid[] = { G_OBEX_HDR_ID_ACTION, 0x00 }; @@ -45,9 +47,106 @@ static void dump_bytes(uint8_t *buf, size_t buf_len) size_t i; for (i = 0; i < buf_len; i++) - g_print("%02x ", buf[i]); + g_printerr("%02x ", buf[i]); - g_print("\n"); + g_printerr("\n"); +} + +static void assert_memequal(void *mem1, size_t len1, void *mem2, size_t len2) +{ + if (len1 == len2 && memcmp(mem1, mem2, len1) == 0) + return; + + g_printerr("\nExpected: "); + dump_bytes(mem1, len1); + g_printerr("Got: "); + dump_bytes(mem2, len2); + + g_assert(0); +} + +static void test_header_name_ascii(void) +{ + GObexHeader *header; + uint8_t buf[1024]; + size_t len; + + header = g_obex_header_unicode(G_OBEX_HDR_ID_NAME, "foo"); + + g_assert(header != NULL); + + len = g_obex_header_encode(header, buf, sizeof(buf)); + + assert_memequal(hdr_name_ascii, sizeof(hdr_name_ascii), buf, len); + + g_obex_header_free(header); +} + +static void test_header_name_umlaut(void) +{ + GObexHeader *header; + uint8_t buf[1024]; + size_t len; + + header = g_obex_header_unicode(G_OBEX_HDR_ID_NAME, "åäö"); + + g_assert(header != NULL); + + len = g_obex_header_encode(header, buf, sizeof(buf)); + + assert_memequal(hdr_name_umlaut, sizeof(hdr_name_umlaut), buf, len); + + g_obex_header_free(header); +} + +static void test_header_bytes(void) +{ + GObexHeader *header; + uint8_t buf[1024], data[] = { 1, 2, 3, 4 }; + size_t len; + + header = g_obex_header_bytes(G_OBEX_HDR_ID_BODY, data, sizeof(data), + FALSE); + + g_assert(header != NULL); + + len = g_obex_header_encode(header, buf, sizeof(buf)); + + assert_memequal(hdr_body, sizeof(hdr_body), buf, len); + + g_obex_header_free(header); +} + +static void test_header_uint8(void) +{ + GObexHeader *header; + uint8_t buf[1024]; + size_t len; + + header = g_obex_header_uint8(G_OBEX_HDR_ID_ACTION, 0x00); + + g_assert(header != NULL); + + len = g_obex_header_encode(header, buf, sizeof(buf)); + + assert_memequal(hdr_actionid, sizeof(hdr_actionid), buf, len); + + g_obex_header_free(header); +} + +static void test_header_uint32(void) +{ + GObexHeader *header; + uint8_t buf[1024]; + size_t len; + + header = g_obex_header_uint32(G_OBEX_HDR_ID_CONNECTION, 0x01020304); + + len = g_obex_header_encode(header, buf, sizeof(buf)); + + assert_memequal(hdr_connid, sizeof(hdr_connid), buf, len); + + g_obex_header_free(header); } static void parse_and_decode(uint8_t *buf, size_t buf_len) @@ -62,22 +161,9 @@ static void parse_and_decode(uint8_t *buf, size_t buf_len) len = g_obex_header_encode(header, encoded, sizeof(encoded)); - g_obex_header_free(header); + assert_memequal(buf, buf_len, encoded, len); - if (len != buf_len) - goto failed; - - if (memcmp(encoded, buf, len) != 0) - goto failed; - - return; - -failed: - g_print("\nIn: "); - dump_bytes(buf, buf_len); - g_print("Out: "); - dump_bytes(encoded, len); - g_assert(0); + g_obex_header_free(header); } static void test_header_encode_connid(void) @@ -85,9 +171,14 @@ static void test_header_encode_connid(void) parse_and_decode(hdr_connid, sizeof(hdr_connid)); } -static void test_header_encode_name(void) +static void test_header_encode_name_ascii(void) { - parse_and_decode(hdr_name, sizeof(hdr_name)); + parse_and_decode(hdr_name_ascii, sizeof(hdr_name_ascii)); +} + +static void test_header_encode_name_umlaut(void) +{ + parse_and_decode(hdr_name_umlaut, sizeof(hdr_name_umlaut)); } static void test_header_encode_body(void) @@ -114,16 +205,30 @@ static void test_parse_header_connid(void) g_obex_header_free(header); } -static void test_parse_header_name(void) +static void test_parse_header_name_ascii(void) { GObexHeader *header; size_t parsed; - header = g_obex_header_parse(hdr_name, sizeof(hdr_name), + header = g_obex_header_parse(hdr_name_ascii, sizeof(hdr_name_ascii), FALSE, &parsed); g_assert(header != NULL); - g_assert_cmpuint(parsed, ==, sizeof(hdr_name)); + g_assert_cmpuint(parsed, ==, sizeof(hdr_name_ascii)); + + g_obex_header_free(header); +} + +static void test_parse_header_name_umlaut(void) +{ + GObexHeader *header; + size_t parsed; + + header = g_obex_header_parse(hdr_name_umlaut, sizeof(hdr_name_umlaut), + FALSE, &parsed); + g_assert(header != NULL); + + g_assert_cmpuint(parsed, ==, sizeof(hdr_name_umlaut)); g_obex_header_free(header); } @@ -177,12 +282,12 @@ static void test_parse_header_multi(void) size_t parsed; buf = g_byte_array_sized_new(sizeof(hdr_connid) + - sizeof(hdr_name) + + sizeof(hdr_name_ascii) + sizeof(hdr_actionid) + sizeof(hdr_body)); g_byte_array_append(buf, hdr_connid, sizeof(hdr_connid)); - g_byte_array_append(buf, hdr_name, sizeof(hdr_name)); + g_byte_array_append(buf, hdr_name_ascii, sizeof(hdr_name_ascii)); g_byte_array_append(buf, hdr_actionid, sizeof(hdr_actionid)); g_byte_array_append(buf, hdr_body, sizeof(hdr_body)); @@ -194,7 +299,7 @@ static void test_parse_header_multi(void) header = g_obex_header_parse(buf->data, buf->len, FALSE, &parsed); g_assert(header != NULL); - g_assert_cmpuint(parsed, ==, sizeof(hdr_name)); + g_assert_cmpuint(parsed, ==, sizeof(hdr_name_ascii)); g_byte_array_remove_range(buf, 0, parsed); g_obex_header_free(header); @@ -270,8 +375,10 @@ int main(int argc, char *argv[]) g_test_add_func("/gobex/test_parse_header_connid", test_parse_header_connid); - g_test_add_func("/gobex/test_parse_header_name", - test_parse_header_name); + g_test_add_func("/gobex/test_parse_header_name_ascii", + test_parse_header_name_ascii); + g_test_add_func("/gobex/test_parse_header_name_umlaut", + test_parse_header_name_umlaut); g_test_add_func("/gobex/test_parse_header_body", test_parse_header_body); g_test_add_func("/gobex/test_parse_header_body_extdata", @@ -283,12 +390,23 @@ int main(int argc, char *argv[]) g_test_add_func("/gobex/test_header_encode_connid", test_header_encode_connid); - g_test_add_func("/gobex/test_header_encode_name", - test_header_encode_name); + g_test_add_func("/gobex/test_header_encode_name_ascii", + test_header_encode_name_ascii); + g_test_add_func("/gobex/test_header_encode_name_umlaut", + test_header_encode_name_umlaut); g_test_add_func("/gobex/test_header_encode_body", test_header_encode_body); g_test_add_func("/gobex/test_header_encode_connid", test_header_encode_actionid); + + g_test_add_func("/gobex/test_header_name_ascii", + test_header_name_ascii); + g_test_add_func("/gobex/test_header_name_umlaut", + test_header_name_umlaut); + g_test_add_func("/gobex/test_header_bytes", test_header_bytes); + g_test_add_func("/gobex/test_header_uint8", test_header_uint8); + g_test_add_func("/gobex/test_header_uint32", test_header_uint32); + g_test_run(); return 0; -- 2.47.3