diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-07-05 19:26:57 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-12-04 22:21:59 +0100 |
commit | 0a4824ddb1c8724a7032935c1e23d726666ac145 (patch) | |
tree | ed336007d49403ea29ff9101d8e92da4505811cd /gobex/gobex-packet.c | |
parent | 49514b2cc4e8cbb1a71b69c5f63fd59dc20bb46b (diff) | |
download | bluez-0a4824ddb1c8724a7032935c1e23d726666ac145.tar.gz |
gobex: Make on-demand body headers a GObexPacket feature
Diffstat (limited to 'gobex/gobex-packet.c')
-rw-r--r-- | gobex/gobex-packet.c | 58 |
1 files changed, 48 insertions, 10 deletions
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)); |