summaryrefslogtreecommitdiff
path: root/src/core/attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/attr.c')
-rw-r--r--src/core/attr.c104
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;
}