From 5f9c0399c3cfcc172771f893ca05a3c5ed34d8c0 Mon Sep 17 00:00:00 2001 From: curse666 Date: Thu, 11 Dec 2014 19:16:52 +0900 Subject: [PATCH] Update parser_expat.c solution for #46. --- src/parser_expat.c | 64 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/parser_expat.c b/src/parser_expat.c index 39c1dc4..c62e87c 100644 --- a/src/parser_expat.c +++ b/src/parser_expat.c @@ -35,6 +35,7 @@ struct _parser_t { void *userdata; int depth; xmpp_stanza_t *stanza; + char* inner_text; }; /* return allocated string with the name from a delimited @@ -141,6 +142,7 @@ static void _start_element(void *userdata, static void _end_element(void *userdata, const XML_Char *name) { parser_t *parser = (parser_t *)userdata; + xmpp_stanza_t *stanza; parser->depth--; @@ -149,36 +151,55 @@ static void _end_element(void *userdata, const XML_Char *name) if (parser->endcb) parser->endcb((char *)name, parser->userdata); } else { - if (parser->stanza->parent) { - /* we're finishing a child stanza, so set current to the parent */ - parser->stanza = parser->stanza->parent; - } else { + if (parser->stanza->parent) { + /* we're finishing a child stanza, so set current to the parent */ + if (parser->inner_text) { + /* create and populate stanza */ + stanza = xmpp_stanza_new(parser->ctx); + if (!stanza) { + /* FIXME: allocation error, disconnect */ + return; + } + xmpp_stanza_set_text(stanza, parser->inner_text); + xmpp_free(parser->ctx, parser->inner_text); + parser->inner_text = NULL; + xmpp_stanza_add_child(parser->stanza, stanza); + xmpp_stanza_release(stanza); + } + parser->stanza = parser->stanza->parent; + } else { if (parser->stanzacb) parser->stanzacb(parser->stanza, parser->userdata); - xmpp_stanza_release(parser->stanza); - parser->stanza = NULL; - } + xmpp_stanza_release(parser->stanza); + parser->stanza = NULL; + } } } static void _characters(void *userdata, const XML_Char *s, int len) { parser_t *parser = (parser_t *)userdata; - xmpp_stanza_t *stanza; + char* new_text; + int textlen; if (parser->depth < 2) return; - /* create and populate stanza */ - stanza = xmpp_stanza_new(parser->ctx); - if (!stanza) { - /* FIXME: allocation error, disconnect */ - return; + if (!parser->inner_text) { + textlen = 0; + } else { + textlen = strlen(parser->inner_text); } - xmpp_stanza_set_text_with_size(stanza, s, len); - xmpp_stanza_add_child(parser->stanza, stanza); - xmpp_stanza_release(stanza); + new_text = xmpp_realloc(parser->ctx, parser->inner_text, textlen+len+1); + if (!new_text) { + /* FIXME: allocation error, disconnect */ + return; + } + + parser->inner_text = new_text; + memcpy(parser->inner_text+textlen, s, len); + parser->inner_text[textlen+len] = '\0'; } parser_t *parser_new(xmpp_ctx_t *ctx, @@ -199,6 +220,7 @@ parser_t *parser_new(xmpp_ctx_t *ctx, parser->userdata = userdata; parser->depth = 0; parser->stanza = NULL; + parser->inner_text = NULL; parser_reset(parser); } @@ -217,6 +239,11 @@ void parser_free(parser_t *parser) if (parser->expat) XML_ParserFree(parser->expat); + if (parser->inner_text) { + xmpp_free (parser->ctx, parser->inner_text); + parser->inner_text = NULL; + } + xmpp_free(parser->ctx, parser); } @@ -235,6 +262,11 @@ int parser_reset(parser_t *parser) parser->depth = 0; parser->stanza = NULL; + if (parser->inner_text) { + xmpp_free (parser->ctx, parser->inner_text); + parser->inner_text = NULL; + } + XML_SetUserData(parser->expat, parser); XML_SetElementHandler(parser->expat, _start_element, _end_element); XML_SetCharacterDataHandler(parser->expat, _characters);