summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/jingle/libjingle/talk/xmllite
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/xmllite')
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/Makefile.am18
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.cc167
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.h87
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.cc151
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.h79
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.cc65
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.h61
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.cc491
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.h231
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.cc205
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.h62
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.cc250
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.h108
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.cc190
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.h49
15 files changed, 2214 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/Makefile.am b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/Makefile.am
new file mode 100644
index 00000000..1e7abcfd
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/Makefile.am
@@ -0,0 +1,18 @@
+libcricketxmllite_la_SOURCES = qname.cc \
+ xmlbuilder.cc \
+ xmlconstants.cc \
+ xmlelement.cc \
+ xmlnsstack.cc \
+ xmlparser.cc \
+ xmlprinter.cc
+
+noinst_HEADERS = qname.h \
+ xmlbuilder.h \
+ xmlconstants.h \
+ xmlelement.h \
+ xmlnsstack.h \
+ xmlparser.h \
+ xmlprinter.h
+AM_CPPFLAGS = -DPOSIX -I$(srcdir)/../..
+
+noinst_LTLIBRARIES = libcricketxmllite.la
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.cc
new file mode 100644
index 00000000..626cfa96
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.cc
@@ -0,0 +1,167 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+#include "talk/base/common.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/qname.h"
+#include "talk/xmllite/xmlconstants.h"
+
+//#define new TRACK_NEW
+
+namespace buzz {
+
+static int QName_Hash(const std::string & ns, const char * local) {
+ int result = ns.size() * 101;
+ while (*local) {
+ result *= 19;
+ result += *local;
+ local += 1;
+ }
+ return result;
+}
+
+static const int bits = 9;
+static QName::Data * get_qname_table() {
+ static QName::Data qname_table[1 << bits];
+ return qname_table;
+}
+
+static QName::Data *
+AllocateOrFind(const std::string & ns, const char * local) {
+ int index = QName_Hash(ns, local);
+ int increment = index >> (bits - 1) | 1;
+ QName::Data * qname_table = get_qname_table();
+ for (;;) {
+ index &= ((1 << bits) - 1);
+ if (!qname_table[index].Occupied()) {
+ return new QName::Data(ns, local);
+ }
+ if (qname_table[index].localPart_ == local &&
+ qname_table[index].namespace_ == ns) {
+ qname_table[index].AddRef();
+ return qname_table + index;
+ }
+ index += increment;
+ }
+}
+
+static QName::Data *
+Add(const std::string & ns, const char * local) {
+ int index = QName_Hash(ns, local);
+ int increment = index >> (bits - 1) | 1;
+ QName::Data * qname_table = get_qname_table();
+ for (;;) {
+ index &= ((1 << bits) - 1);
+ if (!qname_table[index].Occupied()) {
+ qname_table[index].namespace_ = ns;
+ qname_table[index].localPart_ = local;
+ qname_table[index].AddRef(); // AddRef twice so it's never deleted
+ qname_table[index].AddRef();
+ return qname_table + index;
+ }
+ if (qname_table[index].localPart_ == local &&
+ qname_table[index].namespace_ == ns) {
+ qname_table[index].AddRef();
+ return qname_table + index;
+ }
+ index += increment;
+ }
+}
+
+QName::~QName() {
+ data_->Release();
+}
+
+QName::QName() : data_(QN_EMPTY.data_) {
+ data_->AddRef();
+}
+
+QName::QName(bool add, const std::string & ns, const char * local) :
+ data_(add ? Add(ns, local) : AllocateOrFind(ns, local)) {}
+
+QName::QName(bool add, const std::string & ns, const std::string & local) :
+ data_(add ? Add(ns, local.c_str()) : AllocateOrFind(ns, local.c_str())) {}
+
+QName::QName(const std::string & ns, const char * local) :
+ data_(AllocateOrFind(ns, local)) {}
+
+static std::string
+QName_LocalPart(const std::string & name) {
+ size_t i = name.rfind(':');
+ if (i == std::string::npos)
+ return name;
+ return name.substr(i + 1);
+}
+
+static std::string
+QName_Namespace(const std::string & name) {
+ size_t i = name.rfind(':');
+ if (i == std::string::npos)
+ return STR_EMPTY;
+ return name.substr(0, i);
+}
+
+QName::QName(const std::string & mergedOrLocal) :
+ data_(AllocateOrFind(QName_Namespace(mergedOrLocal),
+ QName_LocalPart(mergedOrLocal).c_str())) {}
+
+std::string
+QName::Merged() const {
+ if (data_->namespace_ == STR_EMPTY)
+ return data_->localPart_;
+
+ std::string result(data_->namespace_);
+ result.reserve(result.length() + 1 + data_->localPart_.length());
+ result += ':';
+ result += data_->localPart_;
+ return result;
+}
+
+bool
+QName::operator==(const QName & other) const {
+ return other.data_ == data_ ||
+ data_->localPart_ == other.data_->localPart_ &&
+ data_->namespace_ == other.data_->namespace_;
+}
+
+int
+QName::Compare(const QName & other) const {
+ if (data_ == other.data_)
+ return 0;
+
+ int result = data_->localPart_.compare(other.data_->localPart_);
+ if (result)
+ return result;
+
+ return data_->namespace_.compare(other.data_->namespace_);
+}
+
+}
+
+
+
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.h
new file mode 100644
index 00000000..b1bcec61
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/qname.h
@@ -0,0 +1,87 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _qname_h_
+#define _qname_h_
+
+#include <string>
+
+namespace buzz {
+
+
+class QName
+{
+public:
+ explicit QName();
+ QName(const QName & qname) : data_(qname.data_) { data_->AddRef(); }
+ explicit QName(bool add, const std::string & ns, const char * local);
+ explicit QName(bool add, const std::string & ns, const std::string & local);
+ explicit QName(const std::string & ns, const char * local);
+ explicit QName(const std::string & mergedOrLocal);
+ QName & operator=(const QName & qn) {
+ qn.data_->AddRef();
+ data_->Release();
+ data_ = qn.data_;
+ return *this;
+ }
+ ~QName();
+
+ const std::string & Namespace() const { return data_->namespace_; }
+ const std::string & LocalPart() const { return data_->localPart_; }
+ std::string Merged() const;
+ int Compare(const QName & other) const;
+ bool operator==(const QName & other) const;
+ bool operator!=(const QName & other) const { return !operator==(other); }
+ bool operator<(const QName & other) const { return Compare(other) < 0; }
+
+ class Data {
+ public:
+ Data(const std::string & ns, const std::string & local) :
+ refcount_(1),
+ namespace_(ns),
+ localPart_(local) {}
+
+ Data() : refcount_(0) {}
+
+ std::string namespace_;
+ std::string localPart_;
+ void AddRef() { refcount_++; }
+ void Release() { if (!--refcount_) { delete this; } }
+ bool Occupied() { return !!refcount_; }
+
+ private:
+ int refcount_;
+ };
+
+private:
+ Data * data_;
+};
+
+
+}
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.cc
new file mode 100644
index 00000000..313c4013
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.cc
@@ -0,0 +1,151 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/stl_decl.h"
+#include <vector>
+#include <set>
+#include <expat.h>
+#include "talk/base/common.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/xmlbuilder.h"
+
+#define new TRACK_NEW
+
+namespace buzz {
+
+XmlBuilder::XmlBuilder() :
+ pelCurrent_(NULL),
+ pelRoot_(NULL),
+ pvParents_(new std::vector<XmlElement *>()) {
+}
+
+void
+XmlBuilder::Reset() {
+ pelRoot_.reset();
+ pelCurrent_ = NULL;
+ pvParents_->clear();
+}
+
+XmlElement *
+XmlBuilder::BuildElement(XmlParseContext * pctx,
+ const char * name, const char ** atts) {
+ QName tagName(pctx->ResolveQName(name, false));
+ if (tagName == QN_EMPTY)
+ return NULL;
+
+ XmlElement * pelNew = new XmlElement(tagName);
+
+ if (!*atts)
+ return pelNew;
+
+ std::set<QName> seenNonlocalAtts;
+
+ while (*atts) {
+ QName attName(pctx->ResolveQName(*atts, true));
+ if (attName == QN_EMPTY) {
+ delete pelNew;
+ return NULL;
+ }
+
+ // verify that namespaced names are unique
+ if (!attName.Namespace().empty()) {
+ if (seenNonlocalAtts.count(attName)) {
+ delete pelNew;
+ return NULL;
+ }
+ seenNonlocalAtts.insert(attName);
+ }
+
+ pelNew->AddAttr(attName, std::string(*(atts + 1)));
+ atts += 2;
+ }
+
+ return pelNew;
+}
+
+void
+XmlBuilder::StartElement(XmlParseContext * pctx,
+ const char * name, const char ** atts) {
+ XmlElement * pelNew = BuildElement(pctx, name, atts);
+ if (pelNew == NULL) {
+ pctx->RaiseError(XML_ERROR_SYNTAX);
+ return;
+ }
+
+ if (!pelCurrent_) {
+ pelCurrent_ = pelNew;
+ pelRoot_.reset(pelNew);
+ pvParents_->push_back(NULL);
+ } else {
+ pelCurrent_->AddElement(pelNew);
+ pvParents_->push_back(pelCurrent_);
+ pelCurrent_ = pelNew;
+ }
+}
+
+void
+XmlBuilder::EndElement(XmlParseContext * pctx, const char * name) {
+ UNUSED(pctx);
+ UNUSED(name);
+ pelCurrent_ = pvParents_->back();
+ pvParents_->pop_back();
+}
+
+void
+XmlBuilder::CharacterData(XmlParseContext * pctx,
+ const char * text, int len) {
+ UNUSED(pctx);
+ if (pelCurrent_) {
+ pelCurrent_->AddParsedText(text, len);
+ }
+}
+
+void
+XmlBuilder::Error(XmlParseContext * pctx, XML_Error err) {
+ UNUSED(pctx);
+ UNUSED(err);
+ pelRoot_.reset(NULL);
+ pelCurrent_ = NULL;
+ pvParents_->clear();
+}
+
+XmlElement *
+XmlBuilder::CreateElement() {
+ return pelRoot_.release();
+}
+
+XmlElement *
+XmlBuilder::BuiltElement() {
+ return pelRoot_.get();
+}
+
+XmlBuilder::~XmlBuilder() {
+}
+
+
+
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.h
new file mode 100644
index 00000000..b5b1be59
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlbuilder.h
@@ -0,0 +1,79 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _xmlbuilder_h_
+#define _xmlbuilder_h_
+
+#include <string>
+#include "talk/base/scoped_ptr.h"
+#include "talk/base/stl_decl.h"
+#include "talk/xmllite/xmlparser.h"
+
+#ifdef OSX
+#include "talk/third_party/expat/expat.h"
+#else
+#include <expat.h>
+#endif
+
+namespace buzz {
+
+class XmlElement;
+class XmlParseContext;
+
+
+class XmlBuilder : public XmlParseHandler {
+public:
+ XmlBuilder();
+
+ static XmlElement * BuildElement(XmlParseContext * pctx,
+ const char * name, const char ** atts);
+ virtual void StartElement(XmlParseContext * pctx,
+ const char * name, const char ** atts);
+ virtual void EndElement(XmlParseContext * pctx, const char * name);
+ virtual void CharacterData(XmlParseContext * pctx,
+ const char * text, int len);
+ virtual void Error(XmlParseContext * pctx, XML_Error);
+ virtual ~XmlBuilder();
+
+ void Reset();
+
+ // Take ownership of the built element; second call returns NULL
+ XmlElement * CreateElement();
+
+ // Peek at the built element without taking ownership
+ XmlElement * BuiltElement();
+
+private:
+ XmlElement * pelCurrent_;
+ scoped_ptr<XmlElement> pelRoot_;
+ scoped_ptr<std::vector<XmlElement *, std::allocator<XmlElement *> > >
+ pvParents_;
+};
+
+}
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.cc
new file mode 100644
index 00000000..503f832f
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.cc
@@ -0,0 +1,65 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "xmlconstants.h"
+
+using namespace buzz;
+
+const std::string & XmlConstants::str_empty() {
+ static const std::string str_empty_;
+ return str_empty_;
+}
+
+const std::string & XmlConstants::ns_xml() {
+ static const std::string ns_xml_("http://www.w3.org/XML/1998/namespace");
+ return ns_xml_;
+}
+
+const std::string & XmlConstants::ns_xmlns() {
+ static const std::string ns_xmlns_("http://www.w3.org/2000/xmlns/");
+ return ns_xmlns_;
+}
+
+const std::string & XmlConstants::str_xmlns() {
+ static const std::string str_xmlns_("xmlns");
+ return str_xmlns_;
+}
+
+const std::string & XmlConstants::str_xml() {
+ static const std::string str_xml_("xml");
+ return str_xml_;
+}
+
+const std::string & XmlConstants::str_version() {
+ static const std::string str_version_("version");
+ return str_version_;
+}
+
+const std::string & XmlConstants::str_encoding() {
+ static const std::string str_encoding_("encoding");
+ return str_encoding_;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.h
new file mode 100644
index 00000000..8514d6f4
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlconstants.h
@@ -0,0 +1,61 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Because global constant initialization order is undefined
+// globals cannot depend on other objects to be instantiated.
+// This class creates string objects within static methods
+// such that globals may refer to these constants by the
+// accessor function and they are guaranteed to be initialized.
+
+#ifndef TALK_XMLLITE_CONSTANTS_H_
+#define TALK_XMLLITE_CONSTANTS_H_
+
+#include <string>
+
+#define STR_EMPTY XmlConstants::str_empty()
+#define NS_XML XmlConstants::ns_xml()
+#define NS_XMLNS XmlConstants::ns_xmlns()
+#define STR_XMLNS XmlConstants::str_xmlns()
+#define STR_XML XmlConstants::str_xml()
+#define STR_VERSION XmlConstants::str_version()
+#define STR_ENCODING XmlConstants::str_encoding()
+namespace buzz {
+
+class XmlConstants {
+ public:
+ static const std::string & str_empty();
+ static const std::string & ns_xml();
+ static const std::string & ns_xmlns();
+ static const std::string & str_xmlns();
+ static const std::string & str_xml();
+ static const std::string & str_version();
+ static const std::string & str_encoding();
+};
+
+}
+
+#endif // TALK_XMLLITE_CONSTANTS_H_
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.cc
new file mode 100644
index 00000000..d3619a92
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.cc
@@ -0,0 +1,491 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string>
+#include <iostream>
+#include <vector>
+#include <sstream>
+
+#include "talk/base/common.h"
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/qname.h"
+#include "talk/xmllite/xmlparser.h"
+#include "talk/xmllite/xmlbuilder.h"
+#include "talk/xmllite/xmlprinter.h"
+#include "talk/xmllite/xmlconstants.h"
+
+#define new TRACK_NEW
+
+namespace buzz {
+
+const QName QN_EMPTY(true, STR_EMPTY, STR_EMPTY);
+const QName QN_XMLNS(true, STR_EMPTY, STR_XMLNS);
+
+
+XmlChild::~XmlChild() {
+}
+
+bool
+XmlText::IsTextImpl() const {
+ return true;
+}
+
+XmlElement *
+XmlText::AsElementImpl() const {
+ return NULL;
+}
+
+XmlText *
+XmlText::AsTextImpl() const {
+ return const_cast<XmlText *>(this);
+}
+
+void
+XmlText::SetText(const std::string & text) {
+ text_ = text;
+}
+
+void
+XmlText::AddParsedText(const char * buf, int len) {
+ text_.append(buf, len);
+}
+
+void
+XmlText::AddText(const std::string & text) {
+ text_ += text;
+}
+
+XmlText::~XmlText() {
+}
+
+XmlElement::XmlElement(const QName & name) :
+ name_(name),
+ pFirstAttr_(NULL),
+ pLastAttr_(NULL),
+ pFirstChild_(NULL),
+ pLastChild_(NULL) {
+}
+
+XmlElement::XmlElement(const XmlElement & elt) :
+ XmlChild(),
+ name_(elt.name_),
+ pFirstAttr_(NULL),
+ pLastAttr_(NULL),
+ pFirstChild_(NULL),
+ pLastChild_(NULL) {
+
+ // copy attributes
+ XmlAttr * pAttr;
+ XmlAttr ** ppLastAttr = &pFirstAttr_;
+ XmlAttr * newAttr = NULL;
+ for (pAttr = elt.pFirstAttr_; pAttr; pAttr = pAttr->NextAttr()) {
+ newAttr = new XmlAttr(*pAttr);
+ *ppLastAttr = newAttr;
+ ppLastAttr = &(newAttr->pNextAttr_);
+ }
+ pLastAttr_ = newAttr;
+
+ // copy children
+ XmlChild * pChild;
+ XmlChild ** ppLast = &pFirstChild_;
+ XmlChild * newChild = NULL;
+
+ for (pChild = elt.pFirstChild_; pChild; pChild = pChild->NextChild()) {
+ if (pChild->IsText()) {
+ newChild = new XmlText(*(pChild->AsText()));
+ } else {
+ newChild = new XmlElement(*(pChild->AsElement()));
+ }
+ *ppLast = newChild;
+ ppLast = &(newChild->pNextChild_);
+ }
+ pLastChild_ = newChild;
+
+}
+
+XmlElement::XmlElement(const QName & name, bool useDefaultNs) :
+ name_(name),
+ pFirstAttr_(useDefaultNs ? new XmlAttr(QN_XMLNS, name.Namespace()) : NULL),
+ pLastAttr_(pFirstAttr_),
+ pFirstChild_(NULL),
+ pLastChild_(NULL) {
+}
+
+bool
+XmlElement::IsTextImpl() const {
+ return false;
+}
+
+XmlElement *
+XmlElement::AsElementImpl() const {
+ return const_cast<XmlElement *>(this);
+}
+
+XmlText *
+XmlElement::AsTextImpl() const {
+ return NULL;
+}
+
+const std::string &
+XmlElement::BodyText() const {
+ if (pFirstChild_ && pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
+ return pFirstChild_->AsText()->Text();
+ }
+
+ return STR_EMPTY;
+}
+
+void
+XmlElement::SetBodyText(const std::string & text) {
+ if (text == STR_EMPTY) {
+ ClearChildren();
+ } else if (pFirstChild_ == NULL) {
+ AddText(text);
+ } else if (pFirstChild_->IsText() && pLastChild_ == pFirstChild_) {
+ pFirstChild_->AsText()->SetText(text);
+ } else {
+ ClearChildren();
+ AddText(text);
+ }
+}
+
+const QName &
+XmlElement::FirstElementName() const {
+ const XmlElement * element = FirstElement();
+ if (element == NULL)
+ return QN_EMPTY;
+ return element->Name();
+}
+
+XmlAttr *
+XmlElement::FirstAttr() {
+ return pFirstAttr_;
+}
+
+const std::string &
+XmlElement::Attr(const QName & name) const {
+ XmlAttr * pattr;
+ for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
+ if (pattr->name_ == name)
+ return pattr->value_;
+ }
+ return STR_EMPTY;
+}
+
+bool
+XmlElement::HasAttr(const QName & name) const {
+ XmlAttr * pattr;
+ for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
+ if (pattr->name_ == name)
+ return true;
+ }
+ return false;
+}
+
+void
+XmlElement::SetAttr(const QName & name, const std::string & value) {
+ XmlAttr * pattr;
+ for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
+ if (pattr->name_ == name)
+ break;
+ }
+ if (!pattr) {
+ pattr = new XmlAttr(name, value);
+ if (pLastAttr_)
+ pLastAttr_->pNextAttr_ = pattr;
+ else
+ pFirstAttr_ = pattr;
+ pLastAttr_ = pattr;
+ return;
+ }
+ pattr->value_ = value;
+}
+
+void
+XmlElement::ClearAttr(const QName & name) {
+ XmlAttr * pattr;
+ XmlAttr *pLastAttr = NULL;
+ for (pattr = pFirstAttr_; pattr; pattr = pattr->pNextAttr_) {
+ if (pattr->name_ == name)
+ break;
+ pLastAttr = pattr;
+ }
+ if (!pattr)
+ return;
+ if (!pLastAttr)
+ pFirstAttr_ = pattr->pNextAttr_;
+ else
+ pLastAttr->pNextAttr_ = pattr->pNextAttr_;
+ if (pLastAttr_ == pattr)
+ pLastAttr_ = pLastAttr;
+ delete pattr;
+}
+
+XmlChild *
+XmlElement::FirstChild() {
+ return pFirstChild_;
+}
+
+XmlElement *
+XmlElement::FirstElement() {
+ XmlChild * pChild;
+ for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText())
+ return pChild->AsElement();
+ }
+ return NULL;
+}
+
+XmlElement *
+XmlElement::NextElement() {
+ XmlChild * pChild;
+ for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText())
+ return pChild->AsElement();
+ }
+ return NULL;
+}
+
+XmlElement *
+XmlElement::FirstWithNamespace(const std::string & ns) {
+ XmlChild * pChild;
+ for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
+ return pChild->AsElement();
+ }
+ return NULL;
+}
+
+XmlElement *
+XmlElement::NextWithNamespace(const std::string & ns) {
+ XmlChild * pChild;
+ for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
+ return pChild->AsElement();
+ }
+ return NULL;
+}
+
+XmlElement *
+XmlElement::FirstNamed(const QName & name) {
+ XmlChild * pChild;
+ for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText() && pChild->AsElement()->Name() == name)
+ return pChild->AsElement();
+ }
+ return NULL;
+}
+
+XmlElement *
+XmlElement::NextNamed(const QName & name) {
+ XmlChild * pChild;
+ for (pChild = pNextChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText() && pChild->AsElement()->Name() == name)
+ return pChild->AsElement();
+ }
+ return NULL;
+}
+
+const std::string &
+XmlElement::TextNamed(const QName & name) const {
+ XmlChild * pChild;
+ for (pChild = pFirstChild_; pChild; pChild = pChild->pNextChild_) {
+ if (!pChild->IsText() && pChild->AsElement()->Name() == name)
+ return pChild->AsElement()->BodyText();
+ }
+ return STR_EMPTY;
+}
+
+void
+XmlElement::InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNext) {
+ if (pPredecessor == NULL) {
+ pNext->pNextChild_ = pFirstChild_;
+ pFirstChild_ = pNext;
+ }
+ else {
+ pNext->pNextChild_ = pPredecessor->pNextChild_;
+ pPredecessor->pNextChild_ = pNext;
+ }
+}
+
+void
+XmlElement::RemoveChildAfter(XmlChild * pPredecessor) {
+ XmlChild * pNext;
+
+ if (pPredecessor == NULL) {
+ pNext = pFirstChild_;
+ pFirstChild_ = pNext->pNextChild_;
+ }
+ else {
+ pNext = pPredecessor->pNextChild_;
+ pPredecessor->pNextChild_ = pNext->pNextChild_;
+ }
+
+ if (pLastChild_ == pNext)
+ pLastChild_ = pPredecessor;
+
+ delete pNext;
+}
+
+void
+XmlElement::AddAttr(const QName & name, const std::string & value) {
+ ASSERT(!HasAttr(name));
+
+ XmlAttr ** pprev = pLastAttr_ ? &(pLastAttr_->pNextAttr_) : &pFirstAttr_;
+ pLastAttr_ = (*pprev = new XmlAttr(name, value));
+}
+
+void
+XmlElement::AddAttr(const QName & name, const std::string & value,
+ int depth) {
+ XmlElement * element = this;
+ while (depth--) {
+ element = element->pLastChild_->AsElement();
+ }
+ element->AddAttr(name, value);
+}
+
+void
+XmlElement::AddParsedText(const char * cstr, int len) {
+ if (len == 0)
+ return;
+
+ if (pLastChild_ && pLastChild_->IsText()) {
+ pLastChild_->AsText()->AddParsedText(cstr, len);
+ return;
+ }
+ XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
+ pLastChild_ = *pprev = new XmlText(cstr, len);
+}
+
+void
+XmlElement::AddText(const std::string & text) {
+ if (text == STR_EMPTY)
+ return;
+
+ if (pLastChild_ && pLastChild_->IsText()) {
+ pLastChild_->AsText()->AddText(text);
+ return;
+ }
+ XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
+ pLastChild_ = *pprev = new XmlText(text);
+}
+
+void
+XmlElement::AddText(const std::string & text, int depth) {
+ // note: the first syntax is ambigious for msvc 6
+ // XmlElement * pel(this);
+ XmlElement * element = this;
+ while (depth--) {
+ element = element->pLastChild_->AsElement();
+ }
+ element->AddText(text);
+}
+
+void
+XmlElement::AddElement(XmlElement *pelChild) {
+ if (pelChild == NULL)
+ return;
+
+ XmlChild ** pprev = pLastChild_ ? &(pLastChild_->pNextChild_) : &pFirstChild_;
+ pLastChild_ = *pprev = pelChild;
+ pelChild->pNextChild_ = NULL;
+}
+
+void
+XmlElement::AddElement(XmlElement *pelChild, int depth) {
+ XmlElement * element = this;
+ while (depth--) {
+ element = element->pLastChild_->AsElement();
+ }
+ element->AddElement(pelChild);
+}
+
+void
+XmlElement::ClearNamedChildren(const QName & name) {
+ XmlChild * prev_child = NULL;
+ XmlChild * next_child;
+ XmlChild * child;
+ for (child = FirstChild(); child; child = next_child) {
+ next_child = child->NextChild();
+ if (!child->IsText() && child->AsElement()->Name() == name)
+ {
+ RemoveChildAfter(prev_child);
+ continue;
+ }
+ prev_child = child;
+ }
+}
+
+void
+XmlElement::ClearChildren() {
+ XmlChild * pchild;
+ for (pchild = pFirstChild_; pchild; ) {
+ XmlChild * pToDelete = pchild;
+ pchild = pchild->pNextChild_;
+ delete pToDelete;
+ }
+ pFirstChild_ = pLastChild_ = NULL;
+}
+
+std::string
+XmlElement::Str() const {
+ std::stringstream ss;
+ Print(&ss, NULL, 0);
+ return ss.str();
+}
+
+XmlElement *
+XmlElement::ForStr(const std::string & str) {
+ XmlBuilder builder;
+ XmlParser::ParseXml(&builder, str);
+ return builder.CreateElement();
+}
+
+void
+XmlElement::Print(
+ std::ostream * pout, std::string xmlns[], int xmlnsCount) const {
+ XmlPrinter::PrintXml(pout, this, xmlns, xmlnsCount);
+}
+
+XmlElement::~XmlElement() {
+ XmlAttr * pattr;
+ for (pattr = pFirstAttr_; pattr; ) {
+ XmlAttr * pToDelete = pattr;
+ pattr = pattr->pNextAttr_;
+ delete pToDelete;
+ }
+
+ XmlChild * pchild;
+ for (pchild = pFirstChild_; pchild; ) {
+ XmlChild * pToDelete = pchild;
+ pchild = pchild->pNextChild_;
+ delete pToDelete;
+ }
+}
+
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.h
new file mode 100644
index 00000000..06545d89
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlelement.h
@@ -0,0 +1,231 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _xmlelement_h_
+#define _xmlelement_h_
+
+#include <iosfwd>
+#include <string>
+#include "talk/base/scoped_ptr.h"
+#include "talk/xmllite/qname.h"
+
+namespace buzz {
+
+extern const QName QN_EMPTY;
+extern const QName QN_XMLNS;
+
+
+class XmlChild;
+class XmlText;
+class XmlElement;
+class XmlAttr;
+
+class XmlChild {
+friend class XmlElement;
+
+public:
+
+ XmlChild * NextChild() { return pNextChild_; }
+ const XmlChild * NextChild() const { return pNextChild_; }
+
+ bool IsText() const { return IsTextImpl(); }
+
+ XmlElement * AsElement() { return AsElementImpl(); }
+ const XmlElement * AsElement() const { return AsElementImpl(); }
+
+ XmlText * AsText() { return AsTextImpl(); }
+ const XmlText * AsText() const { return AsTextImpl(); }
+
+
+protected:
+
+ XmlChild() :
+ pNextChild_(NULL) {
+ }
+
+ virtual bool IsTextImpl() const = 0;
+ virtual XmlElement * AsElementImpl() const = 0;
+ virtual XmlText * AsTextImpl() const = 0;
+
+
+ virtual ~XmlChild();
+
+private:
+ XmlChild(const XmlChild & noimpl);
+
+ XmlChild * pNextChild_;
+
+};
+
+class XmlText : public XmlChild {
+public:
+ explicit XmlText(const std::string & text) :
+ XmlChild(),
+ text_(text) {
+ }
+ explicit XmlText(const XmlText & t) :
+ XmlChild(),
+ text_(t.text_) {
+ }
+ explicit XmlText(const char * cstr, size_t len) :
+ XmlChild(),
+ text_(cstr, len) {
+ }
+ virtual ~XmlText();
+
+ const std::string & Text() const { return text_; }
+ void SetText(const std::string & text);
+ void AddParsedText(const char * buf, int len);
+ void AddText(const std::string & text);
+
+protected:
+ virtual bool IsTextImpl() const;
+ virtual XmlElement * AsElementImpl() const;
+ virtual XmlText * AsTextImpl() const;
+
+private:
+ std::string text_;
+};
+
+class XmlAttr {
+friend class XmlElement;
+
+public:
+ XmlAttr * NextAttr() const { return pNextAttr_; }
+ const QName & Name() const { return name_; }
+ const std::string & Value() const { return value_; }
+
+private:
+ explicit XmlAttr(const QName & name, const std::string & value) :
+ pNextAttr_(NULL),
+ name_(name),
+ value_(value) {
+ }
+ explicit XmlAttr(const XmlAttr & att) :
+ pNextAttr_(NULL),
+ name_(att.name_),
+ value_(att.value_) {
+ }
+
+ XmlAttr * pNextAttr_;
+ QName name_;
+ std::string value_;
+};
+
+class XmlElement : public XmlChild {
+public:
+ explicit XmlElement(const QName & name);
+ explicit XmlElement(const QName & name, bool useDefaultNs);
+ explicit XmlElement(const XmlElement & elt);
+
+ virtual ~XmlElement();
+
+ const QName & Name() const { return name_; }
+
+ const std::string & BodyText() const;
+ void SetBodyText(const std::string & text);
+
+ const QName & FirstElementName() const;
+
+ XmlAttr * FirstAttr();
+ const XmlAttr * FirstAttr() const
+ { return const_cast<XmlElement *>(this)->FirstAttr(); }
+
+ //! Attr will return STR_EMPTY if the attribute isn't there:
+ //! use HasAttr to test presence of an attribute.
+ const std::string & Attr(const QName & name) const;
+ bool HasAttr(const QName & name) const;
+ void SetAttr(const QName & name, const std::string & value);
+ void ClearAttr(const QName & name);
+
+ XmlChild * FirstChild();
+ const XmlChild * FirstChild() const
+ { return const_cast<XmlElement *>(this)->FirstChild(); }
+
+ XmlElement * FirstElement();
+ const XmlElement * FirstElement() const
+ { return const_cast<XmlElement *>(this)->FirstElement(); }
+
+ XmlElement * NextElement();
+ const XmlElement * NextElement() const
+ { return const_cast<XmlElement *>(this)->NextElement(); }
+
+ XmlElement * FirstWithNamespace(const std::string & ns);
+ const XmlElement * FirstWithNamespace(const std::string & ns) const
+ { return const_cast<XmlElement *>(this)->FirstWithNamespace(ns); }
+
+ XmlElement * NextWithNamespace(const std::string & ns);
+ const XmlElement * NextWithNamespace(const std::string & ns) const
+ { return const_cast<XmlElement *>(this)->NextWithNamespace(ns); }
+
+ XmlElement * FirstNamed(const QName & name);
+ const XmlElement * FirstNamed(const QName & name) const
+ { return const_cast<XmlElement *>(this)->FirstNamed(name); }
+
+ XmlElement * NextNamed(const QName & name);
+ const XmlElement * NextNamed(const QName & name) const
+ { return const_cast<XmlElement *>(this)->NextNamed(name); }
+
+ const std::string & TextNamed(const QName & name) const;
+
+ void InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNewChild);
+ void RemoveChildAfter(XmlChild * pPredecessor);
+
+ void AddParsedText(const char * buf, int len);
+ void AddText(const std::string & text);
+ void AddText(const std::string & text, int depth);
+ void AddElement(XmlElement * pelChild);
+ void AddElement(XmlElement * pelChild, int depth);
+ void AddAttr(const QName & name, const std::string & value);
+ void AddAttr(const QName & name, const std::string & value, int depth);
+ void ClearNamedChildren(const QName & name);
+ void ClearChildren();
+
+ static XmlElement * ForStr(const std::string & str);
+ std::string Str() const;
+
+ void Print(std::ostream * pout, std::string xmlns[], int xmlnsCount) const;
+
+protected:
+ virtual bool IsTextImpl() const;
+ virtual XmlElement * AsElementImpl() const;
+ virtual XmlText * AsTextImpl() const;
+
+private:
+ QName name_;
+ XmlAttr * pFirstAttr_;
+ XmlAttr * pLastAttr_;
+ XmlChild * pFirstChild_;
+ XmlChild * pLastChild_;
+
+};
+
+
+
+}
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.cc
new file mode 100644
index 00000000..4dcb6490
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.cc
@@ -0,0 +1,205 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/stl_decl.h"
+#include <string>
+#include <iostream>
+#include <vector>
+#include <sstream>
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/xmlnsstack.h"
+#include "talk/xmllite/xmlconstants.h"
+
+namespace buzz {
+
+XmlnsStack::XmlnsStack() :
+ pxmlnsStack_(new std::vector<std::string>),
+ pxmlnsDepthStack_(new std::vector<size_t>) {
+}
+
+XmlnsStack::~XmlnsStack() {}
+
+void
+XmlnsStack::PushFrame() {
+ pxmlnsDepthStack_->push_back(pxmlnsStack_->size());
+}
+
+void
+XmlnsStack::PopFrame() {
+ size_t prev_size = pxmlnsDepthStack_->back();
+ pxmlnsDepthStack_->pop_back();
+ if (prev_size < pxmlnsStack_->size()) {
+ pxmlnsStack_->erase(pxmlnsStack_->begin() + prev_size,
+ pxmlnsStack_->end());
+ }
+}
+const std::pair<std::string, bool> NS_NOT_FOUND(STR_EMPTY, false);
+const std::pair<std::string, bool> EMPTY_NS_FOUND(STR_EMPTY, true);
+const std::pair<std::string, bool> XMLNS_DEFINITION_FOUND(NS_XMLNS, true);
+
+const std::string *
+XmlnsStack::NsForPrefix(const std::string & prefix) {
+ if (prefix.length() >= 3 &&
+ (prefix[0] == 'x' || prefix[0] == 'X') &&
+ (prefix[1] == 'm' || prefix[1] == 'M') &&
+ (prefix[2] == 'l' || prefix[2] == 'L')) {
+ if (prefix == "xml")
+ return &(NS_XML);
+ if (prefix == "xmlns")
+ return &(NS_XMLNS);
+ return NULL;
+ }
+
+ std::vector<std::string>::iterator pos;
+ for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
+ pos -= 2;
+ if (*pos == prefix)
+ return &(*(pos + 1));
+ }
+
+ if (prefix == STR_EMPTY)
+ return &(STR_EMPTY); // default namespace
+
+ return NULL; // none found
+}
+
+bool
+XmlnsStack::PrefixMatchesNs(const std::string & prefix, const std::string & ns) {
+ const std::string * match = NsForPrefix(prefix);
+ if (match == NULL)
+ return false;
+ return (*match == ns);
+}
+
+std::pair<std::string, bool>
+XmlnsStack::PrefixForNs(const std::string & ns, bool isattr) {
+ if (ns == NS_XML)
+ return std::make_pair(std::string("xml"), true);
+ if (ns == NS_XMLNS)
+ return std::make_pair(std::string("xmlns"), true);
+ if (isattr ? ns == STR_EMPTY : PrefixMatchesNs(STR_EMPTY, ns))
+ return std::make_pair(STR_EMPTY, true);
+
+ std::vector<std::string>::iterator pos;
+ for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
+ pos -= 2;
+ if (*(pos + 1) == ns &&
+ (!isattr || !pos->empty()) && PrefixMatchesNs(*pos, ns))
+ return std::make_pair(*pos, true);
+ }
+
+ return std::make_pair(STR_EMPTY, false); // none found
+}
+
+std::string
+XmlnsStack::FormatQName(const QName & name, bool isAttr) {
+ std::string prefix(PrefixForNs(name.Namespace(), isAttr).first);
+ if (prefix == STR_EMPTY)
+ return name.LocalPart();
+ else
+ return prefix + ':' + name.LocalPart();
+}
+
+void
+XmlnsStack::AddXmlns(const std::string & prefix, const std::string & ns) {
+ pxmlnsStack_->push_back(prefix);
+ pxmlnsStack_->push_back(ns);
+}
+
+void
+XmlnsStack::RemoveXmlns() {
+ pxmlnsStack_->pop_back();
+ pxmlnsStack_->pop_back();
+}
+
+static bool IsAsciiLetter(char ch) {
+ return ((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z'));
+}
+
+static std::string AsciiLower(const std::string & s) {
+ std::string result(s);
+ size_t i;
+ for (i = 0; i < result.length(); i++) {
+ if (result[i] >= 'A' && result[i] <= 'Z')
+ result[i] += 'a' - 'A';
+ }
+ return result;
+}
+
+static std::string SuggestPrefix(const std::string & ns) {
+ size_t len = ns.length();
+ size_t i = ns.find_last_of('.');
+ if (i != std::string::npos && len - i <= 4 + 1)
+ len = i; // chop off ".html" or ".xsd" or ".?{0,4}"
+ size_t last = len;
+ while (last > 0) {
+ last -= 1;
+ if (IsAsciiLetter(ns[last])) {
+ size_t first = last;
+ last += 1;
+ while (first > 0) {
+ if (!IsAsciiLetter(ns[first - 1]))
+ break;
+ first -= 1;
+ }
+ if (last - first > 4)
+ last = first + 3;
+ std::string candidate(AsciiLower(ns.substr(first, last - first)));
+ if (candidate.find("xml") != 0)
+ return candidate;
+ break;
+ }
+ }
+ return "ns";
+}
+
+
+std::pair<std::string, bool>
+XmlnsStack::AddNewPrefix(const std::string & ns, bool isAttr) {
+ if (PrefixForNs(ns, isAttr).second)
+ return std::make_pair(STR_EMPTY, false);
+
+ std::string base(SuggestPrefix(ns));
+ std::string result(base);
+ int i = 2;
+ while (NsForPrefix(result) != NULL) {
+ std::stringstream ss;
+ ss << base;
+ ss << (i++);
+ ss >> result;
+ }
+ AddXmlns(result, ns);
+ return std::make_pair(result, true);
+}
+
+void XmlnsStack::Reset() {
+ pxmlnsStack_->clear();
+ pxmlnsDepthStack_->clear();
+}
+
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.h
new file mode 100644
index 00000000..299ec1ce
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlnsstack.h
@@ -0,0 +1,62 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _xmlnsstack_h_
+#define _xmlnsstack_h_
+
+#include <string>
+#include "talk/base/scoped_ptr.h"
+#include "talk/base/stl_decl.h"
+#include "talk/xmllite/qname.h"
+
+namespace buzz {
+
+class XmlnsStack {
+public:
+ XmlnsStack();
+ ~XmlnsStack();
+
+ void AddXmlns(const std::string & prefix, const std::string & ns);
+ void RemoveXmlns();
+ void PushFrame();
+ void PopFrame();
+ void Reset();
+
+ const std::string * NsForPrefix(const std::string & prefix);
+ bool PrefixMatchesNs(const std::string & prefix, const std::string & ns);
+ std::pair<std::string, bool> PrefixForNs(const std::string & ns, bool isAttr);
+ std::pair<std::string, bool> AddNewPrefix(const std::string & ns, bool isAttr);
+ std::string FormatQName(const QName & name, bool isAttr);
+
+private:
+
+ scoped_ptr<std::vector<std::string, std::allocator<std::string> > > pxmlnsStack_;
+ scoped_ptr<std::vector<size_t, std::allocator<size_t> > > pxmlnsDepthStack_;
+};
+}
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.cc
new file mode 100644
index 00000000..f2b56778
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.cc
@@ -0,0 +1,250 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/stl_decl.h"
+#include <string>
+#include <vector>
+#include <iostream>
+#include <expat.h>
+#include "talk/xmllite/xmlelement.h"
+#include "talk/base/common.h"
+#include "talk/xmllite/xmlparser.h"
+#include "talk/xmllite/xmlnsstack.h"
+#include "talk/xmllite/xmlconstants.h"
+
+#include <expat.h>
+
+#define new TRACK_NEW
+
+namespace buzz {
+
+
+static void
+StartElementCallback(void * userData, const char *name, const char **atts) {
+ (static_cast<XmlParser *>(userData))->ExpatStartElement(name, atts);
+}
+
+static void
+EndElementCallback(void * userData, const char *name) {
+ (static_cast<XmlParser *>(userData))->ExpatEndElement(name);
+}
+
+static void
+CharacterDataCallback(void * userData, const char *text, int len) {
+ (static_cast<XmlParser *>(userData))->ExpatCharacterData(text, len);
+}
+
+static void
+XmlDeclCallback(void * userData, const char * ver, const char * enc, int st) {
+ (static_cast<XmlParser *>(userData))->ExpatXmlDecl(ver, enc, st);
+}
+
+XmlParser::XmlParser(XmlParseHandler *pxph) :
+ context_(this), pxph_(pxph), sentError_(false) {
+ expat_ = XML_ParserCreate(NULL);
+ XML_SetUserData(expat_, this);
+ XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback);
+ XML_SetCharacterDataHandler(expat_, CharacterDataCallback);
+ XML_SetXmlDeclHandler(expat_, XmlDeclCallback);
+}
+
+void
+XmlParser::Reset() {
+ if (!XML_ParserReset(expat_, NULL)) {
+ XML_ParserFree(expat_);
+ expat_ = XML_ParserCreate(NULL);
+ }
+ XML_SetUserData(expat_, this);
+ XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback);
+ XML_SetCharacterDataHandler(expat_, CharacterDataCallback);
+ XML_SetXmlDeclHandler(expat_, XmlDeclCallback);
+ context_.Reset();
+ sentError_ = false;
+}
+
+static bool
+XmlParser_StartsWithXmlns(const char *name) {
+ return name[0] == 'x' &&
+ name[1] == 'm' &&
+ name[2] == 'l' &&
+ name[3] == 'n' &&
+ name[4] == 's';
+}
+
+void
+XmlParser::ExpatStartElement(const char *name, const char **atts) {
+ if (context_.RaisedError() != XML_ERROR_NONE)
+ return;
+ const char **att;
+ context_.StartElement();
+ for (att = atts; *att; att += 2) {
+ if (XmlParser_StartsWithXmlns(*att)) {
+ if ((*att)[5] == '\0') {
+ context_.StartNamespace("", *(att + 1));
+ }
+ else if ((*att)[5] == ':') {
+ if (**(att + 1) == '\0') {
+ // In XML 1.0 empty namespace illegal with prefix (not in 1.1)
+ context_.RaiseError(XML_ERROR_SYNTAX);
+ return;
+ }
+ context_.StartNamespace((*att) + 6, *(att + 1));
+ }
+ }
+ }
+ pxph_->StartElement(&context_, name, atts);
+}
+
+void
+XmlParser::ExpatEndElement(const char *name) {
+ if (context_.RaisedError() != XML_ERROR_NONE)
+ return;
+ context_.EndElement();
+ pxph_->EndElement(&context_, name);
+}
+
+void
+XmlParser::ExpatCharacterData(const char *text, int len) {
+ if (context_.RaisedError() != XML_ERROR_NONE)
+ return;
+ pxph_->CharacterData(&context_, text, len);
+}
+
+void
+XmlParser::ExpatXmlDecl(const char * ver, const char * enc, int standalone) {
+ if (context_.RaisedError() != XML_ERROR_NONE)
+ return;
+
+ if (ver && std::string("1.0") != ver) {
+ context_.RaiseError(XML_ERROR_SYNTAX);
+ return;
+ }
+
+ if (standalone == 0) {
+ context_.RaiseError(XML_ERROR_SYNTAX);
+ return;
+ }
+
+ if (enc && !((enc[0] == 'U' || enc[0] == 'u') &&
+ (enc[1] == 'T' || enc[1] == 't') &&
+ (enc[2] == 'F' || enc[2] == 'f') &&
+ enc[3] == '-' && enc[4] =='8')) {
+ context_.RaiseError(XML_ERROR_INCORRECT_ENCODING);
+ return;
+ }
+
+}
+
+bool
+XmlParser::Parse(const char *data, size_t len, bool isFinal) {
+ if (sentError_)
+ return false;
+
+ if (XML_Parse(expat_, data, static_cast<int>(len), isFinal) != XML_STATUS_OK)
+ context_.RaiseError(XML_GetErrorCode(expat_));
+
+ if (context_.RaisedError() != XML_ERROR_NONE) {
+ sentError_ = true;
+ pxph_->Error(&context_, context_.RaisedError());
+ return false;
+ }
+
+ return true;
+}
+
+XmlParser::~XmlParser() {
+ XML_ParserFree(expat_);
+}
+
+void
+XmlParser::ParseXml(XmlParseHandler *pxph, std::string text) {
+ XmlParser parser(pxph);
+ parser.Parse(text.c_str(), text.length(), true);
+}
+
+XmlParser::ParseContext::ParseContext(XmlParser *parser) :
+ parser_(parser),
+ xmlnsstack_(),
+ raised_(XML_ERROR_NONE) {
+}
+
+void
+XmlParser::ParseContext::StartNamespace(const char *prefix, const char *ns) {
+ xmlnsstack_.AddXmlns(
+ *prefix ? std::string(prefix) : STR_EMPTY,
+// ns == NS_CLIENT ? NS_CLIENT :
+// ns == NS_ROSTER ? NS_ROSTER :
+// ns == NS_GR ? NS_GR :
+ std::string(ns));
+}
+
+void
+XmlParser::ParseContext::StartElement() {
+ xmlnsstack_.PushFrame();
+}
+
+void
+XmlParser::ParseContext::EndElement() {
+ xmlnsstack_.PopFrame();
+}
+
+QName
+XmlParser::ParseContext::ResolveQName(const char *qname, bool isAttr) {
+ const char *c;
+ for (c = qname; *c; ++c) {
+ if (*c == ':') {
+ const std::string * result;
+ result = xmlnsstack_.NsForPrefix(std::string(qname, c - qname));
+ if (result == NULL)
+ return QN_EMPTY;
+ const char * localname = c + 1;
+ return QName(*result, localname);
+ }
+ }
+ if (isAttr) {
+ return QName(STR_EMPTY, qname);
+ }
+
+ const std::string * result;
+ result = xmlnsstack_.NsForPrefix(STR_EMPTY);
+ if (result == NULL)
+ return QN_EMPTY;
+
+ return QName(*result, qname);
+}
+
+void
+XmlParser::ParseContext::Reset() {
+ xmlnsstack_.Reset();
+ raised_ = XML_ERROR_NONE;
+}
+
+XmlParser::ParseContext::~ParseContext() {
+}
+
+}
+
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.h
new file mode 100644
index 00000000..760802e4
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlparser.h
@@ -0,0 +1,108 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _xmlparser_h_
+#define _xmlparser_h_
+
+#include <string>
+#include "talk/xmllite/xmlnsstack.h"
+#include <expat.h>
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct * XML_Parser;
+
+namespace buzz {
+
+class XmlParseHandler;
+class XmlParseContext;
+class XmlParser;
+
+class XmlParseContext {
+public:
+ virtual QName ResolveQName(const char * qname, bool isAttr) = 0;
+ virtual void RaiseError(XML_Error err) = 0;
+};
+
+class XmlParseHandler {
+public:
+ virtual void StartElement(XmlParseContext * pctx,
+ const char * name, const char ** atts) = 0;
+ virtual void EndElement(XmlParseContext * pctx,
+ const char * name) = 0;
+ virtual void CharacterData(XmlParseContext * pctx,
+ const char * text, int len) = 0;
+ virtual void Error(XmlParseContext * pctx,
+ XML_Error errorCode) = 0;
+};
+
+class XmlParser {
+public:
+ static void ParseXml(XmlParseHandler * pxph, std::string text);
+
+ explicit XmlParser(XmlParseHandler * pxph);
+ bool Parse(const char * data, size_t len, bool isFinal);
+ void Reset();
+ virtual ~XmlParser();
+
+ // expat callbacks
+ void ExpatStartElement(const char * name, const char ** atts);
+ void ExpatEndElement(const char * name);
+ void ExpatCharacterData(const char * text, int len);
+ void ExpatXmlDecl(const char * ver, const char * enc, int standalone);
+
+private:
+
+ class ParseContext : public XmlParseContext {
+ public:
+ ParseContext(XmlParser * parser);
+ virtual ~ParseContext();
+ virtual QName ResolveQName(const char * qname, bool isAttr);
+ virtual void RaiseError(XML_Error err) { if (!raised_) raised_ = err; }
+ XML_Error RaisedError() { return raised_; }
+ void Reset();
+
+ void StartElement();
+ void EndElement();
+ void StartNamespace(const char * prefix, const char * ns);
+
+ private:
+ const XmlParser * parser_;
+ XmlnsStack xmlnsstack_;
+ XML_Error raised_;
+ };
+
+ ParseContext context_;
+ XML_Parser expat_;
+ XmlParseHandler * pxph_;
+ bool sentError_;
+
+
+};
+
+}
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.cc b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.cc
new file mode 100644
index 00000000..892e2ebb
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.cc
@@ -0,0 +1,190 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/base/stl_decl.h"
+#include <string>
+#include <iostream>
+#include <vector>
+#include <sstream>
+#include "talk/xmllite/xmlelement.h"
+#include "talk/xmllite/xmlprinter.h"
+#include "talk/xmllite/xmlnsstack.h"
+#include "talk/xmllite/xmlconstants.h"
+
+namespace buzz {
+
+class XmlPrinterImpl {
+public:
+ XmlPrinterImpl(std::ostream * pout,
+ const std::string * const xmlns, int xmlnsCount);
+ void PrintElement(const XmlElement * element);
+ void PrintQuotedValue(const std::string & text);
+ void PrintBodyText(const std::string & text);
+
+private:
+ std::ostream *pout_;
+ XmlnsStack xmlnsStack_;
+};
+
+void
+XmlPrinter::PrintXml(std::ostream * pout, const XmlElement * element) {
+ PrintXml(pout, element, NULL, 0);
+}
+
+void
+XmlPrinter::PrintXml(std::ostream * pout, const XmlElement * element,
+ const std::string * const xmlns, int xmlnsCount) {
+ XmlPrinterImpl printer(pout, xmlns, xmlnsCount);
+ printer.PrintElement(element);
+}
+
+XmlPrinterImpl::XmlPrinterImpl(std::ostream * pout,
+ const std::string * const xmlns, int xmlnsCount) :
+ pout_(pout),
+ xmlnsStack_() {
+ int i;
+ for (i = 0; i < xmlnsCount; i += 2) {
+ xmlnsStack_.AddXmlns(xmlns[i], xmlns[i + 1]);
+ }
+}
+
+void
+XmlPrinterImpl::PrintElement(const XmlElement * element) {
+ xmlnsStack_.PushFrame();
+
+ // first go through attrs of pel to add xmlns definitions
+ const XmlAttr * pattr;
+ for (pattr = element->FirstAttr(); pattr; pattr = pattr->NextAttr()) {
+ if (pattr->Name() == QN_XMLNS)
+ xmlnsStack_.AddXmlns(STR_EMPTY, pattr->Value());
+ else if (pattr->Name().Namespace() == NS_XMLNS)
+ xmlnsStack_.AddXmlns(pattr->Name().LocalPart(),
+ pattr->Value());
+ }
+
+ // then go through qnames to make sure needed xmlns definitons are added
+ std::vector<std::string> newXmlns;
+ std::pair<std::string, bool> prefix;
+ prefix = xmlnsStack_.AddNewPrefix(element->Name().Namespace(), false);
+ if (prefix.second) {
+ newXmlns.push_back(prefix.first);
+ newXmlns.push_back(element->Name().Namespace());
+ }
+
+ for (pattr = element->FirstAttr(); pattr; pattr = pattr->NextAttr()) {
+ prefix = xmlnsStack_.AddNewPrefix(pattr->Name().Namespace(), true);
+ if (prefix.second) {
+ newXmlns.push_back(prefix.first);
+ newXmlns.push_back(element->Name().Namespace());
+ }
+ }
+
+ // print the element name
+ *pout_ << '<' << xmlnsStack_.FormatQName(element->Name(), false);
+
+ // and the attributes
+ for (pattr = element->FirstAttr(); pattr; pattr = pattr->NextAttr()) {
+ *pout_ << ' ' << xmlnsStack_.FormatQName(pattr->Name(), true) << "=\"";
+ PrintQuotedValue(pattr->Value());
+ *pout_ << '"';
+ }
+
+ // and the extra xmlns declarations
+ std::vector<std::string>::iterator i(newXmlns.begin());
+ while (i < newXmlns.end()) {
+ if (*i == STR_EMPTY)
+ *pout_ << " xmlns=\"" << *(i + 1) << '"';
+ else
+ *pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"';
+ i += 2;
+ }
+
+ // now the children
+ const XmlChild * pchild = element->FirstChild();
+
+ if (pchild == NULL)
+ *pout_ << "/>";
+ else {
+ *pout_ << '>';
+ while (pchild) {
+ if (pchild->IsText())
+ PrintBodyText(pchild->AsText()->Text());
+ else
+ PrintElement(pchild->AsElement());
+ pchild = pchild->NextChild();
+ }
+ *pout_ << "</" << xmlnsStack_.FormatQName(element->Name(), false) << '>';
+ }
+
+ xmlnsStack_.PopFrame();
+}
+
+void
+XmlPrinterImpl::PrintQuotedValue(const std::string & text) {
+ size_t safe = 0;
+ for (;;) {
+ size_t unsafe = text.find_first_of("<>&\"", safe);
+ if (unsafe == std::string::npos)
+ unsafe = text.length();
+ *pout_ << text.substr(safe, unsafe - safe);
+ if (unsafe == text.length())
+ return;
+ switch (text[unsafe]) {
+ case '<': *pout_ << "&lt;"; break;
+ case '>': *pout_ << "&gt;"; break;
+ case '&': *pout_ << "&amp;"; break;
+ case '"': *pout_ << "&quot;"; break;
+ }
+ safe = unsafe + 1;
+ if (safe == text.length())
+ return;
+ }
+}
+
+void
+XmlPrinterImpl::PrintBodyText(const std::string & text) {
+ size_t safe = 0;
+ for (;;) {
+ size_t unsafe = text.find_first_of("<>&", safe);
+ if (unsafe == std::string::npos)
+ unsafe = text.length();
+ *pout_ << text.substr(safe, unsafe - safe);
+ if (unsafe == text.length())
+ return;
+ switch (text[unsafe]) {
+ case '<': *pout_ << "&lt;"; break;
+ case '>': *pout_ << "&gt;"; break;
+ case '&': *pout_ << "&amp;"; break;
+ }
+ safe = unsafe + 1;
+ if (safe == text.length())
+ return;
+ }
+}
+
+
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.h
new file mode 100644
index 00000000..96900d0d
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/xmlprinter.h
@@ -0,0 +1,49 @@
+/*
+ * libjingle
+ * Copyright 2004--2005, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _xmlprinter_h_
+#define _xmlprinter_h_
+
+#include <iosfwd>
+#include <string>
+#include "talk/base/scoped_ptr.h"
+
+namespace buzz {
+
+class XmlElement;
+
+class XmlPrinter {
+public:
+ static void PrintXml(std::ostream * pout, const XmlElement * pelt);
+
+ static void PrintXml(std::ostream * pout, const XmlElement * pelt,
+ const std::string * const xmlns, int xmlnsCount);
+};
+
+}
+
+#endif