[gxml/newattr: 5/13] NamedNodeMap.vala: add NamedMap interface and the NamedAttrMap implementation; may change NamedMap t
- From: Richard Hans Schwarting <rschwart src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml/newattr: 5/13] NamedNodeMap.vala: add NamedMap interface and the NamedAttrMap implementation; may change NamedMap t
- Date: Tue, 22 Oct 2013 06:56:10 +0000 (UTC)
commit a09942f908f426db133c588c7f20b475eb9b5ca8
Author: Richard Schwarting <aquarichy gmail com>
Date: Tue Oct 22 02:43:25 2013 -0400
NamedNodeMap.vala: add NamedMap interface and the NamedAttrMap implementation; may change NamedMap to
NamedNodeMap yet; this will replace the GLib.HashTable usage for GXml.Node.attributes, and will allow us to
rip out all the GXml<>libxml2 syncing code that occurs, since our NamedAttrMap will update the underlying
libxml2 structures immediately when changes occur
gxml/NamedNodeMap.vala | 130 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 130 insertions(+), 0 deletions(-)
---
diff --git a/gxml/NamedNodeMap.vala b/gxml/NamedNodeMap.vala
new file mode 100644
index 0000000..23f58a1
--- /dev/null
+++ b/gxml/NamedNodeMap.vala
@@ -0,0 +1,130 @@
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* Node.vala
+ *
+ * Copyright (C) 2011-2013 Richard Schwarting <aquarichy gmail com>
+ * Copyright (C) 2011 Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Richard Schwarting <aquarichy gmail com>
+ */
+
+using GXml;
+
+namespace GXml {
+ public interface NamedNodeMap<T> : GLib.Object {
+ // TODO: consider adding lookup, remove, etc from GLib.HashTable as convenience API
+ // TODO: figure out how to let people do attributes["pie"] for attributes.get_named_item
("pie"); GLib HashTables can do it
+
+ public abstract T get_named_item (string name);
+ public abstract T set_named_item (T item);
+ public abstract T remove_named_item (string name);
+ public abstract T item (ulong index);
+ public abstract ulong length {
+ get;
+ private set;
+ }
+ }
+
+ public class NamedAttrMap : GLib.Object, NamedNodeMap<Attr?> {
+ private Element elem;
+
+ internal NamedAttrMap (Element e) {
+ this.elem = e;
+ }
+
+ public Attr? get_named_item (string name) {
+ Xml.Attr *prop = this.elem.node->has_prop (name);
+ return this.elem.owner_document.lookup_attr (prop);
+ }
+
+ public Attr? set_named_item (Attr? item) {
+ Xml.Attr *prop;
+ Attr old;
+
+ /* TODO: INUSE_ATTRIBUTE_ERR if new_attr already belongs to
+ another element */
+ this.elem.check_read_only ();
+ this.elem.check_wrong_document (item);
+
+ /* we take a clone, because libxml2 recycles xmlAttrs apparently(?),
+ and we'd just return the old xmlAttr but with the new values */
+ old = this.get_named_item (item.node_name);
+ if (old != null) {
+ old = (GXml.Attr)old.clone_node (true);
+ }
+
+ /* TODO: instead of using item.node_value, which uses child_nodes
+ and iterates over them, use xmlNodeListGetString () */
+ this.elem.node->set_prop (item.node_name, item.node_value);
+
+ return old;
+ }
+
+ public Attr? remove_named_item (string name) {
+ Attr clone;
+ Attr old;
+
+ old = this.get_named_item (name);
+ if (old == null) {
+ GXml.warning (DomException.NOT_FOUND,
+ "No child with name '%s' exists in node '%s'".printf (name,
this.elem.node_name));
+ return null;
+ } else {
+ /* Get a clone, because libxml2's xmlRemoveProp frees an
+ * Attrs memory, and we still want to return a copy */
+ clone = (Attr)old.clone_node (true);
+ /* TODO: implement cloning for Attrs; may need to clone a
+ * new xmlAttr, all so Attrs can exist outside
+ * of an Element (will we need an out of tree
+ * placeholder Element?) THANKS DOM :( */
+ this.elem.node->has_prop (name)->remove ();
+ /* TODO: embed Xml.Attr into GXml.Attr; but then when we
+ * remove xmlAttrs, because they'll be freed from
+ * memory, we need to invalidate any GXml.Attrs that
+ * hold them (which we can find using doc.lookup_attr()
+ */
+ return clone;
+ }
+ }
+
+ public Attr? item (ulong index) {
+ Xml.Attr *attr;
+
+ attr = this.elem.node->properties;
+ for (int i = 0; i < index && attr != null; i++) {
+ attr = attr->next;
+ }
+
+ if (attr == null) {
+ return null;
+ } else {
+ return this.elem.owner_document.lookup_attr (attr);
+ }
+ }
+
+ public ulong length {
+ get {
+ int len = 0;
+ for (Xml.Attr *attr = this.elem.node->properties; attr != null; attr =
attr->next) {
+ len++;
+ }
+ return len;
+ }
+ private set {
+ }
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]