summaryrefslogtreecommitdiff
path: root/src/core/node.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/node.h')
-rw-r--r--src/core/node.h144
1 files changed, 124 insertions, 20 deletions
diff --git a/src/core/node.h b/src/core/node.h
index 27c9f35..68776da 100644
--- a/src/core/node.h
+++ b/src/core/node.h
@@ -10,7 +10,12 @@
#include <stdbool.h>
+#include <libwapcaplet/libwapcaplet.h>
+
#include <dom/core/node.h>
+#include <dom/functypes.h>
+
+#include "utils/list.h"
/**
* User data context attached to a DOM node
@@ -23,6 +28,23 @@ struct dom_user_data {
struct dom_user_data *next; /**< Next in list */
struct dom_user_data *prev; /**< Previous in list */
};
+typedef struct dom_user_data dom_user_data;
+
+/**
+ * The internally used virtual function table.
+ */
+typedef struct dom_node_protect_vtable {
+
+ void (*destroy)(dom_node_internal *n);
+ /**< The destroy virtual function, it
+ * should be private to client */
+ dom_exception (*alloc)(struct dom_document *doc,
+ dom_node_internal *n, dom_node_internal **ret);
+ /**< Allocate the memory of the new Node */
+ dom_exception (*copy)(dom_node_internal *new, dom_node_internal *old);
+ /**< Copy the old to new as well as
+ * all its attributes, but not its children */
+} dom_node_protect_vtable;
/**
* The real DOM node object
@@ -31,13 +53,11 @@ struct dom_user_data {
*/
struct dom_node_internal {
struct dom_node base; /**< The vtable base */
- void (*destroy)(dom_node_internal *n);
- /**< The destroy vitual function, it
- * should be privated to client */
+ void *vtable; /**< The protected vtable */
- struct dom_string *name; /**< Node name (this is the local part
- * of a QName in the cases where a
- * namespace exists) */
+ struct lwc_string_s *name; /**< Node name (this is the local part
+ * of a QName in the cases where a
+ * namespace exists) */
struct dom_string *value; /**< Node value */
dom_node_type type; /**< Node type */
dom_node_internal *parent; /**< Parent node */
@@ -48,27 +68,37 @@ struct dom_node_internal {
struct dom_document *owner; /**< Owning document */
- struct dom_string *namespace; /**< Namespace URI */
- struct dom_string *prefix; /**< Namespace prefix */
+ struct lwc_string_s *namespace; /**< Namespace URI */
+ struct lwc_string_s *prefix; /**< Namespace prefix */
struct dom_user_data *user_data; /**< User data list */
uint32_t refcnt; /**< Reference count */
+
+ struct list_entry pending_list; /**< The document delete pending list */
};
-dom_node_internal * dom_node_create(struct dom_document *doc);
+dom_node_internal * _dom_node_create(struct dom_document *doc);
-dom_exception dom_node_initialise(struct dom_node_internal *node,
+dom_exception _dom_node_initialise(struct dom_node_internal *node,
struct dom_document *doc, dom_node_type type,
- struct dom_string *name, struct dom_string *value,
- struct dom_string *namespace, struct dom_string *prefix);
+ struct lwc_string_s *name, struct dom_string *value,
+ struct lwc_string_s *namespace, struct lwc_string_s *prefix);
-void dom_node_finalise(struct dom_document *doc, dom_node_internal *node);
+dom_exception _dom_node_initialise_generic(
+ struct dom_node_internal *node, struct dom_document *doc,
+ dom_alloc alloc, void *pw, struct lwc_context_s *ctx,
+ dom_node_type type, struct lwc_string_s *name,
+ struct dom_string *value, struct lwc_string_s *namespace,
+ struct lwc_string_s *prefix);
+
+void _dom_node_finalise(struct dom_document *doc, dom_node_internal *node);
+void _dom_node_finalise_generic(dom_node_internal *node, dom_alloc alloc,
+ void *pw, struct lwc_context_s *ctx);
bool _dom_node_readonly(const dom_node_internal *node);
/* The DOM Node's vtable methods */
-void _dom_node_destroy(struct dom_node_internal *node);
dom_exception _dom_node_get_node_name(dom_node_internal *node,
struct dom_string **result);
dom_exception _dom_node_get_node_value(dom_node_internal *node,
@@ -110,7 +140,7 @@ dom_exception _dom_node_clone_node(dom_node_internal *node, bool deep,
dom_node_internal **result);
dom_exception _dom_node_normalize(dom_node_internal *node);
dom_exception _dom_node_is_supported(dom_node_internal *node,
- struct dom_string *feature, dom_node_internal *version,
+ struct dom_string *feature, struct dom_string *version,
bool *result);
dom_exception _dom_node_get_namespace(dom_node_internal *node,
struct dom_string **result);
@@ -129,8 +159,8 @@ dom_exception _dom_node_get_text_content(dom_node_internal *node,
struct dom_string **result);
dom_exception _dom_node_set_text_content(dom_node_internal *node,
struct dom_string *content);
-dom_exception _dom_node_is_same(dom_node_internal *node, dom_node_internal *other,
- bool *result);
+dom_exception _dom_node_is_same(dom_node_internal *node,
+ dom_node_internal *other, bool *result);
dom_exception _dom_node_lookup_prefix(dom_node_internal *node,
struct dom_string *namespace, struct dom_string **result);
dom_exception _dom_node_is_default_namespace(dom_node_internal *node,
@@ -188,11 +218,85 @@ dom_exception _dom_node_get_user_data(dom_node_internal *node,
_dom_node_get_user_data
+/* Following comes the protected vtable */
+void _dom_node_destroy(struct dom_node_internal *node);
+dom_exception _dom_node_alloc(struct dom_document *doc,
+ struct dom_node_internal *n, struct dom_node_internal **ret);
+dom_exception _dom_node_copy(struct dom_node_internal *new,
+ struct dom_node_internal *old);
+
+#define DOM_NODE_PROTECT_VTABLE \
+ _dom_node_destroy, \
+ _dom_node_alloc, \
+ _dom_node_copy
+
+
/* The destroy API should be used inside DOM module */
-static inline void dom_node_destroy(struct dom_node *node)
+static inline void dom_node_destroy(struct dom_node_internal *node)
+{
+ ((dom_node_protect_vtable *) node->vtable)->destroy(node);
+}
+#define dom_node_destroy(n) dom_node_destroy((dom_node_internal *) (n))
+
+/* Allocate the Node */
+static inline dom_exception dom_node_alloc(struct dom_document *doc,
+ struct dom_node_internal *n, struct dom_node_internal **ret)
+{
+ return ((dom_node_protect_vtable *) n->vtable)->alloc(doc, n, ret);
+}
+#define dom_node_alloc(d,n,r) dom_node_alloc((struct dom_document *) (d), \
+ (dom_node_internal *) (n), (dom_node_internal **) (r))
+
+
+/* Copy the Node old to new */
+static inline dom_exception dom_node_copy(struct dom_node_internal *new,
+ struct dom_node_internal *old)
{
- ((dom_node_internal *) node)->destroy((dom_node_internal *) node);
+ return ((dom_node_protect_vtable *) old->vtable)->copy(new, old);
}
-#define dom_node_destroy(n) dom_node_destroy((dom_node *) (n))
+#define dom_node_copy(n,o) dom_node_copy((dom_node_internal *) (n), \
+ (dom_node_internal *) (o))
+
+/* Following are some helper functions */
+#define dom_node_get_owner(n) ((dom_node_internal *) (n))->owner
+
+#define dom_node_set_owner(n, d) ((dom_node_internal *) (n))->owner = \
+ (struct dom_document *) (d)
+
+#define dom_node_get_parent(n) ((dom_node_internal *) (n))->parent
+
+#define dom_node_set_parent(n, p) ((dom_node_internal *) (n))->parent = \
+ (dom_node_internal *) (p)
+
+#define dom_node_get_refcount(n) ((dom_node_internal *) (n))->refcnt
+
+dom_exception _redocument_lwcstring(lwc_context *old, lwc_context *new,
+ lwc_string **string);
+dom_exception _redocument_domstring(struct dom_document *old,
+ struct dom_document* new, struct dom_string **string);
+dom_exception _dom_merge_adjacent_text(dom_node_internal *p,
+ dom_node_internal *n);
+/* Used to extract the lwc_string from dom_string.
+ * If there is no lwc_string inside the param, create one use the node->owner
+ * as document */
+dom_exception _dom_node_get_intern_string(dom_node_internal *node,
+ struct dom_string *str, struct lwc_string_s **intern);
+void _dom_node_unref_intern_string(dom_node_internal *node,
+ struct lwc_string_s *inter);
+
+/* Try to destroy the node, if its refcnt is not zero, then append it to the
+ * owner document's pending list */
+void _dom_node_try_destroy(dom_node_internal *node);
+#define dom_node_try_destroy(n) _dom_node_try_destroy((dom_node_internal *) (n))
+
+/* To add some node to the pending list */
+void _dom_node_mark_pending(dom_node_internal *node);
+#define dom_node_mark_pending(n) _dom_node_mark_pending(\
+ (dom_node_internal *) (n))
+/* To remove the node from the pending list, this may happen when
+ * a node is removed and then appended to another parent */
+void _dom_node_remove_pending(dom_node_internal *node);
+#define dom_node_remove_pending(n) _dom_node_remove_pending(\
+ (dom_node_internal *) (n))
#endif