From 0a4824ddb1c8724a7032935c1e23d726666ac145 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 5 Jul 2011 19:26:57 +0300 Subject: [PATCH] gobex: Make on-demand body headers a GObexPacket feature --- gobex/gobex-header.c | 42 ----------------------------- gobex/gobex-header.h | 6 ----- gobex/gobex-packet.c | 58 +++++++++++++++++++++++++++++++++------- gobex/gobex-packet.h | 5 ++++ gobex/gobex-transfer.c | 13 +++------ unit/test-gobex-header.c | 51 ----------------------------------- unit/test-gobex-packet.c | 16 +++-------- unit/test-gobex.c | 11 +++----- 8 files changed, 64 insertions(+), 138 deletions(-) diff --git a/gobex/gobex-header.c b/gobex/gobex-header.c index 3446bb9e7..061a1e0cd 100644 --- a/gobex/gobex-header.c +++ b/gobex/gobex-header.c @@ -43,9 +43,6 @@ struct _GObexHeader { guint8 u8; guint32 u32; } v; - - GObexHeaderDataFunc get_data; - gpointer get_data_data; }; static glong utf8_to_utf16(gunichar2 **utf16, const char *utf8) { @@ -83,24 +80,6 @@ static const guint8 *get_bytes(void *to, const guint8 *from, gsize count) return (from + count); } -static gssize get_data(GObexHeader *header, guint8 *buf, gsize len) -{ - guint16 u16; - gssize ret; - - ret = header->get_data(header, buf + 2, len - 2, - header->get_data_data); - if (ret < 0) - return ret; - - header->vlen = ret; - header->hlen = header->vlen + 3; - u16 = g_htons(header->hlen); - memcpy(buf, &u16, sizeof(u16)); - - return header->hlen; -} - gssize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len) { guint8 *ptr = buf; @@ -126,9 +105,6 @@ gssize g_obex_header_encode(GObexHeader *header, void *buf, gsize buf_len) g_free(utf16); break; case G_OBEX_HDR_TYPE_BYTES: - if (header->get_data) - return get_data(header, ptr, buf_len - 1); - u16 = g_htons(header->hlen); ptr = put_bytes(ptr, &u16, sizeof(u16)); if (header->extdata) @@ -391,24 +367,6 @@ GObexHeader *g_obex_header_new_bytes(guint8 id, void *data, gsize len, return header; } -GObexHeader *g_obex_header_new_on_demand(guint8 id, GObexHeaderDataFunc func, - gpointer user_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->hlen = 3; - header->get_data = func; - header->get_data_data = user_data; - - return header; -} - GObexHeader *g_obex_header_new_uint8(guint8 id, guint8 val) { GObexHeader *header; diff --git a/gobex/gobex-header.h b/gobex/gobex-header.h index b25051fb6..dfce62c9d 100644 --- a/gobex/gobex-header.h +++ b/gobex/gobex-header.h @@ -55,9 +55,6 @@ typedef struct _GObexHeader GObexHeader; -typedef gssize (*GObexHeaderDataFunc) (GObexHeader *header, void *buf, - gsize len, gpointer user_data); - gboolean g_obex_header_get_unicode(GObexHeader *header, const char **str); gboolean g_obex_header_get_bytes(GObexHeader *header, const guint8 **val, gsize *len); @@ -67,9 +64,6 @@ gboolean g_obex_header_get_uint32(GObexHeader *header, guint32 *val); GObexHeader *g_obex_header_new_unicode(guint8 id, const char *str); GObexHeader *g_obex_header_new_bytes(guint8 id, void *data, gsize len, GObexDataPolicy data_policy); -GObexHeader *g_obex_header_new_on_demand(guint8 id, - GObexHeaderDataFunc func, - gpointer user_data); GObexHeader *g_obex_header_new_uint8(guint8 id, guint8 val); GObexHeader *g_obex_header_new_uint32(guint8 id, guint32 val); diff --git a/gobex/gobex-packet.c b/gobex/gobex-packet.c index e5bf618ac..6051fc4c8 100644 --- a/gobex/gobex-packet.c +++ b/gobex/gobex-packet.c @@ -40,6 +40,9 @@ struct _GObexPacket { gsize hlen; /* Length of all encoded headers */ GSList *headers; + + GObexPacketDataFunc get_body; + gpointer get_body_data; }; GObexHeader *g_obex_packet_get_header(GObexPacket *pkt, guint8 id) @@ -94,6 +97,18 @@ gboolean g_obex_packet_add_header(GObexPacket *pkt, GObexHeader *header) return TRUE; } +gboolean g_obex_packet_add_body(GObexPacket *pkt, GObexPacketDataFunc func, + gpointer user_data) +{ + if (pkt->get_body != NULL) + return FALSE; + + pkt->get_body = func; + pkt->get_body_data = user_data; + + return TRUE; +} + const void *g_obex_packet_get_data(GObexPacket *pkt, gsize *len) { if (pkt->data_len == 0) { @@ -257,8 +272,32 @@ failed: return NULL; } +static gssize get_body(GObexPacket *pkt, guint8 *buf, gsize len) +{ + guint16 u16; + gssize ret; + + if (len < 3) + return -ENOBUFS; + + ret = pkt->get_body(pkt, buf + 3, len - 3, pkt->get_body_data); + if (ret < 0) + return ret; + + if (ret > 0) + buf[0] = G_OBEX_HDR_ID_BODY; + else + buf[0] = G_OBEX_HDR_ID_BODY_END; + + u16 = g_htons(ret + 3); + memcpy(&buf[1], &u16, sizeof(u16)); + + return ret; +} + gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len) { + gssize ret; gsize count; guint16 u16; GSList *l; @@ -281,7 +320,6 @@ gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len) for (l = pkt->headers; l != NULL; l = g_slist_next(l)) { GObexHeader *hdr = l->data; - gssize ret; if (count >= len) return -ENOBUFS; @@ -290,18 +328,18 @@ gssize g_obex_packet_encode(GObexPacket *pkt, guint8 *buf, gsize len) if (ret < 0) return ret; - /* Fix-up on-demand body header type and final bit. This - * breaks the layers of abstraction a bit but it's the - * simplest way to avoid two consecutive empty packets */ - if (g_obex_header_get_id(hdr) == G_OBEX_HDR_ID_BODY && - ret == 3) { - buf[0] |= FINAL_BIT; - buf[count] = G_OBEX_HDR_ID_BODY_END; - } - count += ret; } + if (pkt->get_body) { + ret = get_body(pkt, buf + count, len - count); + if (ret < 0) + return ret; + if (ret == 0) + buf[0] |= FINAL_BIT; + count += ret + 3; + } + u16 = g_htons(count); memcpy(&buf[1], &u16, sizeof(u16)); diff --git a/gobex/gobex-packet.h b/gobex/gobex-packet.h index 0d38c1da0..ce7844771 100644 --- a/gobex/gobex-packet.h +++ b/gobex/gobex-packet.h @@ -80,11 +80,16 @@ typedef struct _GObexPacket GObexPacket; +typedef gssize (*GObexPacketDataFunc) (GObexPacket *header, void *buf, + gsize len, gpointer user_data); + GObexHeader *g_obex_packet_get_header(GObexPacket *pkt, guint8 id); guint8 g_obex_packet_get_operation(GObexPacket *pkt, gboolean *final); GObexHeader *g_obex_packet_find_header(GObexPacket *pkt, guint8 id); gboolean g_obex_packet_prepend_header(GObexPacket *pkt, GObexHeader *header); gboolean g_obex_packet_add_header(GObexPacket *pkt, GObexHeader *header); +gboolean g_obex_packet_add_body(GObexPacket *pkt, GObexPacketDataFunc func, + gpointer user_data); gboolean g_obex_packet_set_data(GObexPacket *pkt, const void *data, gsize len, GObexDataPolicy data_policy); const void *g_obex_packet_get_data(GObexPacket *pkt, gsize *len); diff --git a/gobex/gobex-transfer.c b/gobex/gobex-transfer.c index 551737e2e..48145dba5 100644 --- a/gobex/gobex-transfer.c +++ b/gobex/gobex-transfer.c @@ -65,7 +65,7 @@ static void transfer_abort_response(GObex *obex, GError *err, GObexPacket *rsp, } -static gssize put_get_data(GObexHeader *header, void *buf, gsize len, +static gssize put_get_data(GObexPacket *pkt, void *buf, gsize len, gpointer user_data) { struct transfer *transfer = user_data; @@ -94,7 +94,6 @@ static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp, { struct transfer *transfer = user_data; GObexPacket *req; - GObexHeader *hdr; gboolean rspcode, final; if (err != NULL) { @@ -119,10 +118,7 @@ static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp, } req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL); - - hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, put_get_data, - transfer); - g_obex_packet_add_header(req, hdr); + g_obex_packet_add_body(req, put_get_data, transfer); transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response, transfer, &err); @@ -155,16 +151,13 @@ guint g_obex_put(GObex *obex, const char *type, const char *name, GError **err) { GObexPacket *req; - GObexHeader *hdr; struct transfer *transfer; transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data); transfer->data_producer = data_func; req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, NULL); - hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, - put_get_data, transfer); - g_obex_packet_add_header(req, hdr); + g_obex_packet_add_body(req, put_get_data, transfer); transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response, transfer, err); diff --git a/unit/test-gobex-header.c b/unit/test-gobex-header.c index bf69abb48..33ebda3b5 100644 --- a/unit/test-gobex-header.c +++ b/unit/test-gobex-header.c @@ -130,53 +130,6 @@ static void test_header_uint32(void) g_obex_header_free(header); } -static gssize get_body_data(GObexHeader *header, void *buf, gsize len, - gpointer user_data) -{ - uint8_t body_data[] = { 1, 2, 3, 4 }; - - memcpy(buf, body_data, sizeof(body_data)); - - return sizeof(body_data); -} - -static void test_header_on_demand(void) -{ - GObexHeader *header; - uint8_t buf[1024]; - size_t len; - - header = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, - get_body_data, 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 gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len, - gpointer user_data) -{ - return -1; -} - -static void test_header_on_demand_fail(void) -{ - GObexHeader *header; - uint8_t buf[1024]; - gssize len; - - header = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, - get_body_data_fail, NULL); - - len = g_obex_header_encode(header, buf, sizeof(buf)); - g_assert_cmpint(len, ==, -1); - - g_obex_header_free(header); -} - static GObexHeader *parse_and_encode(uint8_t *buf, size_t buf_len) { GObexHeader *header; @@ -505,10 +458,6 @@ int main(int argc, char *argv[]) g_test_add_func("/gobex/test_header_uint8", test_header_uint8); g_test_add_func("/gobex/test_header_uint32", test_header_uint32); - g_test_add_func("/gobex/test_header_on_demand", test_header_on_demand); - g_test_add_func("/gobex/test_header_on_demand_fail", - test_header_on_demand_fail); - g_test_run(); return 0; diff --git a/unit/test-gobex-packet.c b/unit/test-gobex-packet.c index 33be55d9a..ac78568a6 100644 --- a/unit/test-gobex-packet.c +++ b/unit/test-gobex-packet.c @@ -144,7 +144,7 @@ static void test_decode_encode(void) g_obex_packet_free(pkt); } -static gssize get_body_data(GObexHeader *header, void *buf, gsize len, +static gssize get_body_data(GObexPacket *pkt, void *buf, gsize len, gpointer user_data) { uint8_t data[] = { 1, 2, 3, 4 }; @@ -157,15 +157,11 @@ static gssize get_body_data(GObexHeader *header, void *buf, gsize len, static void test_encode_on_demand(void) { GObexPacket *pkt; - GObexHeader *hdr; uint8_t buf[255]; gssize len; pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL); - - hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, - get_body_data, NULL); - g_obex_packet_add_header(pkt, hdr); + g_obex_packet_add_body(pkt, get_body_data, NULL); len = g_obex_packet_encode(pkt, buf, sizeof(buf)); if (len < 0) { @@ -178,7 +174,7 @@ static void test_encode_on_demand(void) g_obex_packet_free(pkt); } -static gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len, +static gssize get_body_data_fail(GObexPacket *pkt, void *buf, gsize len, gpointer user_data) { return -1; @@ -187,15 +183,11 @@ static gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len, static void test_encode_on_demand_fail(void) { GObexPacket *pkt; - GObexHeader *hdr; uint8_t buf[255]; gssize len; pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL); - - hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, - get_body_data_fail, NULL); - g_obex_packet_add_header(pkt, hdr); + g_obex_packet_add_body(pkt, get_body_data_fail, NULL); len = g_obex_packet_encode(pkt, buf, sizeof(buf)); diff --git a/unit/test-gobex.c b/unit/test-gobex.c index 1fb74b55a..4792b8d5c 100644 --- a/unit/test-gobex.c +++ b/unit/test-gobex.c @@ -570,7 +570,7 @@ static void test_send_connect_pkt(void) test_send_connect(SOCK_SEQPACKET); } -static gssize get_body_data(GObexHeader *header, void *buf, gsize len, +static gssize get_body_data(GObexPacket *pkt, void *buf, gsize len, gpointer user_data) { uint8_t data[] = { 1, 2, 3, 4 }; @@ -580,20 +580,19 @@ static gssize get_body_data(GObexHeader *header, void *buf, gsize len, return sizeof(data); } -static gssize get_body_data_fail(GObexHeader *header, void *buf, gsize len, +static gssize get_body_data_fail(GObexPacket *pkt, void *buf, gsize len, gpointer user_data) { g_main_loop_quit(mainloop); return -1; } -static void test_send_on_demand(int transport_type, GObexHeaderDataFunc func) +static void test_send_on_demand(int transport_type, GObexPacketDataFunc func) { struct rcv_buf_info r; GIOChannel *io; GIOCondition cond; GObexPacket *req; - GObexHeader *hdr; guint io_id, timer_id; GObex *obex; @@ -604,9 +603,7 @@ static void test_send_on_demand(int transport_type, GObexHeaderDataFunc func) r.len = sizeof(pkt_put_body); req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, NULL); - - hdr = g_obex_header_new_on_demand(G_OBEX_HDR_ID_BODY, func, &r); - g_obex_packet_add_header(req, hdr); + g_obex_packet_add_body(req, func, &r); g_obex_send(obex, req, &r.err); g_assert_no_error(r.err); -- 2.47.3