diff options
Diffstat (limited to 'src/core/attr.c')
-rw-r--r-- | src/core/attr.c | 104 |
1 files changed, 23 insertions, 81 deletions
diff --git a/src/core/attr.c b/src/core/attr.c index 232f7ba..a82f117 100644 --- a/src/core/attr.c +++ b/src/core/attr.c @@ -177,120 +177,62 @@ dom_exception dom_attr_get_value(struct dom_attr *attr, { struct dom_node *a = (struct dom_node *) attr; struct dom_node *c; - uint8_t *rep; - size_t rep_len; - size_t rep_alloc; + struct dom_string *value, *temp; dom_exception err; -#define CHUNK 128 - - rep = dom_document_alloc(a->owner, NULL, CHUNK); - if (rep == NULL) - return DOM_NO_MEM_ERR; - - rep_len = 0; - rep_alloc = CHUNK; + err = dom_string_create_from_const_ptr(a->owner, + (const uint8_t *) "", SLEN(""), &value); + if (err != DOM_NO_ERR) { + return err; + } /* Traverse children, building a string representation as we go */ for (c = a->first_child; c != NULL; c = c->next) { if (c->type == DOM_TEXT_NODE && c->value != NULL) { - const uint8_t *data; - size_t len; - - err = dom_string_get_data(c->value, &data, &len); + /* Append to existing value */ + err = dom_string_concat(value, c->value, &temp); if (err != DOM_NO_ERR) { - dom_document_alloc(a->owner, rep, 0); + dom_string_unref(value); return err; } - /* Extend buffer, if necessary */ - if (rep_len + len >= rep_alloc) { - uint8_t *temp; - size_t required = (rep_len + len) - rep_alloc; - - /* Round required up to a chunk boundary */ - required = - (required + CHUNK - 1) & ~(CHUNK - 1); - - temp = dom_document_alloc(a->owner, rep, - rep_alloc + required); - if (temp == NULL) { - dom_document_alloc(a->owner, rep, 0); - return DOM_NO_MEM_ERR; - } - - rep = temp; - rep_alloc += required; - } - - /* Copy text into buffer */ - memcpy(rep + rep_len, data, len); + /* Finished with previous value */ + dom_string_unref(value); - /* And fix up length information */ - rep_len += len; + /* Claim new value */ + value = temp; } else if (c->type == DOM_ENTITY_REFERENCE_NODE) { struct dom_string *tr; - const uint8_t *data; - size_t len; /* Get textual representation of entity */ err = dom_entity_reference_get_textual_representation( (struct dom_entity_reference *) c, &tr); if (err != DOM_NO_ERR) { - dom_document_alloc(a->owner, rep, 0); + dom_string_unref(value); return err; } - err = dom_string_get_data(tr, &data, &len); + /* Append to existing value */ + err = dom_string_concat(value, tr, &temp); if (err != DOM_NO_ERR) { dom_string_unref(tr); - dom_document_alloc(a->owner, rep, 0); + dom_string_unref(value); return err; } - /* Extend buffer, if necessary */ - if (rep_len + len >= rep_alloc) { - uint8_t *temp; - size_t required = (rep_len + len) - rep_alloc; - - /* Round required up to a chunk boundary */ - required = - (required + CHUNK - 1) & ~(CHUNK - 1); - - temp = dom_document_alloc(a->owner, rep, - rep_alloc + required); - if (temp == NULL) { - dom_document_alloc(a->owner, rep, 0); - return DOM_NO_MEM_ERR; - } - - rep = temp; - rep_alloc += required; - } - - /* Copy text into buffer */ - memcpy(rep + rep_len, data, len); - - /* And fix up length information */ - rep_len += len; - /* No longer need textual representation */ dom_string_unref(tr); - } - } -#undef CHUNK + /* Finished with previous value */ + dom_string_unref(value); - /* Create DOMString */ - err = dom_string_create_from_ptr(a->owner, rep, rep_len, result); - if (err != DOM_NO_ERR) { - dom_document_alloc(a->owner, rep, 0); - return err; + /* Claim new value */ + value = temp; + } } - /* Cleanup */ - dom_document_alloc(a->owner, rep, 0); + *result = value; return DOM_NO_ERR; } |