summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/attr.c120
-rw-r--r--src/core/entity_ref.c22
-rw-r--r--src/core/entity_ref.h3
3 files changed, 142 insertions, 3 deletions
diff --git a/src/core/attr.c b/src/core/attr.c
index 31c9d94..6200ab1 100644
--- a/src/core/attr.c
+++ b/src/core/attr.c
@@ -6,6 +6,7 @@
*/
#include <stddef.h>
+#include <string.h>
#include <dom/core/attr.h>
#include <dom/core/document.h>
@@ -13,6 +14,7 @@
#include "core/attr.h"
#include "core/document.h"
+#include "core/entity_ref.h"
#include "core/node.h"
#include "utils/utils.h"
@@ -176,12 +178,124 @@ dom_exception dom_attr_get_specified(struct dom_attr *attr, bool *result)
dom_exception dom_attr_get_value(struct dom_attr *attr,
struct dom_string **result)
{
- UNUSED(attr);
- UNUSED(result);
+ struct dom_node *a = (struct dom_node *) attr;
+ struct dom_node *c;
+ uint8_t *rep;
+ size_t rep_len;
+ size_t rep_alloc;
+ 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;
/* 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);
+ if (err != DOM_NO_ERR) {
+ dom_document_alloc(a->owner, rep, 0);
+ 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;
+ } 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);
+ return err;
+ }
+
+ err = dom_string_get_data(tr, &data, &len);
+ if (err != DOM_NO_ERR) {
+ dom_string_unref(tr);
+ dom_document_alloc(a->owner, rep, 0);
+ 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);
+ }
+ }
- return DOM_NOT_SUPPORTED_ERR;
+#undef CHUNK
+
+ /* 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;
+ }
+
+ /* Cleanup */
+ dom_document_alloc(a->owner, rep, 0);
+
+ return DOM_NO_ERR;
}
/**
diff --git a/src/core/entity_ref.c b/src/core/entity_ref.c
index 8382249..bf4868b 100644
--- a/src/core/entity_ref.c
+++ b/src/core/entity_ref.c
@@ -8,6 +8,7 @@
#include "core/document.h"
#include "core/entity_ref.h"
#include "core/node.h"
+#include "utils/utils.h"
/**
* A DOM entity reference
@@ -97,3 +98,24 @@ void dom_entity_reference_destroy(struct dom_document *doc,
/* Destroy fragment */
dom_document_alloc(doc, entity, 0);
}
+
+/**
+ * Get the textual representation of an EntityReference
+ *
+ * \param entity The entity reference to get the textual representation of
+ * \param result Pointer to location to receive result
+ * \return DOM_NO_ERR on success.
+ *
+ * The returned string will have its reference count increased. It is
+ * the responsibility of the caller to unref the string once it has
+ * finished with it.
+ */
+dom_exception dom_entity_reference_get_textual_representation(
+ struct dom_entity_reference *entity, struct dom_string **result)
+{
+ UNUSED(entity);
+ UNUSED(result);
+
+ return DOM_NOT_SUPPORTED_ERR;
+}
+
diff --git a/src/core/entity_ref.h b/src/core/entity_ref.h
index 047ff30..fa03737 100644
--- a/src/core/entity_ref.h
+++ b/src/core/entity_ref.h
@@ -21,4 +21,7 @@ dom_exception dom_entity_reference_create(struct dom_document *doc,
void dom_entity_reference_destroy(struct dom_document *doc,
struct dom_entity_reference *entity);
+dom_exception dom_entity_reference_get_textual_representation(
+ struct dom_entity_reference *entity,
+ struct dom_string **result);
#endif