static void test_header_encode_name_empty(void) { GObexHeader *header; const char *str; gboolean ret; header = parse_and_encode(hdr_name_empty, sizeof(hdr_name_empty)); ret = g_obex_header_get_unicode(header, &str); g_assert(ret == TRUE); g_assert_cmpstr(str, ==, ""); g_obex_header_free(header); }
static void test_header_encode_connid(void) { GObexHeader *header; gboolean ret; guint32 val; header = parse_and_encode(hdr_connid, sizeof(hdr_connid)); ret = g_obex_header_get_uint32(header, &val); g_assert(ret == TRUE); g_assert(val == 0x01020304); 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_new_bytes(G_OBEX_HDR_BODY, data, sizeof(data)); 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_name_umlaut(void) { GObexHeader *header; uint8_t buf[1024]; size_t len; header = g_obex_header_new_unicode(G_OBEX_HDR_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_uint8(void) { GObexHeader *header; uint8_t buf[1024]; size_t len; header = g_obex_header_new_uint8(G_OBEX_HDR_ACTION, 0xab); 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_encode_body(void) { GObexHeader *header; guint8 expected[] = { 1, 2, 3, 4}; const guint8 *buf; size_t len; gboolean ret; header = parse_and_encode(hdr_body, sizeof(hdr_body)); ret = g_obex_header_get_bytes(header, &buf, &len); g_assert(ret == TRUE); assert_memequal(expected, sizeof(expected), buf, len); g_obex_header_free(header); }
static void test_header_encode_apparam(void) { GObexHeader *header; GObexApparam *apparam; gboolean ret; guint32 data; header = parse_and_encode(hdr_apparam, sizeof(hdr_apparam)); apparam = g_obex_header_get_apparam(header); g_assert(apparam != NULL); ret = g_obex_apparam_get_uint32(apparam, 0x00, &data); g_assert(ret == TRUE); g_assert(data == 0x01020304); g_obex_apparam_free(apparam); g_obex_header_free(header); }
static void test_header_apparam(void) { GObexHeader *header; GObexApparam *apparam; uint8_t buf[1024]; size_t len; apparam = g_obex_apparam_set_uint32(NULL, 0, 0x01020304); g_assert(apparam != NULL); header = g_obex_header_new_apparam(apparam); g_assert(header != NULL); len = g_obex_header_encode(header, buf, sizeof(buf)); assert_memequal(hdr_apparam, sizeof(hdr_apparam), buf, len); g_obex_apparam_free(apparam); g_obex_header_free(header); }
GObexHeader *g_obex_header_decode(const void *data, gsize len, GObexDataPolicy data_policy, gsize *parsed, GError **err) { GObexHeader *header; const guint8 *ptr = data; guint16 hdr_len; gsize str_len; GError *conv_err = NULL; if (len < 2) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Too short header in packet"); g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message); return NULL; } header = g_new0(GObexHeader, 1); ptr = get_bytes(&header->id, ptr, sizeof(header->id)); g_obex_debug(G_OBEX_DEBUG_HEADER, "header 0x%02x", G_OBEX_HDR_ENC(header->id)); switch (G_OBEX_HDR_ENC(header->id)) { case G_OBEX_HDR_ENC_UNICODE: if (len < 3) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Not enough data for unicode header (0x%02x)", header->id); goto failed; } ptr = get_bytes(&hdr_len, ptr, sizeof(hdr_len)); hdr_len = g_ntohs(hdr_len); if (hdr_len == 3) { header->v.string = g_strdup(""); header->vlen = 0; header->hlen = hdr_len; *parsed = hdr_len; break; } if (hdr_len > len || hdr_len < 5) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Invalid unicode header (0x%02x) length (%u)", header->id, hdr_len); goto failed; } header->v.string = g_convert((const char *) ptr, hdr_len - 5, "UTF8", "UTF16BE", NULL, &str_len, &conv_err); if (header->v.string == NULL) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Unicode conversion failed: %s", conv_err->message); g_error_free(conv_err); goto failed; } header->vlen = (gsize) str_len; header->hlen = hdr_len; *parsed = hdr_len; break; case G_OBEX_HDR_ENC_BYTES: if (len < 3) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Too short byte array header"); goto failed; } ptr = get_bytes(&hdr_len, ptr, sizeof(hdr_len)); hdr_len = g_ntohs(hdr_len); if (hdr_len > len) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Too long byte array header"); goto failed; } if (hdr_len < 3) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Too small byte array length"); goto failed; } header->vlen = hdr_len - 3; header->hlen = hdr_len; switch (data_policy) { case G_OBEX_DATA_COPY: header->v.data = g_memdup(ptr, header->vlen); break; case G_OBEX_DATA_REF: header->extdata = TRUE; header->v.extdata = ptr; break; default: g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_INVALID_ARGS, "Invalid data policy"); goto failed; } *parsed = hdr_len; break; case G_OBEX_HDR_ENC_UINT8: header->vlen = 1; header->hlen = 2; header->v.u8 = *ptr; *parsed = 2; break; case G_OBEX_HDR_ENC_UINT32: if (len < 5) { g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR, "Too short uint32 header"); goto failed; } header->vlen = 4; header->hlen = 5; ptr = get_bytes(&header->v.u32, ptr, sizeof(header->v.u32)); header->v.u32 = g_ntohl(header->v.u32); *parsed = 5; break; default: g_assert_not_reached(); } return header; failed: if (*err) g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message); g_obex_header_free(header); return NULL; }