Removes xmllite from talk/xmllite since webrtc/xmllite is used instead.

BUG=3379
R=marpan@google.com

Review URL: https://webrtc-codereview.appspot.com/23039004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7436 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrike@webrtc.org 2014-10-13 18:27:11 +00:00
parent 8bee130fa0
commit 1e6a5dd14e
20 changed files with 0 additions and 3390 deletions

View File

@ -1,95 +0,0 @@
/*
* 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/xmllite/qname.h"
namespace buzz {
QName::QName() {
}
QName::QName(const QName& qname)
: namespace_(qname.namespace_),
local_part_(qname.local_part_) {
}
QName::QName(const StaticQName& const_value)
: namespace_(const_value.ns),
local_part_(const_value.local) {
}
QName::QName(const std::string& ns, const std::string& local)
: namespace_(ns),
local_part_(local) {
}
QName::QName(const std::string& merged_or_local) {
size_t i = merged_or_local.rfind(':');
if (i == std::string::npos) {
local_part_ = merged_or_local;
} else {
namespace_ = merged_or_local.substr(0, i);
local_part_ = merged_or_local.substr(i + 1);
}
}
QName::~QName() {
}
std::string QName::Merged() const {
if (namespace_[0] == '\0')
return local_part_;
std::string result;
result.reserve(namespace_.length() + 1 + local_part_.length());
result += namespace_;
result += ':';
result += local_part_;
return result;
}
bool QName::IsEmpty() const {
return namespace_.empty() && local_part_.empty();
}
int QName::Compare(const StaticQName& other) const {
int result = local_part_.compare(other.local);
if (result != 0)
return result;
return namespace_.compare(other.ns);
}
int QName::Compare(const QName& other) const {
int result = local_part_.compare(other.local_part_);
if (result != 0)
return result;
return namespace_.compare(other.namespace_);
}
} // namespace buzz

View File

@ -1,100 +0,0 @@
/*
* 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 TALK_XMLLITE_QNAME_H_
#define TALK_XMLLITE_QNAME_H_
#include <string>
namespace buzz {
class QName;
// StaticQName is used to represend constant quailified names. They
// can be initialized statically and don't need intializers code, e.g.
// const StaticQName QN_FOO = { "foo_namespace", "foo" };
//
// Beside this use case, QName should be used everywhere
// else. StaticQName instances are implicitly converted to QName
// objects.
struct StaticQName {
const char* const ns;
const char* const local;
bool operator==(const QName& other) const;
bool operator!=(const QName& other) const;
};
class QName {
public:
QName();
QName(const QName& qname);
QName(const StaticQName& const_value);
QName(const std::string& ns, const std::string& local);
explicit QName(const std::string& merged_or_local);
~QName();
const std::string& Namespace() const { return namespace_; }
const std::string& LocalPart() const { return local_part_; }
std::string Merged() const;
bool IsEmpty() const;
int Compare(const StaticQName& other) const;
int Compare(const QName& other) const;
bool operator==(const StaticQName& other) const {
return Compare(other) == 0;
}
bool operator==(const QName& other) const {
return Compare(other) == 0;
}
bool operator!=(const StaticQName& other) const {
return Compare(other) != 0;
}
bool operator!=(const QName& other) const {
return Compare(other) != 0;
}
bool operator<(const QName& other) const {
return Compare(other) < 0;
}
private:
std::string namespace_;
std::string local_part_;
};
inline bool StaticQName::operator==(const QName& other) const {
return other.Compare(*this) == 0;
}
inline bool StaticQName::operator!=(const QName& other) const {
return other.Compare(*this) != 0;
}
} // namespace buzz
#endif // TALK_XMLLITE_QNAME_H_

View File

@ -1,131 +0,0 @@
/*
* libjingle
* Copyright 2004, 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/xmllite/qname.h"
#include "webrtc/base/gunit.h"
using buzz::StaticQName;
using buzz::QName;
TEST(QNameTest, TestTrivial) {
QName name("test");
EXPECT_EQ(name.LocalPart(), "test");
EXPECT_EQ(name.Namespace(), "");
}
TEST(QNameTest, TestSplit) {
QName name("a:test");
EXPECT_EQ(name.LocalPart(), "test");
EXPECT_EQ(name.Namespace(), "a");
QName name2("a-very:long:namespace:test-this");
EXPECT_EQ(name2.LocalPart(), "test-this");
EXPECT_EQ(name2.Namespace(), "a-very:long:namespace");
}
TEST(QNameTest, TestMerge) {
QName name("a", "test");
EXPECT_EQ(name.LocalPart(), "test");
EXPECT_EQ(name.Namespace(), "a");
EXPECT_EQ(name.Merged(), "a:test");
QName name2("a-very:long:namespace", "test-this");
EXPECT_EQ(name2.LocalPart(), "test-this");
EXPECT_EQ(name2.Namespace(), "a-very:long:namespace");
EXPECT_EQ(name2.Merged(), "a-very:long:namespace:test-this");
}
TEST(QNameTest, TestAssignment) {
QName name("a", "test");
// copy constructor
QName namecopy(name);
EXPECT_EQ(namecopy.LocalPart(), "test");
EXPECT_EQ(namecopy.Namespace(), "a");
QName nameassigned("");
nameassigned = name;
EXPECT_EQ(nameassigned.LocalPart(), "test");
EXPECT_EQ(nameassigned.Namespace(), "a");
}
TEST(QNameTest, TestConstAssignment) {
StaticQName name = { "a", "test" };
QName namecopy(name);
EXPECT_EQ(namecopy.LocalPart(), "test");
EXPECT_EQ(namecopy.Namespace(), "a");
QName nameassigned("");
nameassigned = name;
EXPECT_EQ(nameassigned.LocalPart(), "test");
EXPECT_EQ(nameassigned.Namespace(), "a");
}
TEST(QNameTest, TestEquality) {
QName name("a-very:long:namespace:test-this");
QName name2("a-very:long:namespace", "test-this");
QName name3("a-very:long:namespaxe", "test-this");
EXPECT_TRUE(name == name2);
EXPECT_FALSE(name == name3);
}
TEST(QNameTest, TestCompare) {
QName name("a");
QName name2("nsa", "a");
QName name3("nsa", "b");
QName name4("nsb", "b");
EXPECT_TRUE(name < name2);
EXPECT_FALSE(name2 < name);
EXPECT_FALSE(name2 < name2);
EXPECT_TRUE(name2 < name3);
EXPECT_FALSE(name3 < name2);
EXPECT_TRUE(name3 < name4);
EXPECT_FALSE(name4 < name3);
}
TEST(QNameTest, TestStaticQName) {
const StaticQName const_name1 = { "namespace", "local-name1" };
const StaticQName const_name2 = { "namespace", "local-name2" };
const QName name("namespace", "local-name1");
const QName name1 = const_name1;
const QName name2 = const_name2;
EXPECT_TRUE(name == const_name1);
EXPECT_TRUE(const_name1 == name);
EXPECT_FALSE(name != const_name1);
EXPECT_FALSE(const_name1 != name);
EXPECT_TRUE(name == name1);
EXPECT_TRUE(name1 == name);
EXPECT_FALSE(name != name1);
EXPECT_FALSE(name1 != name);
EXPECT_FALSE(name == name2);
EXPECT_FALSE(name2 == name);
EXPECT_TRUE(name != name2);
EXPECT_TRUE(name2 != name);
}

View File

@ -1,147 +0,0 @@
/*
* 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/xmllite/xmlbuilder.h"
#include <set>
#include <vector>
#include "talk/xmllite/xmlconstants.h"
#include "talk/xmllite/xmlelement.h"
#include "webrtc/base/common.h"
namespace buzz {
XmlBuilder::XmlBuilder() :
pelCurrent_(NULL),
pelRoot_(),
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.IsEmpty())
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.IsEmpty()) {
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) {
RTC_UNUSED(pctx);
RTC_UNUSED(name);
pelCurrent_ = pvParents_->back();
pvParents_->pop_back();
}
void
XmlBuilder::CharacterData(XmlParseContext * pctx,
const char * text, int len) {
RTC_UNUSED(pctx);
if (pelCurrent_) {
pelCurrent_->AddParsedText(text, len);
}
}
void
XmlBuilder::Error(XmlParseContext * pctx, XML_Error err) {
RTC_UNUSED(pctx);
RTC_UNUSED(err);
pelRoot_.reset(NULL);
pelCurrent_ = NULL;
pvParents_->clear();
}
XmlElement *
XmlBuilder::CreateElement() {
return pelRoot_.release();
}
XmlElement *
XmlBuilder::BuiltElement() {
return pelRoot_.get();
}
XmlBuilder::~XmlBuilder() {
}
} // namespace buzz

View File

@ -1,78 +0,0 @@
/*
* 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 <vector>
#include "talk/xmllite/xmlparser.h"
#include "webrtc/base/scoped_ptr.h"
#ifdef EXPAT_RELATIVE_PATH
#include "expat.h"
#else
#include "third_party/expat/v2_0_1/Source/lib/expat.h"
#endif // EXPAT_RELATIVE_PATH
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_;
rtc::scoped_ptr<XmlElement> pelRoot_;
rtc::scoped_ptr<std::vector<XmlElement*> > pvParents_;
};
}
#endif

View File

@ -1,194 +0,0 @@
/*
* libjingle
* Copyright 2004, 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 <iostream>
#include <sstream>
#include <string>
#include "talk/xmllite/xmlbuilder.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmllite/xmlparser.h"
#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
using buzz::XmlBuilder;
using buzz::XmlElement;
using buzz::XmlParser;
TEST(XmlBuilderTest, TestTrivial) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing/>");
EXPECT_EQ("<testing/>", builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestAttributes1) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a='b'/>");
EXPECT_EQ("<testing a=\"b\"/>", builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestAttributes2) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing e='' long='some text'/>");
EXPECT_EQ("<testing e=\"\" long=\"some text\"/>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestNesting1) {
XmlBuilder builder;
XmlParser::ParseXml(&builder,
"<top><first/><second><third></third></second></top>");
EXPECT_EQ("<top><first/><second><third/></second></top>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestNesting2) {
XmlBuilder builder;
XmlParser::ParseXml(&builder,
"<top><fifth><deeper><and><deeper/></and><sibling><leaf/>"
"</sibling></deeper></fifth><first/><second><third></third>"
"</second></top>");
EXPECT_EQ("<top><fifth><deeper><and><deeper/></and><sibling><leaf/>"
"</sibling></deeper></fifth><first/><second><third/>"
"</second></top>", builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestQuoting1) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a='>'/>");
EXPECT_EQ("<testing a=\"&gt;\"/>", builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestQuoting2) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a='&lt;>&amp;&quot;'/>");
EXPECT_EQ("<testing a=\"&lt;&gt;&amp;&quot;\"/>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestQuoting3) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a='so &quot;important&quot;'/>");
EXPECT_EQ("<testing a=\"so &quot;important&quot;\"/>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestQuoting4) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a='&quot;important&quot;, yes'/>");
EXPECT_EQ("<testing a=\"&quot;important&quot;, yes\"/>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestQuoting5) {
XmlBuilder builder;
XmlParser::ParseXml(&builder,
"<testing a='&lt;what is &quot;important&quot;&gt;'/>");
EXPECT_EQ("<testing a=\"&lt;what is &quot;important&quot;&gt;\"/>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestText1) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing>></testing>");
EXPECT_EQ("<testing>&gt;</testing>", builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestText2) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing>&lt;>&amp;&quot;</testing>");
EXPECT_EQ("<testing>&lt;&gt;&amp;\"</testing>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestText3) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing>so &lt;important&gt;</testing>");
EXPECT_EQ("<testing>so &lt;important&gt;</testing>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestText4) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing>&lt;important&gt;, yes</testing>");
EXPECT_EQ("<testing>&lt;important&gt;, yes</testing>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestText5) {
XmlBuilder builder;
XmlParser::ParseXml(&builder,
"<testing>importance &amp;&lt;important&gt;&amp;</testing>");
EXPECT_EQ("<testing>importance &amp;&lt;important&gt;&amp;</testing>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestNamespace1) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing xmlns='foo'/>");
EXPECT_EQ("<testing xmlns=\"foo\"/>", builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestNamespace2) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing xmlns:a='foo' a:b='c'/>");
EXPECT_EQ("<testing xmlns:a=\"foo\" a:b=\"c\"/>",
builder.BuiltElement()->Str());
}
TEST(XmlBuilderTest, TestNamespace3) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing xmlns:a=''/>");
EXPECT_TRUE(NULL == builder.BuiltElement());
}
TEST(XmlBuilderTest, TestNamespace4) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a:b='c'/>");
EXPECT_TRUE(NULL == builder.BuiltElement());
}
TEST(XmlBuilderTest, TestAttrCollision1) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, "<testing a='first' a='second'/>");
EXPECT_TRUE(NULL == builder.BuiltElement());
}
TEST(XmlBuilderTest, TestAttrCollision2) {
XmlBuilder builder;
XmlParser::ParseXml(&builder,
"<testing xmlns:a='foo' xmlns:b='foo' a:x='c' b:x='d'/>");
EXPECT_TRUE(NULL == builder.BuiltElement());
}
TEST(XmlBuilderTest, TestAttrCollision3) {
XmlBuilder builder;
XmlParser::ParseXml(&builder,
"<testing xmlns:a='foo'><nested xmlns:b='foo' a:x='c' b:x='d'/>"
"</testing>");
EXPECT_TRUE(NULL == builder.BuiltElement());
}

View File

@ -1,42 +0,0 @@
/*
* 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/xmllite/xmlconstants.h"
namespace buzz {
const char STR_EMPTY[] = "";
const char NS_XML[] = "http://www.w3.org/XML/1998/namespace";
const char NS_XMLNS[] = "http://www.w3.org/2000/xmlns/";
const char STR_XMLNS[] = "xmlns";
const char STR_XML[] = "xml";
const char STR_VERSION[] = "version";
const char STR_ENCODING[] = "encoding";
const StaticQName QN_XMLNS = { STR_EMPTY, STR_XMLNS };
} // namespace buzz

View File

@ -1,47 +0,0 @@
/*
* 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 TALK_XMLLITE_XMLCONSTANTS_H_
#define TALK_XMLLITE_XMLCONSTANTS_H_
#include "talk/xmllite/qname.h"
namespace buzz {
extern const char STR_EMPTY[];
extern const char NS_XML[];
extern const char NS_XMLNS[];
extern const char STR_XMLNS[];
extern const char STR_XML[];
extern const char STR_VERSION[];
extern const char STR_ENCODING[];
extern const StaticQName QN_XMLNS;
} // namespace buzz
#endif // TALK_XMLLITE_XMLCONSTANTS_H_

View File

@ -1,513 +0,0 @@
/*
* 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/xmllite/xmlelement.h"
#include <ostream>
#include <sstream>
#include <string>
#include <vector>
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlbuilder.h"
#include "talk/xmllite/xmlconstants.h"
#include "talk/xmllite/xmlparser.h"
#include "talk/xmllite/xmlprinter.h"
#include "webrtc/base/common.h"
namespace buzz {
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),
first_attr_(NULL),
last_attr_(NULL),
first_child_(NULL),
last_child_(NULL),
cdata_(false) {
}
XmlElement::XmlElement(const XmlElement& elt) :
XmlChild(),
name_(elt.name_),
first_attr_(NULL),
last_attr_(NULL),
first_child_(NULL),
last_child_(NULL),
cdata_(false) {
// copy attributes
XmlAttr* attr;
XmlAttr ** plast_attr = &first_attr_;
XmlAttr* newAttr = NULL;
for (attr = elt.first_attr_; attr; attr = attr->NextAttr()) {
newAttr = new XmlAttr(*attr);
*plast_attr = newAttr;
plast_attr = &(newAttr->next_attr_);
}
last_attr_ = newAttr;
// copy children
XmlChild* pChild;
XmlChild ** ppLast = &first_child_;
XmlChild* newChild = NULL;
for (pChild = elt.first_child_; pChild; pChild = pChild->NextChild()) {
if (pChild->IsText()) {
newChild = new XmlText(*(pChild->AsText()));
} else {
newChild = new XmlElement(*(pChild->AsElement()));
}
*ppLast = newChild;
ppLast = &(newChild->next_child_);
}
last_child_ = newChild;
cdata_ = elt.cdata_;
}
XmlElement::XmlElement(const QName& name, bool useDefaultNs) :
name_(name),
first_attr_(useDefaultNs ? new XmlAttr(QN_XMLNS, name.Namespace()) : NULL),
last_attr_(first_attr_),
first_child_(NULL),
last_child_(NULL),
cdata_(false) {
}
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 (first_child_ && first_child_->IsText() && last_child_ == first_child_) {
return first_child_->AsText()->Text();
}
return std::string();
}
void XmlElement::SetBodyText(const std::string& text) {
if (text.empty()) {
ClearChildren();
} else if (first_child_ == NULL) {
AddText(text);
} else if (first_child_->IsText() && last_child_ == first_child_) {
first_child_->AsText()->SetText(text);
} else {
ClearChildren();
AddText(text);
}
}
const QName XmlElement::FirstElementName() const {
const XmlElement* element = FirstElement();
if (element == NULL)
return QName();
return element->Name();
}
XmlAttr* XmlElement::FirstAttr() {
return first_attr_;
}
const std::string XmlElement::Attr(const StaticQName& name) const {
XmlAttr* attr;
for (attr = first_attr_; attr; attr = attr->next_attr_) {
if (attr->name_ == name)
return attr->value_;
}
return std::string();
}
const std::string XmlElement::Attr(const QName& name) const {
XmlAttr* attr;
for (attr = first_attr_; attr; attr = attr->next_attr_) {
if (attr->name_ == name)
return attr->value_;
}
return std::string();
}
bool XmlElement::HasAttr(const StaticQName& name) const {
XmlAttr* attr;
for (attr = first_attr_; attr; attr = attr->next_attr_) {
if (attr->name_ == name)
return true;
}
return false;
}
bool XmlElement::HasAttr(const QName& name) const {
XmlAttr* attr;
for (attr = first_attr_; attr; attr = attr->next_attr_) {
if (attr->name_ == name)
return true;
}
return false;
}
void XmlElement::SetAttr(const QName& name, const std::string& value) {
XmlAttr* attr;
for (attr = first_attr_; attr; attr = attr->next_attr_) {
if (attr->name_ == name)
break;
}
if (!attr) {
attr = new XmlAttr(name, value);
if (last_attr_)
last_attr_->next_attr_ = attr;
else
first_attr_ = attr;
last_attr_ = attr;
return;
}
attr->value_ = value;
}
void XmlElement::ClearAttr(const QName& name) {
XmlAttr* attr;
XmlAttr* last_attr = NULL;
for (attr = first_attr_; attr; attr = attr->next_attr_) {
if (attr->name_ == name)
break;
last_attr = attr;
}
if (!attr)
return;
if (!last_attr)
first_attr_ = attr->next_attr_;
else
last_attr->next_attr_ = attr->next_attr_;
if (last_attr_ == attr)
last_attr_ = last_attr;
delete attr;
}
XmlChild* XmlElement::FirstChild() {
return first_child_;
}
XmlElement* XmlElement::FirstElement() {
XmlChild* pChild;
for (pChild = first_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText())
return pChild->AsElement();
}
return NULL;
}
XmlElement* XmlElement::NextElement() {
XmlChild* pChild;
for (pChild = next_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText())
return pChild->AsElement();
}
return NULL;
}
XmlElement* XmlElement::FirstWithNamespace(const std::string& ns) {
XmlChild* pChild;
for (pChild = first_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
return pChild->AsElement();
}
return NULL;
}
XmlElement *
XmlElement::NextWithNamespace(const std::string& ns) {
XmlChild* pChild;
for (pChild = next_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns)
return pChild->AsElement();
}
return NULL;
}
XmlElement *
XmlElement::FirstNamed(const QName& name) {
XmlChild* pChild;
for (pChild = first_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name() == name)
return pChild->AsElement();
}
return NULL;
}
XmlElement *
XmlElement::FirstNamed(const StaticQName& name) {
XmlChild* pChild;
for (pChild = first_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name() == name)
return pChild->AsElement();
}
return NULL;
}
XmlElement *
XmlElement::NextNamed(const QName& name) {
XmlChild* pChild;
for (pChild = next_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name() == name)
return pChild->AsElement();
}
return NULL;
}
XmlElement *
XmlElement::NextNamed(const StaticQName& name) {
XmlChild* pChild;
for (pChild = next_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name() == name)
return pChild->AsElement();
}
return NULL;
}
XmlElement* XmlElement::FindOrAddNamedChild(const QName& name) {
XmlElement* child = FirstNamed(name);
if (!child) {
child = new XmlElement(name);
AddElement(child);
}
return child;
}
const std::string XmlElement::TextNamed(const QName& name) const {
XmlChild* pChild;
for (pChild = first_child_; pChild; pChild = pChild->next_child_) {
if (!pChild->IsText() && pChild->AsElement()->Name() == name)
return pChild->AsElement()->BodyText();
}
return std::string();
}
void XmlElement::InsertChildAfter(XmlChild* predecessor, XmlChild* next) {
if (predecessor == NULL) {
next->next_child_ = first_child_;
first_child_ = next;
}
else {
next->next_child_ = predecessor->next_child_;
predecessor->next_child_ = next;
}
}
void XmlElement::RemoveChildAfter(XmlChild* predecessor) {
XmlChild* next;
if (predecessor == NULL) {
next = first_child_;
first_child_ = next->next_child_;
}
else {
next = predecessor->next_child_;
predecessor->next_child_ = next->next_child_;
}
if (last_child_ == next)
last_child_ = predecessor;
delete next;
}
void XmlElement::AddAttr(const QName& name, const std::string& value) {
ASSERT(!HasAttr(name));
XmlAttr ** pprev = last_attr_ ? &(last_attr_->next_attr_) : &first_attr_;
last_attr_ = (*pprev = new XmlAttr(name, value));
}
void XmlElement::AddAttr(const QName& name, const std::string& value,
int depth) {
XmlElement* element = this;
while (depth--) {
element = element->last_child_->AsElement();
}
element->AddAttr(name, value);
}
void XmlElement::AddParsedText(const char* cstr, int len) {
if (len == 0)
return;
if (last_child_ && last_child_->IsText()) {
last_child_->AsText()->AddParsedText(cstr, len);
return;
}
XmlChild ** pprev = last_child_ ? &(last_child_->next_child_) : &first_child_;
last_child_ = *pprev = new XmlText(cstr, len);
}
void XmlElement::AddCDATAText(const char* buf, int len) {
cdata_ = true;
AddParsedText(buf, len);
}
void XmlElement::AddText(const std::string& text) {
if (text == STR_EMPTY)
return;
if (last_child_ && last_child_->IsText()) {
last_child_->AsText()->AddText(text);
return;
}
XmlChild ** pprev = last_child_ ? &(last_child_->next_child_) : &first_child_;
last_child_ = *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->last_child_->AsElement();
}
element->AddText(text);
}
void XmlElement::AddElement(XmlElement *child) {
if (child == NULL)
return;
XmlChild ** pprev = last_child_ ? &(last_child_->next_child_) : &first_child_;
*pprev = child;
last_child_ = child;
child->next_child_ = NULL;
}
void XmlElement::AddElement(XmlElement *child, int depth) {
XmlElement* element = this;
while (depth--) {
element = element->last_child_->AsElement();
}
element->AddElement(child);
}
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::ClearAttributes() {
XmlAttr* attr;
for (attr = first_attr_; attr; ) {
XmlAttr* to_delete = attr;
attr = attr->next_attr_;
delete to_delete;
}
first_attr_ = last_attr_ = NULL;
}
void XmlElement::ClearChildren() {
XmlChild* pchild;
for (pchild = first_child_; pchild; ) {
XmlChild* to_delete = pchild;
pchild = pchild->next_child_;
delete to_delete;
}
first_child_ = last_child_ = NULL;
}
std::string XmlElement::Str() const {
std::stringstream ss;
XmlPrinter::PrintXml(&ss, this);
return ss.str();
}
XmlElement* XmlElement::ForStr(const std::string& str) {
XmlBuilder builder;
XmlParser::ParseXml(&builder, str);
return builder.CreateElement();
}
XmlElement::~XmlElement() {
XmlAttr* attr;
for (attr = first_attr_; attr; ) {
XmlAttr* to_delete = attr;
attr = attr->next_attr_;
delete to_delete;
}
XmlChild* pchild;
for (pchild = first_child_; pchild; ) {
XmlChild* to_delete = pchild;
pchild = pchild->next_child_;
delete to_delete;
}
}
} // namespace buzz

View File

@ -1,251 +0,0 @@
/*
* 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 TALK_XMLLITE_XMLELEMENT_H_
#define TALK_XMLLITE_XMLELEMENT_H_
#include <iosfwd>
#include <string>
#include "talk/xmllite/qname.h"
#include "webrtc/base/scoped_ptr.h"
namespace buzz {
class XmlChild;
class XmlText;
class XmlElement;
class XmlAttr;
class XmlChild {
public:
XmlChild* NextChild() { return next_child_; }
const XmlChild* NextChild() const { return next_child_; }
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() :
next_child_(NULL) {
}
virtual bool IsTextImpl() const = 0;
virtual XmlElement* AsElementImpl() const = 0;
virtual XmlText* AsTextImpl() const = 0;
virtual ~XmlChild();
private:
friend class XmlElement;
XmlChild(const XmlChild& noimpl);
XmlChild* next_child_;
};
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 {
public:
XmlAttr* NextAttr() const { return next_attr_; }
const QName& Name() const { return name_; }
const std::string& Value() const { return value_; }
private:
friend class XmlElement;
explicit XmlAttr(const QName& name, const std::string& value) :
next_attr_(NULL),
name_(name),
value_(value) {
}
explicit XmlAttr(const XmlAttr& att) :
next_attr_(NULL),
name_(att.name_),
value_(att.value_) {
}
XmlAttr* next_attr_;
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_; }
void SetName(const QName& name) { name_ = 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 an empty string if the attribute isn't there:
// use HasAttr to test presence of an attribute.
const std::string Attr(const StaticQName& name) const;
const std::string Attr(const QName& name) const;
bool HasAttr(const StaticQName& 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 StaticQName& name);
const XmlElement* FirstNamed(const StaticQName& name) const {
return const_cast<XmlElement *>(this)->FirstNamed(name);
}
XmlElement* FirstNamed(const QName& name);
const XmlElement* FirstNamed(const QName& name) const {
return const_cast<XmlElement *>(this)->FirstNamed(name);
}
XmlElement* NextNamed(const StaticQName& name);
const XmlElement* NextNamed(const StaticQName& name) const {
return const_cast<XmlElement *>(this)->NextNamed(name);
}
XmlElement* NextNamed(const QName& name);
const XmlElement* NextNamed(const QName& name) const {
return const_cast<XmlElement *>(this)->NextNamed(name);
}
// Finds the first element named 'name'. If that element can't be found then
// adds one and returns it.
XmlElement* FindOrAddNamedChild(const QName& name);
const std::string TextNamed(const QName& name) const;
void InsertChildAfter(XmlChild* predecessor, XmlChild* new_child);
void RemoveChildAfter(XmlChild* predecessor);
void AddParsedText(const char* buf, int len);
// Note: CDATA is not supported by XMPP, therefore using this function will
// generate non-XMPP compatible XML.
void AddCDATAText(const char* buf, int len);
void AddText(const std::string& text);
void AddText(const std::string& text, int depth);
void AddElement(XmlElement* child);
void AddElement(XmlElement* child, 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 ClearAttributes();
void ClearChildren();
static XmlElement* ForStr(const std::string& str);
std::string Str() const;
bool IsCDATA() const { return cdata_; }
protected:
virtual bool IsTextImpl() const;
virtual XmlElement* AsElementImpl() const;
virtual XmlText* AsTextImpl() const;
private:
QName name_;
XmlAttr* first_attr_;
XmlAttr* last_attr_;
XmlChild* first_child_;
XmlChild* last_child_;
bool cdata_;
};
} // namespace buzz
#endif // TALK_XMLLITE_XMLELEMENT_H_

View File

@ -1,275 +0,0 @@
/*
* libjingle
* Copyright 2004, 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 <iostream>
#include <sstream>
#include <string>
#include "talk/xmllite/xmlelement.h"
#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/thread.h"
using buzz::QName;
using buzz::XmlAttr;
using buzz::XmlChild;
using buzz::XmlElement;
std::ostream& operator<<(std::ostream& os, const QName& name) {
os << name.Namespace() << ":" << name.LocalPart();
return os;
}
TEST(XmlElementTest, TestConstructors) {
XmlElement elt(QName("google:test", "first"));
EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", elt.Str());
XmlElement elt2(QName("google:test", "first"), true);
EXPECT_EQ("<first xmlns=\"google:test\"/>", elt2.Str());
}
TEST(XmlElementTest, TestAdd) {
XmlElement elt(QName("google:test", "root"), true);
elt.AddElement(new XmlElement(QName("google:test", "first")));
elt.AddElement(new XmlElement(QName("google:test", "nested")), 1);
elt.AddText("nested-value", 2);
elt.AddText("between-", 1);
elt.AddText("value", 1);
elt.AddElement(new XmlElement(QName("google:test", "nested2")), 1);
elt.AddElement(new XmlElement(QName("google:test", "second")));
elt.AddText("init-value", 1);
elt.AddElement(new XmlElement(QName("google:test", "nested3")), 1);
elt.AddText("trailing-value", 1);
// make sure it looks ok overall
EXPECT_EQ("<root xmlns=\"google:test\">"
"<first><nested>nested-value</nested>between-value<nested2/></first>"
"<second>init-value<nested3/>trailing-value</second></root>",
elt.Str());
// make sure text was concatenated
XmlChild * pchild =
elt.FirstChild()->AsElement()->FirstChild()->NextChild();
EXPECT_TRUE(pchild->IsText());
EXPECT_EQ("between-value", pchild->AsText()->Text());
}
TEST(XmlElementTest, TestAttrs) {
XmlElement elt(QName("", "root"));
elt.SetAttr(QName("", "a"), "avalue");
EXPECT_EQ("<root a=\"avalue\"/>", elt.Str());
elt.SetAttr(QName("", "b"), "bvalue");
EXPECT_EQ("<root a=\"avalue\" b=\"bvalue\"/>", elt.Str());
elt.SetAttr(QName("", "a"), "avalue2");
EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue\"/>", elt.Str());
elt.SetAttr(QName("", "b"), "bvalue2");
EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\"/>", elt.Str());
elt.SetAttr(QName("", "c"), "cvalue");
EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\"/>", elt.Str());
XmlAttr * patt = elt.FirstAttr();
EXPECT_EQ(QName("", "a"), patt->Name());
EXPECT_EQ("avalue2", patt->Value());
patt = patt->NextAttr();
EXPECT_EQ(QName("", "b"), patt->Name());
EXPECT_EQ("bvalue2", patt->Value());
patt = patt->NextAttr();
EXPECT_EQ(QName("", "c"), patt->Name());
EXPECT_EQ("cvalue", patt->Value());
patt = patt->NextAttr();
EXPECT_TRUE(NULL == patt);
EXPECT_TRUE(elt.HasAttr(QName("", "a")));
EXPECT_TRUE(elt.HasAttr(QName("", "b")));
EXPECT_TRUE(elt.HasAttr(QName("", "c")));
EXPECT_FALSE(elt.HasAttr(QName("", "d")));
elt.SetAttr(QName("", "d"), "dvalue");
EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
elt.Str());
EXPECT_TRUE(elt.HasAttr(QName("", "d")));
elt.ClearAttr(QName("", "z")); // not found, no effect
EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>",
elt.Str());
elt.ClearAttr(QName("", "b"));
EXPECT_EQ("<root a=\"avalue2\" c=\"cvalue\" d=\"dvalue\"/>", elt.Str());
elt.ClearAttr(QName("", "a"));
EXPECT_EQ("<root c=\"cvalue\" d=\"dvalue\"/>", elt.Str());
elt.ClearAttr(QName("", "d"));
EXPECT_EQ("<root c=\"cvalue\"/>", elt.Str());
elt.ClearAttr(QName("", "c"));
EXPECT_EQ("<root/>", elt.Str());
}
TEST(XmlElementTest, TestBodyText) {
XmlElement elt(QName("", "root"));
EXPECT_EQ("", elt.BodyText());
elt.AddText("body value text");
EXPECT_EQ("body value text", elt.BodyText());
elt.ClearChildren();
elt.AddText("more value ");
elt.AddText("text");
EXPECT_EQ("more value text", elt.BodyText());
elt.ClearChildren();
elt.AddText("decoy");
elt.AddElement(new XmlElement(QName("", "dummy")));
EXPECT_EQ("", elt.BodyText());
elt.SetBodyText("replacement");
EXPECT_EQ("replacement", elt.BodyText());
elt.SetBodyText("");
EXPECT_TRUE(NULL == elt.FirstChild());
elt.SetBodyText("goodbye");
EXPECT_EQ("goodbye", elt.FirstChild()->AsText()->Text());
EXPECT_EQ("goodbye", elt.BodyText());
}
TEST(XmlElementTest, TestCopyConstructor) {
XmlElement * element = XmlElement::ForStr(
"<root xmlns='test-foo'>This is a <em a='avalue' b='bvalue'>"
"little <b>little</b></em> test</root>");
XmlElement * pelCopy = new XmlElement(*element);
EXPECT_EQ("<root xmlns=\"test-foo\">This is a <em a=\"avalue\" b=\"bvalue\">"
"little <b>little</b></em> test</root>", pelCopy->Str());
delete pelCopy;
pelCopy = new XmlElement(*(element->FirstChild()->NextChild()->AsElement()));
EXPECT_EQ("<foo:em a=\"avalue\" b=\"bvalue\" xmlns:foo=\"test-foo\">"
"little <foo:b>little</foo:b></foo:em>", pelCopy->Str());
XmlAttr * patt = pelCopy->FirstAttr();
EXPECT_EQ(QName("", "a"), patt->Name());
EXPECT_EQ("avalue", patt->Value());
patt = patt->NextAttr();
EXPECT_EQ(QName("", "b"), patt->Name());
EXPECT_EQ("bvalue", patt->Value());
patt = patt->NextAttr();
EXPECT_TRUE(NULL == patt);
delete pelCopy;
delete element;
}
TEST(XmlElementTest, TestNameSearch) {
XmlElement * element = XmlElement::ForStr(
"<root xmlns='test-foo'>"
"<firstname>George</firstname>"
"<middlename>X.</middlename>"
"some text"
"<lastname>Harrison</lastname>"
"<firstname>John</firstname>"
"<middlename>Y.</middlename>"
"<lastname>Lennon</lastname>"
"</root>");
EXPECT_TRUE(NULL ==
element->FirstNamed(QName("", "firstname")));
EXPECT_EQ(element->FirstChild(),
element->FirstNamed(QName("test-foo", "firstname")));
EXPECT_EQ(element->FirstChild()->NextChild(),
element->FirstNamed(QName("test-foo", "middlename")));
EXPECT_EQ(element->FirstElement()->NextElement(),
element->FirstNamed(QName("test-foo", "middlename")));
EXPECT_EQ("Harrison",
element->TextNamed(QName("test-foo", "lastname")));
EXPECT_EQ(element->FirstElement()->NextElement()->NextElement(),
element->FirstNamed(QName("test-foo", "lastname")));
EXPECT_EQ("John", element->FirstNamed(QName("test-foo", "firstname"))->
NextNamed(QName("test-foo", "firstname"))->BodyText());
EXPECT_EQ("Y.", element->FirstNamed(QName("test-foo", "middlename"))->
NextNamed(QName("test-foo", "middlename"))->BodyText());
EXPECT_EQ("Lennon", element->FirstNamed(QName("test-foo", "lastname"))->
NextNamed(QName("test-foo", "lastname"))->BodyText());
EXPECT_TRUE(NULL == element->FirstNamed(QName("test-foo", "firstname"))->
NextNamed(QName("test-foo", "firstname"))->
NextNamed(QName("test-foo", "firstname")));
delete element;
}
class XmlElementCreatorThread : public rtc::Thread {
public:
XmlElementCreatorThread(int count, buzz::QName qname) :
count_(count), qname_(qname) {}
virtual ~XmlElementCreatorThread() {
Stop();
}
virtual void Run() {
std::vector<buzz::XmlElement*> elems;
for (int i = 0; i < count_; i++) {
elems.push_back(new XmlElement(qname_));
}
for (int i = 0; i < count_; i++) {
delete elems[i];
}
}
private:
int count_;
buzz::QName qname_;
};
// If XmlElement creation and destruction isn't thread safe,
// this test should crash.
TEST(XmlElementTest, TestMultithread) {
int thread_count = 2; // Was 100, but that's too slow.
int elem_count = 100; // Was 100000, but that's too slow.
buzz::QName qname("foo", "bar");
std::vector<rtc::Thread*> threads;
for (int i = 0; i < thread_count; i++) {
threads.push_back(
new XmlElementCreatorThread(elem_count, qname));
threads[i]->Start();
}
for (int i = 0; i < thread_count; i++) {
threads[i]->Stop();
delete threads[i];
}
}

View File

@ -1,195 +0,0 @@
/*
* 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/xmllite/xmlnsstack.h"
#include <sstream>
#include <string>
#include <vector>
#include "talk/xmllite/xmlconstants.h"
#include "talk/xmllite/xmlelement.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());
}
}
std::pair<std::string, bool> 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 std::make_pair(NS_XML, true);
if (prefix == "xmlns")
return std::make_pair(NS_XMLNS, true);
// Other names with xml prefix are illegal.
return std::make_pair(STR_EMPTY, false);
}
std::vector<std::string>::iterator pos;
for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) {
pos -= 2;
if (*pos == prefix)
return std::make_pair(*(pos + 1), true);
}
if (prefix == STR_EMPTY)
return std::make_pair(STR_EMPTY, true); // default namespace
return std::make_pair(STR_EMPTY, false); // none found
}
bool XmlnsStack::PrefixMatchesNs(const std::string& prefix,
const std::string& ns) {
const std::pair<std::string, bool> match = NsForPrefix(prefix);
return match.second && (match.first == 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).second) {
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();
}
}

View File

@ -1,62 +0,0 @@
/*
* 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 TALK_XMLLITE_XMLNSSTACK_H_
#define TALK_XMLLITE_XMLNSSTACK_H_
#include <string>
#include <vector>
#include "talk/xmllite/qname.h"
#include "webrtc/base/scoped_ptr.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();
std::pair<std::string, bool> 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:
rtc::scoped_ptr<std::vector<std::string> > pxmlnsStack_;
rtc::scoped_ptr<std::vector<size_t> > pxmlnsDepthStack_;
};
}
#endif // TALK_XMLLITE_XMLNSSTACK_H_

View File

@ -1,258 +0,0 @@
/*
* libjingle
* Copyright 2004, 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/xmllite/xmlnsstack.h"
#include <iostream>
#include <sstream>
#include <string>
#include "talk/xmllite/xmlconstants.h"
#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
using buzz::NS_XML;
using buzz::NS_XMLNS;
using buzz::QName;
using buzz::XmlnsStack;
TEST(XmlnsStackTest, TestBuiltin) {
XmlnsStack stack;
EXPECT_EQ(std::string(NS_XML), stack.NsForPrefix("xml").first);
EXPECT_EQ(std::string(NS_XMLNS), stack.NsForPrefix("xmlns").first);
EXPECT_EQ("", stack.NsForPrefix("").first);
EXPECT_EQ("xml", stack.PrefixForNs(NS_XML, false).first);
EXPECT_EQ("xmlns", stack.PrefixForNs(NS_XMLNS, false).first);
EXPECT_EQ("", stack.PrefixForNs("", false).first);
EXPECT_EQ("", stack.PrefixForNs("", true).first);
}
TEST(XmlnsStackTest, TestNsForPrefix) {
XmlnsStack stack;
stack.AddXmlns("pre1", "ns1");
stack.AddXmlns("pre2", "ns2");
stack.AddXmlns("pre1", "ns3");
stack.AddXmlns("", "ns4");
EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
EXPECT_TRUE(stack.NsForPrefix("pre1").second);
EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
EXPECT_EQ("ns4", stack.NsForPrefix("").first);
EXPECT_EQ("", stack.NsForPrefix("pre3").first);
EXPECT_FALSE(stack.NsForPrefix("pre3").second);
}
TEST(XmlnsStackTest, TestPrefixForNs) {
XmlnsStack stack;
stack.AddXmlns("pre1", "ns1");
stack.AddXmlns("pre2", "ns2");
stack.AddXmlns("pre1", "ns3");
stack.AddXmlns("pre3", "ns2");
stack.AddXmlns("pre4", "ns4");
stack.AddXmlns("", "ns4");
EXPECT_EQ("", stack.PrefixForNs("ns1", false).first);
EXPECT_FALSE(stack.PrefixForNs("ns1", false).second);
EXPECT_EQ("", stack.PrefixForNs("ns1", true).first);
EXPECT_FALSE(stack.PrefixForNs("ns1", true).second);
EXPECT_EQ("pre3", stack.PrefixForNs("ns2", false).first);
EXPECT_TRUE(stack.PrefixForNs("ns2", false).second);
EXPECT_EQ("pre3", stack.PrefixForNs("ns2", true).first);
EXPECT_TRUE(stack.PrefixForNs("ns2", true).second);
EXPECT_EQ("pre1", stack.PrefixForNs("ns3", false).first);
EXPECT_EQ("pre1", stack.PrefixForNs("ns3", true).first);
EXPECT_EQ("", stack.PrefixForNs("ns4", false).first);
EXPECT_TRUE(stack.PrefixForNs("ns4", false).second);
EXPECT_EQ("pre4", stack.PrefixForNs("ns4", true).first);
EXPECT_EQ("", stack.PrefixForNs("ns5", false).first);
EXPECT_FALSE(stack.PrefixForNs("ns5", false).second);
EXPECT_EQ("", stack.PrefixForNs("ns5", true).first);
EXPECT_EQ("", stack.PrefixForNs("", false).first);
EXPECT_EQ("", stack.PrefixForNs("", true).first);
stack.AddXmlns("", "ns6");
EXPECT_EQ("", stack.PrefixForNs("ns6", false).first);
EXPECT_TRUE(stack.PrefixForNs("ns6", false).second);
EXPECT_EQ("", stack.PrefixForNs("ns6", true).first);
EXPECT_FALSE(stack.PrefixForNs("ns6", true).second);
}
TEST(XmlnsStackTest, TestFrames) {
XmlnsStack stack;
stack.PushFrame();
stack.AddXmlns("pre1", "ns1");
stack.AddXmlns("pre2", "ns2");
stack.PushFrame();
stack.AddXmlns("pre1", "ns3");
stack.AddXmlns("pre3", "ns2");
stack.AddXmlns("pre4", "ns4");
stack.PushFrame();
stack.PushFrame();
stack.AddXmlns("", "ns4");
// basic test
EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first);
EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first);
EXPECT_EQ("", stack.NsForPrefix("pre5").first);
EXPECT_FALSE(stack.NsForPrefix("pre5").second);
EXPECT_EQ("ns4", stack.NsForPrefix("").first);
EXPECT_TRUE(stack.NsForPrefix("").second);
// pop the default xmlns definition
stack.PopFrame();
EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first);
EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first);
EXPECT_EQ("", stack.NsForPrefix("pre5").first);
EXPECT_FALSE(stack.NsForPrefix("pre5").second);
EXPECT_EQ("", stack.NsForPrefix("").first);
EXPECT_TRUE(stack.NsForPrefix("").second);
// pop empty frame (nop)
stack.PopFrame();
EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first);
EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first);
EXPECT_EQ("", stack.NsForPrefix("pre5").first);
EXPECT_FALSE(stack.NsForPrefix("pre5").second);
EXPECT_EQ("", stack.NsForPrefix("").first);
EXPECT_TRUE(stack.NsForPrefix("").second);
// pop frame with three defs
stack.PopFrame();
EXPECT_EQ("ns1", stack.NsForPrefix("pre1").first);
EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first);
EXPECT_EQ("", stack.NsForPrefix("pre3").first);
EXPECT_FALSE(stack.NsForPrefix("pre3").second);
EXPECT_EQ("", stack.NsForPrefix("pre4").first);
EXPECT_FALSE(stack.NsForPrefix("pre4").second);
EXPECT_EQ("", stack.NsForPrefix("pre5").first);
EXPECT_FALSE(stack.NsForPrefix("pre5").second);
EXPECT_EQ("", stack.NsForPrefix("").first);
EXPECT_TRUE(stack.NsForPrefix("").second);
// pop frame with last two defs
stack.PopFrame();
EXPECT_FALSE(stack.NsForPrefix("pre1").second);
EXPECT_FALSE(stack.NsForPrefix("pre2").second);
EXPECT_FALSE(stack.NsForPrefix("pre3").second);
EXPECT_FALSE(stack.NsForPrefix("pre4").second);
EXPECT_FALSE(stack.NsForPrefix("pre5").second);
EXPECT_TRUE(stack.NsForPrefix("").second);
EXPECT_EQ("", stack.NsForPrefix("pre1").first);
EXPECT_EQ("", stack.NsForPrefix("pre2").first);
EXPECT_EQ("", stack.NsForPrefix("pre3").first);
EXPECT_EQ("", stack.NsForPrefix("pre4").first);
EXPECT_EQ("", stack.NsForPrefix("pre5").first);
EXPECT_EQ("", stack.NsForPrefix("").first);
}
TEST(XmlnsStackTest, TestAddNewPrefix) {
XmlnsStack stack;
// builtin namespaces cannot be added
EXPECT_FALSE(stack.AddNewPrefix("", true).second);
EXPECT_FALSE(stack.AddNewPrefix("", false).second);
EXPECT_FALSE(stack.AddNewPrefix(NS_XML, true).second);
EXPECT_FALSE(stack.AddNewPrefix(NS_XML, false).second);
EXPECT_FALSE(stack.AddNewPrefix(NS_XMLNS, true).second);
EXPECT_FALSE(stack.AddNewPrefix(NS_XMLNS, false).second);
// namespaces already added cannot be added again.
EXPECT_EQ("foo", stack.AddNewPrefix("http://a.b.com/foo.htm", true).first);
EXPECT_EQ("bare", stack.AddNewPrefix("http://a.b.com/bare", false).first);
EXPECT_EQ("z", stack.AddNewPrefix("z", false).first);
EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/foo.htm", true).second);
EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/bare", true).second);
EXPECT_FALSE(stack.AddNewPrefix("z", true).second);
EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/foo.htm", false).second);
EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/bare", false).second);
EXPECT_FALSE(stack.AddNewPrefix("z", false).second);
// default namespace usable by non-attributes only
stack.AddXmlns("", "http://my/default");
EXPECT_FALSE(stack.AddNewPrefix("http://my/default", false).second);
EXPECT_EQ("def", stack.AddNewPrefix("http://my/default", true).first);
// namespace cannot start with 'xml'
EXPECT_EQ("ns", stack.AddNewPrefix("http://a.b.com/xmltest", true).first);
EXPECT_EQ("ns2", stack.AddNewPrefix("xmlagain", false).first);
// verify added namespaces are still defined
EXPECT_EQ("http://a.b.com/foo.htm", stack.NsForPrefix("foo").first);
EXPECT_TRUE(stack.NsForPrefix("foo").second);
EXPECT_EQ("http://a.b.com/bare", stack.NsForPrefix("bare").first);
EXPECT_TRUE(stack.NsForPrefix("bare").second);
EXPECT_EQ("z", stack.NsForPrefix("z").first);
EXPECT_TRUE(stack.NsForPrefix("z").second);
EXPECT_EQ("http://my/default", stack.NsForPrefix("").first);
EXPECT_TRUE(stack.NsForPrefix("").second);
EXPECT_EQ("http://my/default", stack.NsForPrefix("def").first);
EXPECT_TRUE(stack.NsForPrefix("def").second);
EXPECT_EQ("http://a.b.com/xmltest", stack.NsForPrefix("ns").first);
EXPECT_TRUE(stack.NsForPrefix("ns").second);
EXPECT_EQ("xmlagain", stack.NsForPrefix("ns2").first);
EXPECT_TRUE(stack.NsForPrefix("ns2").second);
}
TEST(XmlnsStackTest, TestFormatQName) {
XmlnsStack stack;
stack.AddXmlns("pre1", "ns1");
stack.AddXmlns("pre2", "ns2");
stack.AddXmlns("pre1", "ns3");
stack.AddXmlns("", "ns4");
EXPECT_EQ("zip",
stack.FormatQName(QName("ns1", "zip"), false)); // no match
EXPECT_EQ("pre2:abracadabra",
stack.FormatQName(QName("ns2", "abracadabra"), false));
EXPECT_EQ("pre1:a",
stack.FormatQName(QName("ns3", "a"), false));
EXPECT_EQ("simple",
stack.FormatQName(QName("ns4", "simple"), false));
EXPECT_EQ("root",
stack.FormatQName(QName("", "root"), false)); // no match
EXPECT_EQ("zip",
stack.FormatQName(QName("ns1", "zip"), true)); // no match
EXPECT_EQ("pre2:abracadabra",
stack.FormatQName(QName("ns2", "abracadabra"), true));
EXPECT_EQ("pre1:a",
stack.FormatQName(QName("ns3", "a"), true));
EXPECT_EQ("simple",
stack.FormatQName(QName("ns4", "simple"), true)); // no match
EXPECT_EQ("root",
stack.FormatQName(QName("", "root"), true));
}

View File

@ -1,278 +0,0 @@
/*
* 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/xmllite/xmlparser.h"
#include <string>
#include <vector>
#include "talk/xmllite/xmlconstants.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmllite/xmlnsstack.h"
#include "talk/xmllite/xmlnsstack.h"
#include "webrtc/base/common.h"
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) :
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));
}
}
}
context_.SetPosition(XML_GetCurrentLineNumber(expat_),
XML_GetCurrentColumnNumber(expat_),
XML_GetCurrentByteIndex(expat_));
pxph_->StartElement(&context_, name, atts);
}
void
XmlParser::ExpatEndElement(const char *name) {
if (context_.RaisedError() != XML_ERROR_NONE)
return;
context_.EndElement();
context_.SetPosition(XML_GetCurrentLineNumber(expat_),
XML_GetCurrentColumnNumber(expat_),
XML_GetCurrentByteIndex(expat_));
pxph_->EndElement(&context_, name);
}
void
XmlParser::ExpatCharacterData(const char *text, int len) {
if (context_.RaisedError() != XML_ERROR_NONE)
return;
context_.SetPosition(XML_GetCurrentLineNumber(expat_),
XML_GetCurrentColumnNumber(expat_),
XML_GetCurrentByteIndex(expat_));
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_.SetPosition(XML_GetCurrentLineNumber(expat_),
XML_GetCurrentColumnNumber(expat_),
XML_GetCurrentByteIndex(expat_));
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() :
xmlnsstack_(),
raised_(XML_ERROR_NONE),
line_number_(0),
column_number_(0),
byte_index_(0) {
}
void
XmlParser::ParseContext::StartNamespace(const char *prefix, const char *ns) {
xmlnsstack_.AddXmlns(*prefix ? prefix : STR_EMPTY, 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::pair<std::string, bool> result =
xmlnsstack_.NsForPrefix(std::string(qname, c - qname));
if (!result.second)
return QName();
return QName(result.first, c + 1);
}
}
if (isAttr)
return QName(STR_EMPTY, qname);
std::pair<std::string, bool> result = xmlnsstack_.NsForPrefix(STR_EMPTY);
if (!result.second)
return QName();
return QName(result.first, qname);
}
void
XmlParser::ParseContext::Reset() {
xmlnsstack_.Reset();
raised_ = XML_ERROR_NONE;
}
void
XmlParser::ParseContext::SetPosition(int line, int column,
long byte_index) {
line_number_ = line;
column_number_ = column;
byte_index_ = byte_index;
}
void
XmlParser::ParseContext::GetPosition(unsigned long * line,
unsigned long * column,
unsigned long * byte_index) {
if (line != NULL) {
*line = static_cast<unsigned long>(line_number_);
}
if (column != NULL) {
*column = static_cast<unsigned long>(column_number_);
}
if (byte_index != NULL) {
*byte_index = static_cast<unsigned long>(byte_index_);
}
}
XmlParser::ParseContext::~ParseContext() {
}
} // namespace buzz

View File

@ -1,120 +0,0 @@
/*
* 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 TALK_XMLLITE_XMLPARSER_H_
#define TALK_XMLLITE_XMLPARSER_H_
#include <string>
#include "talk/xmllite/xmlnsstack.h"
#ifdef EXPAT_RELATIVE_PATH
#include "expat.h"
#else
#include "third_party/expat/v2_0_1/Source/lib/expat.h"
#endif // EXPAT_RELATIVE_PATH
struct XML_ParserStruct;
typedef struct XML_ParserStruct* XML_Parser;
namespace buzz {
class XmlParseHandler;
class XmlParseContext;
class XmlParser;
class XmlParseContext {
public:
virtual ~XmlParseContext() {}
virtual QName ResolveQName(const char * qname, bool isAttr) = 0;
virtual void RaiseError(XML_Error err) = 0;
virtual void GetPosition(unsigned long * line, unsigned long * column,
unsigned long * byte_index) = 0;
};
class XmlParseHandler {
public:
virtual ~XmlParseHandler() {}
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();
virtual ~ParseContext();
virtual QName ResolveQName(const char * qname, bool isAttr);
virtual void RaiseError(XML_Error err) { if (!raised_) raised_ = err; }
virtual void GetPosition(unsigned long * line, unsigned long * column,
unsigned long * byte_index);
XML_Error RaisedError() { return raised_; }
void Reset();
void StartElement();
void EndElement();
void StartNamespace(const char * prefix, const char * ns);
void SetPosition(int line, int column, long byte_index);
private:
XmlnsStack xmlnsstack_;
XML_Error raised_;
XML_Size line_number_;
XML_Size column_number_;
XML_Index byte_index_;
};
ParseContext context_;
XML_Parser expat_;
XmlParseHandler * pxph_;
bool sentError_;
};
} // namespace buzz
#endif // TALK_XMLLITE_XMLPARSER_H_

View File

@ -1,302 +0,0 @@
/*
* libjingle
* Copyright 2004, 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 <iostream>
#include <sstream>
#include <string>
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlparser.h"
#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
using buzz::QName;
using buzz::XmlParser;
using buzz::XmlParseContext;
using buzz::XmlParseHandler;
class XmlParserTestHandler : public XmlParseHandler {
public:
virtual void StartElement(XmlParseContext * pctx,
const char * name, const char ** atts) {
ss_ << "START (" << pctx->ResolveQName(name, false).Merged();
while (*atts) {
ss_ << ", " << pctx->ResolveQName(*atts, true).Merged()
<< "='" << *(atts+1) << "'";
atts += 2;
}
ss_ << ") ";
}
virtual void EndElement(XmlParseContext * pctx, const char * name) {
RTC_UNUSED(pctx);
RTC_UNUSED(name);
ss_ << "END ";
}
virtual void CharacterData(XmlParseContext * pctx,
const char * text, int len) {
RTC_UNUSED(pctx);
ss_ << "TEXT (" << std::string(text, len) << ") ";
}
virtual void Error(XmlParseContext * pctx, XML_Error code) {
RTC_UNUSED(pctx);
ss_ << "ERROR (" << static_cast<int>(code) << ") ";
}
virtual ~XmlParserTestHandler() {
}
std::string Str() {
return ss_.str();
}
std::string StrClear() {
std::string result = ss_.str();
ss_.str("");
return result;
}
private:
std::stringstream ss_;
};
TEST(XmlParserTest, TestTrivial) {
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<testing/>");
EXPECT_EQ("START (testing) END ", handler.Str());
}
TEST(XmlParserTest, TestAttributes) {
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<testing a='b'/>");
EXPECT_EQ("START (testing, a='b') END ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<testing e='' long='some text'/>");
EXPECT_EQ("START (testing, e='', long='some text') END ", handler.Str());
}
}
TEST(XmlParserTest, TestNesting) {
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<top><first/><second><third></third></second></top>");
EXPECT_EQ("START (top) START (first) END START (second) START (third) "
"END END END ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<top><fifth><deeper><and><deeper/></and>"
"<sibling><leaf/></sibling></deeper></fifth><first/><second>"
"<third></third></second></top>");
EXPECT_EQ("START (top) START (fifth) START (deeper) START (and) START "
"(deeper) END END START (sibling) START (leaf) END END END "
"END START (first) END START (second) START (third) END END END ",
handler.Str());
}
}
TEST(XmlParserTest, TestXmlDecl) {
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<?xml version=\"1.0\"?><testing/>");
EXPECT_EQ("START (testing) END ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<?xml version=\"1.0\" encoding=\"utf-8\"?><testing/>");
EXPECT_EQ("START (testing) END ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
"<testing/>");
EXPECT_EQ("START (testing) END ", handler.Str());
}
}
TEST(XmlParserTest, TestNamespace) {
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<top xmlns='my-namespace' a='b'/>");
EXPECT_EQ("START (my-namespace:top, xmlns='my-namespace', a='b') END ",
handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<foo:top xmlns:foo='my-namespace' "
"a='b' foo:c='d'/>");
EXPECT_EQ("START (my-namespace:top, "
"http://www.w3.org/2000/xmlns/:foo='my-namespace', "
"a='b', my-namespace:c='d') END ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<top><nested xmlns='my-namespace'><leaf/>"
"</nested><sibling/></top>");
EXPECT_EQ("START (top) START (my-namespace:nested, xmlns='my-namespace') "
"START (my-namespace:leaf) END END START (sibling) END END ",
handler.Str());
}
}
TEST(XmlParserTest, TestIncremental) {
XmlParserTestHandler handler;
XmlParser parser(&handler);
std::string fragment;
fragment = "<stream:stream";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("", handler.StrClear());
fragment = " id=\"abcdefg\" xmlns=\"";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("", handler.StrClear());
fragment = "j:c\" xmlns:stream='hm";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("", handler.StrClear());
fragment = "ph'><test";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (hmph:stream, id='abcdefg', xmlns='j:c', "
"http://www.w3.org/2000/xmlns/:stream='hmph') ", handler.StrClear());
fragment = "ing/><again/>abracad";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (j:c:testing) END START (j:c:again) END TEXT (abracad) ",
handler.StrClear());
fragment = "abra</stream:";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("TEXT (abra) ", handler.StrClear());
fragment = "stream>";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("END ", handler.StrClear());
}
TEST(XmlParserTest, TestReset) {
{
XmlParserTestHandler handler;
XmlParser parser(&handler);
std::string fragment;
fragment = "<top><first/><second><third></third>";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (top) START (first) END START (second) START (third) END ",
handler.StrClear());
parser.Reset();
fragment = "<tip><first/><second><third></third>";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (tip) START (first) END START (second) START (third) END ",
handler.StrClear());
}
{
XmlParserTestHandler handler;
XmlParser parser(&handler);
std::string fragment;
fragment = "<top xmlns='m'>";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (m:top, xmlns='m') ", handler.StrClear());
fragment = "<testing/><frag";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (m:testing) END ", handler.StrClear());
parser.Reset();
fragment = "<testing><fragment/";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (testing) ", handler.StrClear());
fragment = ">";
parser.Parse(fragment.c_str(), fragment.length(), false);
EXPECT_EQ("START (fragment) END ", handler.StrClear());
}
}
TEST(XmlParserTest, TestError) {
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "junk");
EXPECT_EQ("ERROR (2) ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<top/> garbage ");
EXPECT_EQ("START (top) END ERROR (9) ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<-hm->");
EXPECT_EQ("ERROR (4) ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler, "<hello>&foobar;</hello>");
EXPECT_EQ("START (hello) ERROR (11) ", handler.Str());
}
{
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<!DOCTYPE HTML PUBLIC \"foobar\" \"barfoo\">");
EXPECT_EQ("ERROR (3) ", handler.Str());
}
{
// XmlParser requires utf-8
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><test/>");
EXPECT_EQ("ERROR (19) ", handler.Str());
}
{
// XmlParser requires version 1.0
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<?xml version=\"2.0\"?><test/>");
EXPECT_EQ("ERROR (2) ", handler.Str());
}
{
// XmlParser requires standalone documents
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<?xml version=\"1.0\" standalone=\"no\"?><test/>");
EXPECT_EQ("ERROR (2) ", handler.Str());
}
{
// XmlParser doesn't like empty namespace URIs
XmlParserTestHandler handler;
XmlParser::ParseXml(&handler,
"<test xmlns:foo='' foo:bar='huh?'>");
EXPECT_EQ("ERROR (2) ", handler.Str());
}
}

View File

@ -1,191 +0,0 @@
/*
* 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/xmllite/xmlprinter.h"
#include <sstream>
#include <string>
#include <vector>
#include "talk/xmllite/xmlconstants.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmllite/xmlnsstack.h"
namespace buzz {
class XmlPrinterImpl {
public:
XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack);
void PrintElement(const XmlElement* element);
void PrintQuotedValue(const std::string& text);
void PrintBodyText(const std::string& text);
void PrintCDATAText(const std::string& text);
private:
std::ostream *pout_;
XmlnsStack* ns_stack_;
};
void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element) {
XmlnsStack ns_stack;
PrintXml(pout, element, &ns_stack);
}
void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element,
XmlnsStack* ns_stack) {
XmlPrinterImpl printer(pout, ns_stack);
printer.PrintElement(element);
}
XmlPrinterImpl::XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack)
: pout_(pout),
ns_stack_(ns_stack) {
}
void XmlPrinterImpl::PrintElement(const XmlElement* element) {
ns_stack_->PushFrame();
// first go through attrs of pel to add xmlns definitions
const XmlAttr* attr;
for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
if (attr->Name() == QN_XMLNS) {
ns_stack_->AddXmlns(STR_EMPTY, attr->Value());
} else if (attr->Name().Namespace() == NS_XMLNS) {
ns_stack_->AddXmlns(attr->Name().LocalPart(),
attr->Value());
}
}
// then go through qnames to make sure needed xmlns definitons are added
std::vector<std::string> new_ns;
std::pair<std::string, bool> prefix;
prefix = ns_stack_->AddNewPrefix(element->Name().Namespace(), false);
if (prefix.second) {
new_ns.push_back(prefix.first);
new_ns.push_back(element->Name().Namespace());
}
for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
prefix = ns_stack_->AddNewPrefix(attr->Name().Namespace(), true);
if (prefix.second) {
new_ns.push_back(prefix.first);
new_ns.push_back(attr->Name().Namespace());
}
}
// print the element name
*pout_ << '<' << ns_stack_->FormatQName(element->Name(), false);
// and the attributes
for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
*pout_ << ' ' << ns_stack_->FormatQName(attr->Name(), true) << "=\"";
PrintQuotedValue(attr->Value());
*pout_ << '"';
}
// and the extra xmlns declarations
std::vector<std::string>::iterator i(new_ns.begin());
while (i < new_ns.end()) {
if (*i == STR_EMPTY) {
*pout_ << " xmlns=\"" << *(i + 1) << '"';
} else {
*pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"';
}
i += 2;
}
// now the children
const XmlChild* child = element->FirstChild();
if (child == NULL)
*pout_ << "/>";
else {
*pout_ << '>';
while (child) {
if (child->IsText()) {
if (element->IsCDATA()) {
PrintCDATAText(child->AsText()->Text());
} else {
PrintBodyText(child->AsText()->Text());
}
} else {
PrintElement(child->AsElement());
}
child = child->NextChild();
}
*pout_ << "</" << ns_stack_->FormatQName(element->Name(), false) << '>';
}
ns_stack_->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;
}
}
void XmlPrinterImpl::PrintCDATAText(const std::string& text) {
*pout_ << "<![CDATA[" << text << "]]>";
}
} // namespace buzz

View File

@ -1,49 +0,0 @@
/*
* 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 TALK_XMLLITE_XMLPRINTER_H_
#define TALK_XMLLITE_XMLPRINTER_H_
#include <iosfwd>
#include <string>
namespace buzz {
class XmlElement;
class XmlnsStack;
class XmlPrinter {
public:
static void PrintXml(std::ostream* pout, const XmlElement* pelt);
static void PrintXml(std::ostream* pout, const XmlElement* pelt,
XmlnsStack* ns_stack);
};
} // namespace buzz
#endif // TALK_XMLLITE_XMLPRINTER_H_

View File

@ -1,62 +0,0 @@
/*
* libjingle
* Copyright 2004, 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/xmllite/xmlprinter.h"
#include <sstream>
#include <string>
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlelement.h"
#include "talk/xmllite/xmlnsstack.h"
#include "webrtc/base/common.h"
#include "webrtc/base/gunit.h"
using buzz::QName;
using buzz::XmlElement;
using buzz::XmlnsStack;
using buzz::XmlPrinter;
TEST(XmlPrinterTest, TestBasicPrinting) {
XmlElement elt(QName("google:test", "first"));
std::stringstream ss;
XmlPrinter::PrintXml(&ss, &elt);
EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", ss.str());
}
TEST(XmlPrinterTest, TestNamespacedPrinting) {
XmlElement elt(QName("google:test", "first"));
elt.AddElement(new XmlElement(QName("nested:test", "second")));
std::stringstream ss;
XmlnsStack ns_stack;
ns_stack.AddXmlns("gg", "google:test");
ns_stack.AddXmlns("", "nested:test");
XmlPrinter::PrintXml(&ss, &elt, &ns_stack);
EXPECT_EQ("<gg:first><second/></gg:first>", ss.str());
}