diff options
author | Lubomir I. Ivanov <neolit123@gmail.com> | 2012-12-28 18:18:23 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-12-28 08:58:44 -0800 |
commit | 8bce372eb1b0f6aa5c6a69c552a13845973ea694 (patch) | |
tree | a99379529c084cc5f5071b77d1ed4072ee36794a /parse-xml.c | |
parent | df613bf107ce98705d01a0bf63fb22257ca25187 (diff) | |
download | subsurface-8bce372eb1b0f6aa5c6a69c552a13845973ea694.tar.gz |
Don't allocate an intermediate buffer for most parsed xmlNode contents
parse-xml.c:
Instead of always allocating a buffer when parsing a node, only
do so for "strings" in the utf8_string() function. Also move the
whitespace trimming of node contents in there.
This change also requires that most parsing functions don't
free the passed buffer, as it will be part of memory allocated
by libxml2.
visit_one_node(), now also has a xmlIsBlankNode() check, where if
1 is returned, the node contains only whitespace or is empty and should
not be processed.
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'parse-xml.c')
-rw-r--r-- | parse-xml.c | 63 |
1 files changed, 17 insertions, 46 deletions
diff --git a/parse-xml.c b/parse-xml.c index 2e4dbc560..aa9d5e0f5 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -110,7 +110,6 @@ static void nonmatch(const char *type, const char *name, char *buffer) if (verbose > 1) printf("Unable to match %s '%s' (%s)\n", type, name, buffer); - free(buffer); } typedef void (*matchfn_t)(char *buffer, void *); @@ -186,8 +185,6 @@ static void divedate(char *buffer, void *_when) if (success) *when = utc_mktime(&cur_tm); - - free(buffer); } static void divetime(char *buffer, void *_when) @@ -202,7 +199,6 @@ static void divetime(char *buffer, void *_when) if (cur_tm.tm_year) *when = utc_mktime(&cur_tm); } - free(buffer); } /* Libdivecomputer: "2011-03-20 10:22:38" */ @@ -222,7 +218,6 @@ static void divedatetime(char *buffer, void *_when) cur_tm.tm_sec = sec; *when = utc_mktime(&cur_tm); } - free(buffer); } union int_or_float { @@ -292,7 +287,6 @@ static void pressure(char *buffer, void *_press) default: printf("Strange pressure reading %s\n", buffer); } - free(buffer); } static void salinity(char *buffer, void *_salinity) @@ -306,7 +300,6 @@ static void salinity(char *buffer, void *_salinity) default: printf("Strange salinity reading %s\n", buffer); } - free(buffer); } static void depth(char *buffer, void *_depth) @@ -328,7 +321,6 @@ static void depth(char *buffer, void *_depth) default: printf("Strange depth reading %s\n", buffer); } - free(buffer); } static void weight(char *buffer, void *_weight) @@ -378,7 +370,6 @@ static void temperature(char *buffer, void *_temperature) default: printf("Strange temperature reading %s\n", buffer); } - free(buffer); } static void sampletime(char *buffer, void *_time) @@ -399,7 +390,6 @@ static void sampletime(char *buffer, void *_time) default: printf("Strange sample time reading %s\n", buffer); } - free(buffer); } static void duration(char *buffer, void *_time) @@ -422,7 +412,6 @@ static void percent(char *buffer, void *_fraction) printf("Strange percentage reading %s\n", buffer); break; } - free(buffer); } static void gasmix(char *buffer, void *_fraction) @@ -453,12 +442,23 @@ static void cylindersize(char *buffer, void *_volume) printf("Strange volume reading %s\n", buffer); break; } - free(buffer); } static void utf8_string(char *buffer, void *_res) { - *(char **)_res = buffer; + int size; + char *res; + while (isspace(*buffer)) + buffer++; + size = strlen(buffer); + while (size && isspace(buffer[size-1])) + size--; + if (!size) + return; + res = malloc(size + 1); + memcpy(res, buffer, size); + res[size] = 0; + *(char **)_res = res; } #define MATCH(pattern, fn, dest) \ @@ -468,28 +468,24 @@ static void get_index(char *buffer, void *_i) { int *i = _i; *i = atoi(buffer); - free(buffer); } static void double_to_permil(char *buffer, void *_i) { int *i = _i; *i = g_ascii_strtod(buffer, NULL) * 1000.0 + 0.5; - free(buffer); } static void hex_value(char *buffer, void *_i) { uint32_t *i = _i; *i = strtol(buffer, NULL, 16); - free(buffer); } static void get_tripflag(char *buffer, void *_tf) { tripflag_t *tf = _tf; *tf = strcmp(buffer, "NOTRIP") ? TF_NONE : NO_TRIP; - free(buffer); } /* @@ -533,7 +529,6 @@ static void fahrenheit(char *buffer, void *_temperature) default: fprintf(stderr, "Crazy Diving Log temperature reading %s\n", buffer); } - free(buffer); } /* @@ -571,7 +566,6 @@ static void psi_or_bar(char *buffer, void *_pressure) default: fprintf(stderr, "Crazy Diving Log PSI reading %s\n", buffer); } - free(buffer); } static int divinglog_fill_sample(struct sample *sample, const char *name, int len, char *buf) @@ -777,7 +771,6 @@ static void uddf_datetime(char *buffer, void *_when) goto success; bad_date: printf("Bad date time %s\n", buffer); - free(buffer); return; success: @@ -790,7 +783,6 @@ success: tm.tm_min = mm; tm.tm_sec = ss; *when = utc_mktime(&tm); - free(buffer); } static int uddf_dive_match(struct dive *dive, const char *name, int len, char *buf) @@ -856,7 +848,6 @@ static void gps_location(char *buffer, void *_dive) dive->latitude = parse_degrees(buffer, &end); dive->longitude = parse_degrees(end, &end); - free(buffer); } /* We're in the top-level dive xml. Try to convert whatever value to a dive value */ @@ -1178,14 +1169,8 @@ static void divecomputer_end(void) cur_dc = NULL; } -static void entry(const char *name, int size, const char *raw) +static void entry(const char *name, char *buf) { - char *buf = malloc(size+1); - - if (!buf) - return; - memcpy(buf, raw, size); - buf[size] = 0; if (in_settings) { try_to_fill_dc_settings(name, buf); return; @@ -1210,7 +1195,6 @@ static void entry(const char *name, int size, const char *raw) try_to_fill_trip(&cur_trip, name, buf); return; } - free(buf); } static const char *nodename(xmlNode *node, char *buf, int len) @@ -1244,25 +1228,12 @@ static const char *nodename(xmlNode *node, char *buf, int len) static void visit_one_node(xmlNode *node) { - int len; - const unsigned char *content; + char *content; char buffer[MAXNAME]; const char *name; content = node->content; - if (!content) - return; - - /* Trim whitespace at beginning */ - while (isspace(*content)) - content++; - - /* Trim whitespace at end */ - len = strlen(content); - while (len && isspace(content[len-1])) - len--; - - if (!len) + if (!content || xmlIsBlankNode(node)) return; /* Don't print out the node name if it is "text" */ @@ -1271,7 +1242,7 @@ static void visit_one_node(xmlNode *node) name = nodename(node, buffer, sizeof(buffer)); - entry(name, len, content); + entry(name, content); } static void traverse(xmlNode *root); |