guint8 u8;
guint32 u32;
} v;
-
- GObexHeaderDataFunc get_data;
- gpointer get_data_data;
};
static glong utf8_to_utf16(gunichar2 **utf16, const char *utf8) {
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;
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)
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;
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);
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);
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)
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) {
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;
for (l = pkt->headers; l != NULL; l = g_slist_next(l)) {
GObexHeader *hdr = l->data;
- gssize ret;
if (count >= len)
return -ENOBUFS;
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));
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);
}
-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;
{
struct transfer *transfer = user_data;
GObexPacket *req;
- GObexHeader *hdr;
gboolean rspcode, final;
if (err != NULL) {
}
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);
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);
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;
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;
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 };
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) {
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;
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));
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 };
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;
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);