/libxnoise/SimpleMarkup/xnoise-markup-node.vala
https://code.google.com/p/xnoise/ · Vala · 499 lines · 397 code · 63 blank · 39 comment · 138 complexity · 4873fbf8fa226c8be61f5fd179c6693d MD5 · raw file
- /* simple-xml-node.vala
- *
- * Copyright (C) 2010 J??rn Magens
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The Xnoise authors hereby grant permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Xnoise. This permission is above and beyond the permissions granted
- * by the GPL license by which Xnoise is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Author:
- * J??rn Magens
- */
- namespace Xnoise.SimpleMarkup {
- public class Node {
- // Represents a xml node. Can contain more nodes, text and attributes
- // For convenient usage with vala iteration
- private unowned Node _parent;
- private unowned Node? _previous = null;
- private Node? _next = null;
- private int _children_count = 0;
-
- private string? _name = null;
- public Attributes attributes = new Attributes();
- public Node(string? name) {
- this._name = name;
- }
-
- public string? text { get; set; default = null; }
- public string? name { get { return _name; } }
- public Node? parent { get { return _parent; } }
- public Node? previous { get { return _previous; } }
- public Node? next { get { return _next; } }
- public class Attributes {
-
- private GLib.HashTable<string, string> table =
- new GLib.HashTable<string, string>(str_hash, str_equal);
-
- public Keys keys;
-
- public Attributes() {
- keys = new Keys(this);
- }
- ~Attributes() {
- table.remove_all();
- table = null;
- }
-
- public class Keys {
- private unowned Attributes attrib;
-
- public Keys(Attributes _attrib) {
- attrib = _attrib;
- }
-
- public bool contains(string needle_key) {
- foreach(string current_key in attrib.key_list) {
- if(str_equal(needle_key, current_key))
- return true;
- }
- return false;
- }
-
- public Iterator iterator() {
- return new Iterator(this.attrib);
- }
-
- public class Iterator {
- private unowned Attributes iter_attib;
- private List<unowned string> key_list = null;
- private unowned List<string> curr_key;
-
- public Iterator(Attributes _iter_attib) {
- this.iter_attib = _iter_attib;
- }
-
- public bool next() {
- if(this.key_list == null) {
- this.key_list = iter_attib.key_list;
- if(this.key_list == null)
- return false;
- this.curr_key = this.key_list.first();
-
- if(this.curr_key.data != null)
- return true;
- else
- return false;
- }
- else {
- if(this.curr_key.next == null)
- return false;
-
- this.curr_key = this.curr_key.next;
- return true;
- }
- }
-
- public string? get() {
- if(this.curr_key == null)
- return null;
- return this.curr_key.data;
- }
- }
- }
- public void add(string key, string val) {
- assert(table != null);
- table.insert(key, val);
- }
-
- public void replace(string key, string val) {
- assert(table != null);
- table.replace(key, val);
- }
-
- public void remove(string key) {
- assert(table != null);
- table.remove(key);
- }
-
- public void clear() {
- assert(table != null);
- table.remove_all();
- }
-
- public int item_count {
- get {
- return (int)table.size();
- }
- }
- public List<unowned string> key_list {
- owned get {
- return table.get_keys();
- }
- }
- public List<unowned string> value_list {
- owned get {
- return table.get_values();
- }
- }
- public string? get(string key) {
- return table.lookup(key);
- }
- public void set(string key, string? val) {
- if(val == null) {
- table.remove(key);
- }
- else {
- table.insert(key, val);
- }
- }
- }
-
- public bool has_text() {
- return this.text != null;
- }
-
- public bool has_children() {
- return _children_count > 0 && this._first != null;
- }
- public bool has_attributes() {
- return attributes.item_count > 0;
- }
- private Node? _first = null;
- private unowned Node? _last = null;
- public int children_count {
- get {
- return this._children_count;
- }
- }
- public void prepend_child(Node node) {
- assert(node.parent == null);
- node._parent = this;
- if(this._first == null && this._last == null) {
- this._first = node;
- this._last = node;
- this._children_count++;
- }
- else {
- this.insert_child(0, node);
- }
- return;
- }
- public void append_child(Node node) {
- assert(node.parent == null);
- node._parent = this;
- if(this._first == null && this._last == null) {
- this._first = node;
- this._last = node;
- }
- else {
- this._last._next = node;
- node._previous = this._last;
- this._last = node;
- }
- this._children_count++;
- return;
- }
- public void insert_child(int pos, Node node) {
- assert(node.parent == null);
- node._parent = this;
- if(pos < 0) {
- pos = this._children_count - 1 - pos;
- assert(pos >= 0);
- }
-
- if(pos > this._children_count) {
- this.append_child(node);
- }
- else if(pos == 0) {
- node._next = this._first;
- this._first._previous = node;
- this._first = node;
- this._children_count++;
- }
- else {
- Node prev = this._first;
- int i = 0;
- while(i < pos - 1) {
- i++;
- prev = prev.next;
- }
- node._previous = prev;
- node._next = prev.next;
- node.next._previous = node;
- prev._next = node;
- this._children_count++;
- }
- }
-
- // returns the first appearance only !!!
- //TODO: method that returns all children with a certain name
- public unowned Node? get_child_by_name(string childname) {
- foreach(unowned Node n in this) {
- if(n.name == childname)
- return n;
- }
- return null;
- }
-
- public Node[] get_children_by_name(string childname) {
- Node[] nds = {};
- foreach(unowned Node n in this) {
- if(n.name == childname)
- nds += n;
- }
- return nds;
- }
- public int get_idx_of_child(Node node) {
- int idx = -1;
- foreach(Node n in this) {
- if(&n == &node) { //adress compare
- return idx;
- }
- idx++;
- }
- return idx;
- }
- //get node by index; don't use this to iterate over list
- public unowned Node? get(int idx) {
- if(idx > (this._children_count - 1))
- return null;
-
- unowned Node? nd = null;;
- if(idx == 0) {
- nd = this._first;
- }
- else if(idx == this._children_count - 1) {
- nd = this._last;
- }
- else if(idx <= this._children_count / 2) { //start from begin
- nd = this._first;
- int i = 0;
- while(i != idx) {
- nd = nd.next;
- i++;
- }
- }
- else { //start from end
- nd = this._last;
- for (int i = this._children_count - 1; i != idx; i--) {
- nd = nd.previous;
- }
- }
- //check if we have a container
- if(nd == null)
- return null;
- else
- return nd;
- }
- //simply overwrite the Node
- public void set(int idx, Node node) {
- assert(node.parent == null);
- node._parent = this;
- if(idx > (this._children_count - 1))
- return; //should I put a warning here?
-
- unowned Node? nd = null;;
- if(idx == 0) {
- nd = this._first;
- }
- else if(idx == this._children_count - 1) {
- nd = this._last;
- }
- else if(idx <= this._children_count / 2) { //start from begin
- int i = 0;
- nd = this._first;
- while(i != idx) {
- nd = nd.next;
- i++;
- }
- }
- else { //start from end
- int i = this._children_count - 1;
- nd = this._last;
- while(i != idx) {
- nd = nd.previous;
- i--;
- }
- }
- return_if_fail(nd != null);
-
- Node prev = nd.previous;
- Node nxt = nd.next;
-
- node._previous = prev;
- node._next = prev.next;
- if(nxt != null)
- nxt._previous = node;
- if(prev != null)
- prev._next = node;
- if(nd == this._first)
- this._first = node;
- if(nd == this._last)
- this._last = node;
- }
- public bool remove_child(Node node) {
- int idx = get_idx_of_child(node);
- if(idx >= 0) {
- return remove_child_at_idx(idx);
- }
- else {
- return false;
- }
- }
-
- public bool remove_child_at_idx(int idx) {
- if(idx > (this._children_count - 1))
- return false;
-
- unowned Node? nd = null;;
- if(idx == 0) {
- nd = this._first;
- }
- else if(idx == this._children_count - 1) {
- nd = this._last;
- }
- else if(idx <= this._children_count / 2) { //start from begin
- nd = this._first;
- int i = 0;
- while(i != idx) {
- nd = nd.next;
- i++;
- }
- }
- else { //start from end
- nd = this._last;
- for(int i = this._children_count - 1; i != idx; i--) {
- nd = nd.previous;
- }
- }
- //check if we have a container
- if(nd == null)
- return false;
- //put the list parts together
- if(nd == this._first) {
- this._first = nd.next;
- }
- if(nd == this._last) {
- this._last = nd.previous;
- }
- if(nd.previous != null) {
- nd.previous._next = nd.next;
- }
- if(nd.next != null) {
- nd.next._previous = nd.previous;
- }
- nd._previous = null;
- nd._next = null;
- this._children_count--;
- return true;
- }
-
- public void clear() {
- this._first = this._last = null;
- this._children_count = 0;
- }
- public Iterator iterator() {
- return new Iterator(this);
- }
- public class Iterator {
- private bool started = false; //set to first item on first iteration
- private bool removed = false;
- private unowned Node parent_node;
- private int _index;
- //a pointer to the current child for the Iterator of the node
- private unowned Node? current_child;
- public Iterator(Node parent_node) {
- this.parent_node = parent_node;
- this.current_child = null;
- this._index = -1;
- }
- public bool next() {
- if(this.removed && this.current_child != null) {
- this.removed = false;
- return true;
- }
- else if(!this.started && this.parent_node._first != null) {
- this.started = true;
- this.current_child = this.parent_node._first;
- this._index++;
- return true;
- }
- else if(this.current_child != null && this.current_child.next != null) {
- this.current_child = this.current_child.next;
- this._index++;
- return true;
- }
- return false;
- }
- public unowned Node get() {
- assert(this.current_child != null);
- return this.current_child;
- }
- public void set(Node node) {
- assert(this.current_child != null);
-
- Node? prev = this.current_child.previous;
- Node? nxt = this.current_child.next;
-
- node._previous = prev;
- node._next = prev.next;
- if(nxt != null)
- nxt._previous = node;
- if(prev != null)
- prev._next = node;
- if(this.current_child == this.parent_node._first)
- this.parent_node._first = node;
- if(this.current_child == this.parent_node._last)
- this.parent_node._last = node;
- }
- }
- }
- }