From 391831ac1eec8828c1405175e7c8a7397594a3df Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 2 Oct 2012 15:45:29 +0300 Subject: [PATCH] core: Move sdp_xml_parse_record from service plugin to sdp-xml.c --- Makefile.tools | 2 +- plugins/service.c | 203 ---------------------------------------------------- src/sdp-xml.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sdp-xml.h | 2 + 4 files changed, 212 insertions(+), 204 deletions(-) diff --git a/Makefile.tools b/Makefile.tools index 81feb7521..9637a9fc7 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -31,7 +31,7 @@ tools_hcitool_SOURCES = tools/hcitool.c src/oui.h src/oui.c \ tools_hcitool_LDADD = lib/libbluetooth-private.la tools_sdptool_SOURCES = tools/sdptool.c src/sdp-xml.h src/sdp-xml.c -tools_sdptool_LDADD = lib/libbluetooth-private.la +tools_sdptool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@ tools_ciptool_LDADD = lib/libbluetooth-private.la diff --git a/plugins/service.c b/plugins/service.c index d586d7992..4a3827059 100644 --- a/plugins/service.c +++ b/plugins/service.c @@ -53,13 +53,6 @@ struct record_data { struct service_adapter *serv_adapter; }; -struct context_data { - sdp_record_t *record; - sdp_data_t attr_data; - struct sdp_xml_data *stack_head; - uint16_t attr_id; -}; - struct pending_auth { DBusMessage *msg; char *sender; @@ -76,202 +69,6 @@ struct service_adapter { static struct service_adapter *serv_adapter_any = NULL; -static int compute_seq_size(sdp_data_t *data) -{ - int unit_size = data->unitSize; - sdp_data_t *seq = data->val.dataseq; - - for (; seq; seq = seq->next) - unit_size += seq->unitSize; - - return unit_size; -} - -static void element_start(GMarkupParseContext *context, - const gchar *element_name, const gchar **attribute_names, - const gchar **attribute_values, gpointer user_data, GError **err) -{ - struct context_data *ctx_data = user_data; - - if (!strcmp(element_name, "record")) - return; - - if (!strcmp(element_name, "attribute")) { - int i; - for (i = 0; attribute_names[i]; i++) { - if (!strcmp(attribute_names[i], "id")) { - ctx_data->attr_id = strtol(attribute_values[i], 0, 0); - break; - } - } - DBG("New attribute 0x%04x", ctx_data->attr_id); - return; - } - - if (ctx_data->stack_head) { - struct sdp_xml_data *newelem = sdp_xml_data_alloc(); - newelem->next = ctx_data->stack_head; - ctx_data->stack_head = newelem; - } else { - ctx_data->stack_head = sdp_xml_data_alloc(); - ctx_data->stack_head->next = NULL; - } - - if (!strcmp(element_name, "sequence")) - ctx_data->stack_head->data = sdp_data_alloc(SDP_SEQ8, NULL); - else if (!strcmp(element_name, "alternate")) - ctx_data->stack_head->data = sdp_data_alloc(SDP_ALT8, NULL); - else { - int i; - /* Parse value, name, encoding */ - for (i = 0; attribute_names[i]; i++) { - if (!strcmp(attribute_names[i], "value")) { - int curlen = strlen(ctx_data->stack_head->text); - int attrlen = strlen(attribute_values[i]); - - /* Ensure we're big enough */ - while ((curlen + 1 + attrlen) > ctx_data->stack_head->size) { - sdp_xml_data_expand(ctx_data->stack_head); - } - - memcpy(ctx_data->stack_head->text + curlen, - attribute_values[i], attrlen); - ctx_data->stack_head->text[curlen + attrlen] = '\0'; - } - - if (!strcmp(attribute_names[i], "encoding")) { - if (!strcmp(attribute_values[i], "hex")) - ctx_data->stack_head->type = 1; - } - - if (!strcmp(attribute_names[i], "name")) { - ctx_data->stack_head->name = strdup(attribute_values[i]); - } - } - - ctx_data->stack_head->data = sdp_xml_parse_datatype(element_name, - ctx_data->stack_head, ctx_data->record); - - if (ctx_data->stack_head->data == NULL) - error("Can't parse element %s", element_name); - } -} - -static void element_end(GMarkupParseContext *context, - const gchar *element_name, gpointer user_data, GError **err) -{ - struct context_data *ctx_data = user_data; - struct sdp_xml_data *elem; - - if (!strcmp(element_name, "record")) - return; - - if (!strcmp(element_name, "attribute")) { - if (ctx_data->stack_head && ctx_data->stack_head->data) { - int ret = sdp_attr_add(ctx_data->record, ctx_data->attr_id, - ctx_data->stack_head->data); - if (ret == -1) - DBG("Could not add attribute 0x%04x", - ctx_data->attr_id); - - ctx_data->stack_head->data = NULL; - sdp_xml_data_free(ctx_data->stack_head); - ctx_data->stack_head = NULL; - } else { - DBG("No data for attribute 0x%04x", ctx_data->attr_id); - } - return; - } - - if (!strcmp(element_name, "sequence")) { - ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data); - - if (ctx_data->stack_head->data->unitSize > USHRT_MAX) { - ctx_data->stack_head->data->unitSize += sizeof(uint32_t); - ctx_data->stack_head->data->dtd = SDP_SEQ32; - } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) { - ctx_data->stack_head->data->unitSize += sizeof(uint16_t); - ctx_data->stack_head->data->dtd = SDP_SEQ16; - } else { - ctx_data->stack_head->data->unitSize += sizeof(uint8_t); - } - } else if (!strcmp(element_name, "alternate")) { - ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data); - - if (ctx_data->stack_head->data->unitSize > USHRT_MAX) { - ctx_data->stack_head->data->unitSize += sizeof(uint32_t); - ctx_data->stack_head->data->dtd = SDP_ALT32; - } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) { - ctx_data->stack_head->data->unitSize += sizeof(uint16_t); - ctx_data->stack_head->data->dtd = SDP_ALT16; - } else { - ctx_data->stack_head->data->unitSize += sizeof(uint8_t); - } - } - - if (ctx_data->stack_head->next && ctx_data->stack_head->data && - ctx_data->stack_head->next->data) { - switch (ctx_data->stack_head->next->data->dtd) { - case SDP_SEQ8: - case SDP_SEQ16: - case SDP_SEQ32: - case SDP_ALT8: - case SDP_ALT16: - case SDP_ALT32: - ctx_data->stack_head->next->data->val.dataseq = - sdp_seq_append(ctx_data->stack_head->next->data->val.dataseq, - ctx_data->stack_head->data); - ctx_data->stack_head->data = NULL; - break; - } - - elem = ctx_data->stack_head; - ctx_data->stack_head = ctx_data->stack_head->next; - - sdp_xml_data_free(elem); - } -} - -static GMarkupParser parser = { - element_start, element_end, NULL, NULL, NULL -}; - -static sdp_record_t *sdp_xml_parse_record(const char *data, int size) -{ - GMarkupParseContext *ctx; - struct context_data *ctx_data; - sdp_record_t *record; - - ctx_data = malloc(sizeof(*ctx_data)); - if (!ctx_data) - return NULL; - - record = sdp_record_alloc(); - if (!record) { - free(ctx_data); - return NULL; - } - - memset(ctx_data, 0, sizeof(*ctx_data)); - ctx_data->record = record; - - ctx = g_markup_parse_context_new(&parser, 0, ctx_data, NULL); - - if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) { - error("XML parsing error"); - g_markup_parse_context_free(ctx); - sdp_record_free(record); - free(ctx_data); - return NULL; - } - - g_markup_parse_context_free(ctx); - - free(ctx_data); - - return record; -} - static struct record_data *find_record(struct service_adapter *serv_adapter, uint32_t handle, const char *sender) { diff --git a/src/sdp-xml.c b/src/sdp-xml.c index 52df285aa..054dfbde3 100644 --- a/src/sdp-xml.c +++ b/src/sdp-xml.c @@ -33,14 +33,223 @@ #include #include +#include + #include #include #include "sdp-xml.h" +#define DBG(...) (void)(0) +#define error(...) (void)(0) + #define STRBUFSIZE 1024 #define MAXINDENT 64 +struct context_data { + sdp_record_t *record; + sdp_data_t attr_data; + struct sdp_xml_data *stack_head; + uint16_t attr_id; +}; + +static int compute_seq_size(sdp_data_t *data) +{ + int unit_size = data->unitSize; + sdp_data_t *seq = data->val.dataseq; + + for (; seq; seq = seq->next) + unit_size += seq->unitSize; + + return unit_size; +} + +static void element_start(GMarkupParseContext *context, + const gchar *element_name, const gchar **attribute_names, + const gchar **attribute_values, gpointer user_data, GError **err) +{ + struct context_data *ctx_data = user_data; + + if (!strcmp(element_name, "record")) + return; + + if (!strcmp(element_name, "attribute")) { + int i; + for (i = 0; attribute_names[i]; i++) { + if (!strcmp(attribute_names[i], "id")) { + ctx_data->attr_id = strtol(attribute_values[i], 0, 0); + break; + } + } + DBG("New attribute 0x%04x", ctx_data->attr_id); + return; + } + + if (ctx_data->stack_head) { + struct sdp_xml_data *newelem = sdp_xml_data_alloc(); + newelem->next = ctx_data->stack_head; + ctx_data->stack_head = newelem; + } else { + ctx_data->stack_head = sdp_xml_data_alloc(); + ctx_data->stack_head->next = NULL; + } + + if (!strcmp(element_name, "sequence")) + ctx_data->stack_head->data = sdp_data_alloc(SDP_SEQ8, NULL); + else if (!strcmp(element_name, "alternate")) + ctx_data->stack_head->data = sdp_data_alloc(SDP_ALT8, NULL); + else { + int i; + /* Parse value, name, encoding */ + for (i = 0; attribute_names[i]; i++) { + if (!strcmp(attribute_names[i], "value")) { + int curlen = strlen(ctx_data->stack_head->text); + int attrlen = strlen(attribute_values[i]); + + /* Ensure we're big enough */ + while ((curlen + 1 + attrlen) > ctx_data->stack_head->size) { + sdp_xml_data_expand(ctx_data->stack_head); + } + + memcpy(ctx_data->stack_head->text + curlen, + attribute_values[i], attrlen); + ctx_data->stack_head->text[curlen + attrlen] = '\0'; + } + + if (!strcmp(attribute_names[i], "encoding")) { + if (!strcmp(attribute_values[i], "hex")) + ctx_data->stack_head->type = 1; + } + + if (!strcmp(attribute_names[i], "name")) { + ctx_data->stack_head->name = strdup(attribute_values[i]); + } + } + + ctx_data->stack_head->data = sdp_xml_parse_datatype(element_name, + ctx_data->stack_head, ctx_data->record); + + if (ctx_data->stack_head->data == NULL) + error("Can't parse element %s", element_name); + } +} + +static void element_end(GMarkupParseContext *context, + const gchar *element_name, gpointer user_data, GError **err) +{ + struct context_data *ctx_data = user_data; + struct sdp_xml_data *elem; + + if (!strcmp(element_name, "record")) + return; + + if (!strcmp(element_name, "attribute")) { + if (ctx_data->stack_head && ctx_data->stack_head->data) { + int ret = sdp_attr_add(ctx_data->record, ctx_data->attr_id, + ctx_data->stack_head->data); + if (ret == -1) + DBG("Could not add attribute 0x%04x", + ctx_data->attr_id); + + ctx_data->stack_head->data = NULL; + sdp_xml_data_free(ctx_data->stack_head); + ctx_data->stack_head = NULL; + } else { + DBG("No data for attribute 0x%04x", ctx_data->attr_id); + } + return; + } + + if (!strcmp(element_name, "sequence")) { + ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data); + + if (ctx_data->stack_head->data->unitSize > USHRT_MAX) { + ctx_data->stack_head->data->unitSize += sizeof(uint32_t); + ctx_data->stack_head->data->dtd = SDP_SEQ32; + } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) { + ctx_data->stack_head->data->unitSize += sizeof(uint16_t); + ctx_data->stack_head->data->dtd = SDP_SEQ16; + } else { + ctx_data->stack_head->data->unitSize += sizeof(uint8_t); + } + } else if (!strcmp(element_name, "alternate")) { + ctx_data->stack_head->data->unitSize = compute_seq_size(ctx_data->stack_head->data); + + if (ctx_data->stack_head->data->unitSize > USHRT_MAX) { + ctx_data->stack_head->data->unitSize += sizeof(uint32_t); + ctx_data->stack_head->data->dtd = SDP_ALT32; + } else if (ctx_data->stack_head->data->unitSize > UCHAR_MAX) { + ctx_data->stack_head->data->unitSize += sizeof(uint16_t); + ctx_data->stack_head->data->dtd = SDP_ALT16; + } else { + ctx_data->stack_head->data->unitSize += sizeof(uint8_t); + } + } + + if (ctx_data->stack_head->next && ctx_data->stack_head->data && + ctx_data->stack_head->next->data) { + switch (ctx_data->stack_head->next->data->dtd) { + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + ctx_data->stack_head->next->data->val.dataseq = + sdp_seq_append(ctx_data->stack_head->next->data->val.dataseq, + ctx_data->stack_head->data); + ctx_data->stack_head->data = NULL; + break; + } + + elem = ctx_data->stack_head; + ctx_data->stack_head = ctx_data->stack_head->next; + + sdp_xml_data_free(elem); + } +} + +static GMarkupParser parser = { + element_start, element_end, NULL, NULL, NULL +}; + +sdp_record_t *sdp_xml_parse_record(const char *data, int size) +{ + GMarkupParseContext *ctx; + struct context_data *ctx_data; + sdp_record_t *record; + + ctx_data = malloc(sizeof(*ctx_data)); + if (!ctx_data) + return NULL; + + record = sdp_record_alloc(); + if (!record) { + free(ctx_data); + return NULL; + } + + memset(ctx_data, 0, sizeof(*ctx_data)); + ctx_data->record = record; + + ctx = g_markup_parse_context_new(&parser, 0, ctx_data, NULL); + + if (g_markup_parse_context_parse(ctx, data, size, NULL) == FALSE) { + error("XML parsing error"); + g_markup_parse_context_free(ctx); + sdp_record_free(record); + free(ctx_data); + return NULL; + } + + g_markup_parse_context_free(ctx); + + free(ctx_data); + + return record; +} + + static void convert_raw_data_to_xml(sdp_data_t *value, int indent_level, void *data, void (*appender)(void *, const char *)) { diff --git a/src/sdp-xml.h b/src/sdp-xml.h index db7db3010..49efc3986 100644 --- a/src/sdp-xml.h +++ b/src/sdp-xml.h @@ -56,4 +56,6 @@ struct sdp_xml_data *sdp_xml_data_expand(struct sdp_xml_data *elem); sdp_data_t *sdp_xml_parse_datatype(const char *el, struct sdp_xml_data *elem, sdp_record_t *record); +sdp_record_t *sdp_xml_parse_record(const char *data, int size); + #endif /* __SDP_XML_H */ -- 2.11.0