1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_XMLLITE_XMLELEMENT_H_ 29 #define TALK_XMLLITE_XMLELEMENT_H_ 30 31 #include <iosfwd> 32 #include <string> 33 34 #include "talk/base/scoped_ptr.h" 35 #include "talk/xmllite/qname.h" 36 37 namespace buzz { 38 39 class XmlChild; 40 class XmlText; 41 class XmlElement; 42 class XmlAttr; 43 44 class XmlChild { 45 public: NextChild()46 XmlChild* NextChild() { return next_child_; } NextChild()47 const XmlChild* NextChild() const { return next_child_; } 48 IsText()49 bool IsText() const { return IsTextImpl(); } 50 AsElement()51 XmlElement* AsElement() { return AsElementImpl(); } AsElement()52 const XmlElement* AsElement() const { return AsElementImpl(); } 53 AsText()54 XmlText* AsText() { return AsTextImpl(); } AsText()55 const XmlText* AsText() const { return AsTextImpl(); } 56 57 58 protected: XmlChild()59 XmlChild() : 60 next_child_(NULL) { 61 } 62 63 virtual bool IsTextImpl() const = 0; 64 virtual XmlElement* AsElementImpl() const = 0; 65 virtual XmlText* AsTextImpl() const = 0; 66 67 68 virtual ~XmlChild(); 69 70 private: 71 friend class XmlElement; 72 73 XmlChild(const XmlChild& noimpl); 74 75 XmlChild* next_child_; 76 }; 77 78 class XmlText : public XmlChild { 79 public: XmlText(const std::string & text)80 explicit XmlText(const std::string& text) : 81 XmlChild(), 82 text_(text) { 83 } XmlText(const XmlText & t)84 explicit XmlText(const XmlText& t) : 85 XmlChild(), 86 text_(t.text_) { 87 } XmlText(const char * cstr,size_t len)88 explicit XmlText(const char* cstr, size_t len) : 89 XmlChild(), 90 text_(cstr, len) { 91 } 92 virtual ~XmlText(); 93 Text()94 const std::string& Text() const { return text_; } 95 void SetText(const std::string& text); 96 void AddParsedText(const char* buf, int len); 97 void AddText(const std::string& text); 98 99 protected: 100 virtual bool IsTextImpl() const; 101 virtual XmlElement* AsElementImpl() const; 102 virtual XmlText* AsTextImpl() const; 103 104 private: 105 std::string text_; 106 }; 107 108 class XmlAttr { 109 public: NextAttr()110 XmlAttr* NextAttr() const { return next_attr_; } Name()111 const QName& Name() const { return name_; } Value()112 const std::string& Value() const { return value_; } 113 114 private: 115 friend class XmlElement; 116 XmlAttr(const QName & name,const std::string & value)117 explicit XmlAttr(const QName& name, const std::string& value) : 118 next_attr_(NULL), 119 name_(name), 120 value_(value) { 121 } XmlAttr(const XmlAttr & att)122 explicit XmlAttr(const XmlAttr& att) : 123 next_attr_(NULL), 124 name_(att.name_), 125 value_(att.value_) { 126 } 127 128 XmlAttr* next_attr_; 129 QName name_; 130 std::string value_; 131 }; 132 133 class XmlElement : public XmlChild { 134 public: 135 explicit XmlElement(const QName& name); 136 explicit XmlElement(const QName& name, bool useDefaultNs); 137 explicit XmlElement(const XmlElement& elt); 138 139 virtual ~XmlElement(); 140 Name()141 const QName& Name() const { return name_; } SetName(const QName & name)142 void SetName(const QName& name) { name_ = name; } 143 144 const std::string BodyText() const; 145 void SetBodyText(const std::string& text); 146 147 const QName FirstElementName() const; 148 149 XmlAttr* FirstAttr(); FirstAttr()150 const XmlAttr* FirstAttr() const 151 { return const_cast<XmlElement *>(this)->FirstAttr(); } 152 153 // Attr will return an empty string if the attribute isn't there: 154 // use HasAttr to test presence of an attribute. 155 const std::string Attr(const StaticQName& name) const; 156 const std::string Attr(const QName& name) const; 157 bool HasAttr(const StaticQName& name) const; 158 bool HasAttr(const QName& name) const; 159 void SetAttr(const QName& name, const std::string& value); 160 void ClearAttr(const QName& name); 161 162 XmlChild* FirstChild(); FirstChild()163 const XmlChild* FirstChild() const { 164 return const_cast<XmlElement *>(this)->FirstChild(); 165 } 166 167 XmlElement* FirstElement(); FirstElement()168 const XmlElement* FirstElement() const { 169 return const_cast<XmlElement *>(this)->FirstElement(); 170 } 171 172 XmlElement* NextElement(); NextElement()173 const XmlElement* NextElement() const { 174 return const_cast<XmlElement *>(this)->NextElement(); 175 } 176 177 XmlElement* FirstWithNamespace(const std::string& ns); FirstWithNamespace(const std::string & ns)178 const XmlElement* FirstWithNamespace(const std::string& ns) const { 179 return const_cast<XmlElement *>(this)->FirstWithNamespace(ns); 180 } 181 182 XmlElement* NextWithNamespace(const std::string& ns); NextWithNamespace(const std::string & ns)183 const XmlElement* NextWithNamespace(const std::string& ns) const { 184 return const_cast<XmlElement *>(this)->NextWithNamespace(ns); 185 } 186 187 XmlElement* FirstNamed(const StaticQName& name); FirstNamed(const StaticQName & name)188 const XmlElement* FirstNamed(const StaticQName& name) const { 189 return const_cast<XmlElement *>(this)->FirstNamed(name); 190 } 191 192 XmlElement* FirstNamed(const QName& name); FirstNamed(const QName & name)193 const XmlElement* FirstNamed(const QName& name) const { 194 return const_cast<XmlElement *>(this)->FirstNamed(name); 195 } 196 197 XmlElement* NextNamed(const StaticQName& name); NextNamed(const StaticQName & name)198 const XmlElement* NextNamed(const StaticQName& name) const { 199 return const_cast<XmlElement *>(this)->NextNamed(name); 200 } 201 202 XmlElement* NextNamed(const QName& name); NextNamed(const QName & name)203 const XmlElement* NextNamed(const QName& name) const { 204 return const_cast<XmlElement *>(this)->NextNamed(name); 205 } 206 207 // Finds the first element named 'name'. If that element can't be found then 208 // adds one and returns it. 209 XmlElement* FindOrAddNamedChild(const QName& name); 210 211 const std::string TextNamed(const QName& name) const; 212 213 void InsertChildAfter(XmlChild* predecessor, XmlChild* new_child); 214 void RemoveChildAfter(XmlChild* predecessor); 215 216 void AddParsedText(const char* buf, int len); 217 // Note: CDATA is not supported by XMPP, therefore using this function will 218 // generate non-XMPP compatible XML. 219 void AddCDATAText(const char* buf, int len); 220 void AddText(const std::string& text); 221 void AddText(const std::string& text, int depth); 222 void AddElement(XmlElement* child); 223 void AddElement(XmlElement* child, int depth); 224 void AddAttr(const QName& name, const std::string& value); 225 void AddAttr(const QName& name, const std::string& value, int depth); 226 void ClearNamedChildren(const QName& name); 227 void ClearAttributes(); 228 void ClearChildren(); 229 230 static XmlElement* ForStr(const std::string& str); 231 std::string Str() const; 232 IsCDATA()233 bool IsCDATA() const { return cdata_; } 234 235 protected: 236 virtual bool IsTextImpl() const; 237 virtual XmlElement* AsElementImpl() const; 238 virtual XmlText* AsTextImpl() const; 239 240 private: 241 QName name_; 242 XmlAttr* first_attr_; 243 XmlAttr* last_attr_; 244 XmlChild* first_child_; 245 XmlChild* last_child_; 246 bool cdata_; 247 }; 248 249 } // namespace buzz 250 251 #endif // TALK_XMLLITE_XMLELEMENT_H_ 252