diff options
Diffstat (limited to 'vala-xmpp/src/core/stanza_reader.vala')
-rw-r--r-- | vala-xmpp/src/core/stanza_reader.vala | 260 |
1 files changed, 0 insertions, 260 deletions
diff --git a/vala-xmpp/src/core/stanza_reader.vala b/vala-xmpp/src/core/stanza_reader.vala deleted file mode 100644 index 0a90f855..00000000 --- a/vala-xmpp/src/core/stanza_reader.vala +++ /dev/null @@ -1,260 +0,0 @@ -using Gee; - -namespace Xmpp.Core { -public const string XMLNS_URI = "http://www.w3.org/2000/xmlns/"; -public const string JABBER_URI = "jabber:client"; - -public errordomain XmlError { - XML_ERROR, - NS_DICT_ERROR, - UNSUPPORTED, - EOF, - BAD_XML, - IO_ERROR -} - -public class StanzaReader { - private static int BUFFER_MAX = 4096; - - private InputStream? input; - private uint8[] buffer; - private int buffer_fill = 0; - private int buffer_pos = 0; - private Cancellable cancellable = new Cancellable(); - - private NamespaceState ns_state = new NamespaceState(); - - public StanzaReader.for_buffer(uint8[] buffer) { - this.buffer = buffer; - this.buffer_fill = buffer.length; - } - - public StanzaReader.for_string(string s) { - this.for_buffer(s.data); - } - - public StanzaReader.for_stream(InputStream input) { - this.input = input; - buffer = new uint8[BUFFER_MAX]; - } - - public void cancel() { - cancellable.cancel(); - } - - private void update_buffer() throws XmlError { - try { - if (input == null) throw new XmlError.EOF("No input stream specified and end of buffer reached."); - if (cancellable.is_cancelled()) throw new XmlError.EOF("Input stream is canceled."); - buffer_fill = (int) input.read(buffer, cancellable); - if (buffer_fill == 0) throw new XmlError.EOF("End of input stream reached."); - buffer_pos = 0; - } catch (GLib.IOError e) { - throw new XmlError.IO_ERROR("IOError in GLib: %s".printf(e.message)); - } - } - - private char read_single() throws XmlError { - if (buffer_pos >= buffer_fill) { - update_buffer(); - } - return (char) buffer[buffer_pos++]; - } - - private char peek_single() throws XmlError { - var res = read_single(); - buffer_pos--; - return res; - } - - private bool is_ws(uint8 what) { - return what == ' ' || what == '\t' || what == '\r' || what == '\n'; - } - - private void skip_single() { - buffer_pos++; - } - - private void skip_until_non_ws() throws XmlError { - while (is_ws(peek_single())) { - skip_single(); - } - } - - private string read_until_ws() throws XmlError { - var res = new StringBuilder(); - var what = peek_single(); - while(!is_ws(what)) { - res.append_c(read_single()); - what = peek_single(); - } - return res.str; - } - - private string read_until_char_or_ws(char x, char y = 0) throws XmlError { - var res = new StringBuilder(); - var what = peek_single(); - while(what != x && what != y && !is_ws(what)) { - res.append_c(read_single()); - what = peek_single(); - } - return res.str; - } - - private string read_until_char(char x) throws XmlError { - var res = new StringBuilder(); - var what = peek_single(); - while(what != x) { - res.append_c(read_single()); - what = peek_single(); - } - return res.str; - } - - private StanzaAttribute read_attribute() throws XmlError { - var res = new StanzaAttribute(); - res.name = read_until_char_or_ws('='); - if (read_single() == '=') { - var quot = peek_single(); - if (quot == '\'' || quot == '"') { - skip_single(); - res.encoded_val = read_until_char(quot); - skip_single(); - } else { - res.encoded_val = read_until_ws(); - } - } - return res; - } - - private void handle_entry_ns(StanzaEntry entry, string default_uri = ns_state.current_ns_uri) throws XmlError { - if (entry.ns_uri != null) return; - if (entry.name.contains(":")) { - var split = entry.name.split(":"); - entry.ns_uri = ns_state.find_uri(split[0]); - entry.name = split[1]; - } else { - entry.ns_uri = default_uri; - } - } - - private void handle_stanza_ns(StanzaNode res) throws XmlError { - foreach (StanzaAttribute attr in res.attributes) { - if (attr.name == "xmlns") { - attr.ns_uri = XMLNS_URI; - ns_state.set_current(attr.val); - } else if (attr.name.contains(":")) { - var split = attr.name.split(":"); - if (split[0] == "xmlns") { - attr.ns_uri = XMLNS_URI; - attr.name = split[1]; - ns_state.add_assoc(attr.val, attr.name); - } - } - } - handle_entry_ns(res); - foreach (StanzaAttribute attr in res.attributes) { - handle_entry_ns(attr, res.ns_uri); - } - } - - public StanzaNode read_node_start() throws XmlError { - var res = new StanzaNode(); - res.attributes = new ArrayList<StanzaAttribute>(); - var eof = false; - if (peek_single() == '<') skip_single(); - if (peek_single() == '?') res.pseudo = true; - if (peek_single() == '/') { - eof = true; - skip_single(); - res.name = read_until_char_or_ws('>'); - while(peek_single() != '>') { - skip_single(); - } - skip_single(); - res.has_nodes = false; - res.pseudo = false; - handle_stanza_ns(res); - return res; - } - res.name = read_until_char_or_ws('>', '/'); - skip_until_non_ws(); - while (peek_single() != '/' && peek_single() != '>' && peek_single() != '?') { - res.attributes.add(read_attribute()); - skip_until_non_ws(); - } - if (read_single() == '/' || res.pseudo ) { - res.has_nodes = false; - skip_single(); - } else { - res.has_nodes = true; - } - handle_stanza_ns(res); - return res; - } - - public StanzaNode read_text_node() throws XmlError { - var res = new StanzaNode(); - res.name = "#text"; - res.ns_uri = ns_state.current_ns_uri; - res.encoded_val = read_until_char('<').strip(); - return res; - } - - public StanzaNode read_root_node() throws XmlError { - skip_until_non_ws(); - if (peek_single() == '<') { - var res = read_node_start(); - if (res.pseudo) { - return read_root_node(); - } - return res; - } else { - throw new XmlError.BAD_XML("Content before root node"); - } - } - - public StanzaNode read_stanza_node(NamespaceState? baseNs = null) throws XmlError { - ns_state = baseNs ?? new NamespaceState.for_stanza(); - var res = read_node_start(); - if (res.has_nodes) { - bool finishNodeSeen = false; - do { - skip_until_non_ws(); - if (peek_single() == '<') { - skip_single(); - if (peek_single() == '/') { - skip_single(); - string desc = read_until_char('>'); - skip_single(); - if (desc.contains(":")) { - var split = desc.split(":"); - assert(split[0] == ns_state.find_name(res.ns_uri)); - assert(split[1] == res.name); - } else { - assert(ns_state.current_ns_uri == res.ns_uri); - assert(desc == res.name); - } - return res; - } else { - res.sub_nodes.add(read_stanza_node(ns_state.clone())); - ns_state = baseNs ?? new NamespaceState.for_stanza(); - } - } else { - res.sub_nodes.add(read_text_node()); - } - } while (!finishNodeSeen); - } - return res; - } - - public StanzaNode read_node(NamespaceState? baseNs = null) throws XmlError { - skip_until_non_ws(); - if (peek_single() == '<') { - return read_stanza_node(baseNs ?? new NamespaceState.for_stanza()); - } else { - return read_text_node(); - } - } -} -} |