Update parser_expat.c

solution for #46.
This commit is contained in:
curse666
2014-12-11 19:16:52 +09:00
committed by Dmitry Podgorny
parent b83347b464
commit 5f9c0399c3

View File

@@ -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);