/* * 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 #include #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(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(this)->FirstChild(); } XmlElement* FirstElement(); const XmlElement* FirstElement() const { return const_cast(this)->FirstElement(); } XmlElement* NextElement(); const XmlElement* NextElement() const { return const_cast(this)->NextElement(); } XmlElement* FirstWithNamespace(const std::string& ns); const XmlElement* FirstWithNamespace(const std::string& ns) const { return const_cast(this)->FirstWithNamespace(ns); } XmlElement* NextWithNamespace(const std::string& ns); const XmlElement* NextWithNamespace(const std::string& ns) const { return const_cast(this)->NextWithNamespace(ns); } XmlElement* FirstNamed(const StaticQName& name); const XmlElement* FirstNamed(const StaticQName& name) const { return const_cast(this)->FirstNamed(name); } XmlElement* FirstNamed(const QName& name); const XmlElement* FirstNamed(const QName& name) const { return const_cast(this)->FirstNamed(name); } XmlElement* NextNamed(const StaticQName& name); const XmlElement* NextNamed(const StaticQName& name) const { return const_cast(this)->NextNamed(name); } XmlElement* NextNamed(const QName& name); const XmlElement* NextNamed(const QName& name) const { return const_cast(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_