OSDN Git Service

gobex: Make on-demand body headers a GObexPacket feature
authorJohan Hedberg <johan.hedberg@intel.com>
Tue, 5 Jul 2011 16:26:57 +0000 (19:26 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 4 Dec 2012 21:21:59 +0000 (22:21 +0100)
gobex/gobex-header.c
gobex/gobex-header.h
gobex/gobex-packet.c
gobex/gobex-packet.h
gobex/gobex-transfer.c
unit/test-gobex-header.c
unit/test-gobex-packet.c
unit/test-gobex.c

index 3446bb9..061a1e0 100644 (file)
@@ -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;
index b25051f..dfce62c 100644 (file)
@@ -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);
 
index e5bf618..6051fc4 100644 (file)
@@ -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));
 
index 0d38c1d..ce78447 100644 (file)
 
 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);
index 551737e..48145db 100644 (file)
@@ -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);
index bf69abb..33ebda3 100644 (file)
@@ -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;
index 33be55d..ac78568 100644 (file)
@@ -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));
 
index 1fb74b5..4792b8d 100644 (file)
@@ -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);