From 0ce322844494022dc85a9c776d9ff041aad17520 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 10 May 2013 20:28:02 +0200 Subject: [PATCH] Avoid re allocations --- src/html_parser.cpp | 38 ++++++++++++++++++-------------------- src/html_parser.hpp | 5 ++++- src/test_html_parser.cpp | 4 ++-- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/html_parser.cpp b/src/html_parser.cpp index ef8ad2b..8d91a2c 100644 --- a/src/html_parser.cpp +++ b/src/html_parser.cpp @@ -54,6 +54,15 @@ void mp::HTMLParser::parse(mp::HTMLParserEvent & event, const char *str) const //static C functions follow would probably make sense to wrap this in PIMPL? +static char* dupe (const char *buff, int len) +{ + char *value = (char *) malloc (len + 1); + assert (value); + memcpy (value, buff, len); + value[len] = '\0'; + return value; +} + static int skipSpace (const char *cp) { int i = 0; @@ -76,7 +85,7 @@ static int skipName (const char *cp, char *dst) return i; } -static int skipAttribute (const char *cp, char *name, char **value) +static int skipAttribute (const char *cp, char *name, const char **value, int *val_len) { int i = skipName (cp, name); *value = NULL; @@ -105,9 +114,8 @@ static int skipAttribute (const char *cp, char *name, char **value) i++; v1 = i; } - *value = (char *) malloc (v1 - v0 + 1); - memcpy (*value, cp + v0, v1-v0); - (*value)[v1-v0] = '\0'; + *value = cp + v0; + *val_len = v1 - v0; } i += skipSpace (cp + i); return i; @@ -119,16 +127,17 @@ static int tagAttrs (mp::HTMLParserEvent & event, { int i; char attr_name[TAG_MAX_LEN]; - char *attr_value; + const char *attr_value; + int val_len; i = skipSpace (cp); while (cp[i] && cp[i] != '>') { - int nor = skipAttribute (cp+i, attr_name, &attr_value); + int nor = skipAttribute (cp+i, attr_name, &attr_value, &val_len); i += nor; if (nor) { - DEBUG(printf ("------ attr %s=%s\n", attr_name, attr_value)); - event.attribute(tagName, attr_name, attr_value); + DEBUG(printf ("------ attr %s=%s\n", attr_name, dupe(attr_value, val_len))); + event.attribute(tagName, attr_name, attr_value, val_len); } else { @@ -177,23 +186,12 @@ static int tagEnd (mp::HTMLParserEvent & event, const char *tagName, const char return i; } -static char* allocFromRange (const char *start, const char *end) -{ - char *value = (char *) malloc (end - start + 1); - assert (value); - memcpy (value, start, end - start); - value[end - start] = '\0'; - return value; -} - static void tagText (mp::HTMLParserEvent & event, const char *text_start, const char *text_end) { if (text_end - text_start) //got text to flush { - char *temp = allocFromRange(text_start, text_end); - DEBUG(printf ("------ text %s\n", temp)); + DEBUG(printf ("------ text %s\n", dupe(text_start, text_end-text_start))); event.text(text_start, text_end-text_start); - free(temp); } } diff --git a/src/html_parser.hpp b/src/html_parser.hpp index a03044b..ad46061 100644 --- a/src/html_parser.hpp +++ b/src/html_parser.hpp @@ -26,7 +26,10 @@ namespace metaproxy_1 { public: virtual void openTagStart(const char *name) = 0; virtual void anyTagEnd(const char *name) = 0; - virtual void attribute(const char *tagName, const char *name, const char *value) = 0; + virtual void attribute(const char *tagName, + const char *name, + const char *value, + int val_len) = 0; virtual void closeTag(const char *name) = 0; virtual void text(const char *value, int len) = 0; }; diff --git a/src/test_html_parser.cpp b/src/test_html_parser.cpp index 5230117..aa818f9 100644 --- a/src/test_html_parser.cpp +++ b/src/test_html_parser.cpp @@ -45,12 +45,12 @@ class MyEvent : public mp::HTMLParserEvent { } void attribute(const char *tagName, - const char *name, const char *value) + const char *name, const char *value, int val_len) { out += " "; out += name; out += "=\""; - out += value; + out.append(value, val_len); out += "\""; } -- 1.7.10.4