diff --git a/lib/clixon/clixon_xml.h b/lib/clixon/clixon_xml.h index 73d06f965..429fb1910 100644 --- a/lib/clixon/clixon_xml.h +++ b/lib/clixon/clixon_xml.h @@ -129,7 +129,7 @@ int xml_flag_reset(cxobj *xn, uint16_t flag); char *xml_value(cxobj *xn); int xml_value_set(cxobj *xn, char *val); -char *xml_value_append(cxobj *xn, char *val); +int xml_value_append(cxobj *xn, char *val); enum cxobj_type xml_type(cxobj *xn); int xml_type_set(cxobj *xn, enum cxobj_type type); diff --git a/lib/src/clixon_json_parse.y b/lib/src/clixon_json_parse.y index 8bbc6396e..5a5503da8 100644 --- a/lib/src/clixon_json_parse.y +++ b/lib/src/clixon_json_parse.y @@ -228,7 +228,7 @@ json_current_body(struct clicon_json_yacc_arg *jy, if ((xn = xml_new("body", jy->jy_current, NULL)) == NULL) goto done; xml_type_set(xn, CX_BODY); - if (value && xml_value_append(xn, value)==NULL) + if (value && xml_value_append(xn, value) < 0) goto done; retval = 0; done: diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index be8a36b81..e948abde2 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -126,9 +126,7 @@ struct xml{ int x_childvec_len;/* Number of children */ int x_childvec_max;/* Length of allocated vector */ enum cxobj_type x_type; /* type of node: element, attribute, body */ - char *x_value; /* attribute and body nodes have values */ - uint32_t x_value_len; /* Length of x_value string (excluding null) */ - uint32_t x_value_max; /* allocated size for x_value */ + cbuf *x_value_cb; /* attribute and body nodes have values */ int x_flags; /* Flags according to XML_FLAG_* */ yang_stmt *x_spec; /* Pointer to specification, eg yang, by reference, dont free */ @@ -624,43 +622,7 @@ xml_flag_reset(cxobj *xn, char* xml_value(cxobj *xn) { - return xn->x_value; -} - -/*! xml value string reallocator - */ -static int -xml_value_realloc(cxobj *xn, - int len0, - char *val) -{ - int retval = -1; - int len; - int diff; - - if (val==NULL) - goto ok; - len = len0 + strlen(val); - diff = xn->x_value_max - (len + 1); - if (diff <= 0){ - while (diff <= 0){ - if (xn->x_value_max == 0) - xn->x_value_max = XML_VALUE_MAX_DEFAULT; - else - xn->x_value_max *= 2; - diff = xn->x_value_max - (len + 1); - } - if ((xn->x_value = realloc(xn->x_value, xn->x_value_max)) == NULL){ - clicon_err(OE_XML, errno, "realloc"); - goto done; - } - } - strncpy(xn->x_value + len0, val, len-len0+1); - xn->x_value_len = len; - ok: - retval = 0; - done: - return retval; + return xn->x_value_cb?cbuf_get(xn->x_value_cb):NULL; } /*! Set value of xml node, value is copied @@ -675,12 +637,15 @@ xml_value_set(cxobj *xn, { int retval = -1; - if (xn->x_value && strlen(xn->x_value)){ - xn->x_value[0] = '\0'; - xn->x_value_len = 0; + if (xn->x_value_cb == NULL){ + if ((xn->x_value_cb = cbuf_new()) == NULL){ + clicon_err(OE_XML, errno, "cbuf_new"); + goto done; + } } - if (xml_value_realloc(xn, 0, val) < 0) - goto done; + else + cbuf_reset(xn->x_value_cb); + cprintf(xn->x_value_cb, "%s", val); retval = 0; done: return retval; @@ -692,13 +657,25 @@ xml_value_set(cxobj *xn, * @retval NULL on error with clicon-err set, or if value is set to NULL * @retval new value */ -char * +int xml_value_append(cxobj *xn, char *val) { - if (xml_value_realloc(xn, xn->x_value_len, val) < 0) - return NULL; - return xn->x_value; + int retval = -1; + + if (xn->x_value_cb == NULL){ + if ((xn->x_value_cb = cbuf_new()) == NULL){ + clicon_err(OE_XML, errno, "cbuf_new"); + goto done; + } + } + if (cprintf(xn->x_value_cb, "%s", val) < 0){ + clicon_err(OE_XML, errno, "cprintf"); + goto done; + } + retval = 0; + done: + return retval; } /*! Get type of xnode @@ -1623,8 +1600,8 @@ xml_free(cxobj *x) if (x->x_name) free(x->x_name); - if (x->x_value) - free(x->x_value); + if (x->x_value_cb) + cbuf_free(x->x_value_cb); if (x->x_prefix) free(x->x_prefix); for (i=0; ix_childvec_len; i++){ @@ -2648,8 +2625,10 @@ clicon_log_xml(int level, int retval = -1; /* Print xml as cbuf */ - if ((cb = cbuf_new()) == NULL) + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_XML, errno, "cbuf_new"); goto done; + } if (clicon_xml2cbuf(cb, x, 0, 0, -1) < 0) goto done; diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y index 6d735d621..3a1e94195 100644 --- a/lib/src/clixon_xml_parse.y +++ b/lib/src/clixon_xml_parse.y @@ -104,7 +104,7 @@ xml_parse_content(struct xml_parse_yacc_arg *ya, goto done; xml_type_set(xn, CX_BODY); } - if (xml_value_append(xn, str)==NULL) + if (xml_value_append(xn, str) < 0) goto done; ya->ya_xelement = xn; retval = 0; @@ -140,7 +140,7 @@ xml_parse_whitespace(struct xml_parse_yacc_arg *ya, goto done; xml_type_set(xn, CX_BODY); } - if (xml_value_append(xn, str)==NULL) + if (xml_value_append(xn, str) < 0) goto done; ya->ya_xelement = xn; ok: @@ -148,7 +148,6 @@ xml_parse_whitespace(struct xml_parse_yacc_arg *ya, done: return retval; } - static int xml_parse_version(struct xml_parse_yacc_arg *ya, diff --git a/test/test_perf_xml.sh b/test/test_perf_xml.sh index 9c7ed164f..17d7d6ce4 100755 --- a/test/test_perf_xml.sh +++ b/test/test_perf_xml.sh @@ -18,8 +18,11 @@ for (( i=0; i<$perfnr; i++ )); do done echo "]]>" >> $fxml +# 32-bit i386: +#0.37user 1.94system 0:02.47elapsed 93%CPU (0avgtext+0avgdata 9336maxresident)k +#256inputs+0outputs (2major+2049minor)pagefaults 0swa new "xml parse long CDATA" expecteof_file "time $clixon_util_xml" 0 "$fxml" - + rm -rf $dir