1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_LIBJINGLE_XMLLITE_XMLELEMENT_H_ 12 #define WEBRTC_LIBJINGLE_XMLLITE_XMLELEMENT_H_ 13 14 #include <iosfwd> 15 #include <string> 16 17 #include "webrtc/libjingle/xmllite/qname.h" 18 #include "webrtc/base/scoped_ptr.h" 19 20 namespace buzz { 21 22 class XmlChild; 23 class XmlText; 24 class XmlElement; 25 class XmlAttr; 26 27 class XmlChild { 28 public: 29 XmlChild* NextChild() { return next_child_; } 30 const XmlChild* NextChild() const { return next_child_; } 31 32 bool IsText() const { return IsTextImpl(); } 33 34 XmlElement* AsElement() { return AsElementImpl(); } 35 const XmlElement* AsElement() const { return AsElementImpl(); } 36 37 XmlText* AsText() { return AsTextImpl(); } 38 const XmlText* AsText() const { return AsTextImpl(); } 39 40 41 protected: 42 XmlChild() : 43 next_child_(NULL) { 44 } 45 46 virtual bool IsTextImpl() const = 0; 47 virtual XmlElement* AsElementImpl() const = 0; 48 virtual XmlText* AsTextImpl() const = 0; 49 50 51 virtual ~XmlChild(); 52 53 private: 54 friend class XmlElement; 55 56 XmlChild(const XmlChild& noimpl); 57 58 XmlChild* next_child_; 59 }; 60 61 class XmlText : public XmlChild { 62 public: 63 explicit XmlText(const std::string& text) : 64 XmlChild(), 65 text_(text) { 66 } 67 explicit XmlText(const XmlText& t) : 68 XmlChild(), 69 text_(t.text_) { 70 } 71 explicit XmlText(const char* cstr, size_t len) : 72 XmlChild(), 73 text_(cstr, len) { 74 } 75 virtual ~XmlText(); 76 77 const std::string& Text() const { return text_; } 78 void SetText(const std::string& text); 79 void AddParsedText(const char* buf, int len); 80 void AddText(const std::string& text); 81 82 protected: 83 virtual bool IsTextImpl() const; 84 virtual XmlElement* AsElementImpl() const; 85 virtual XmlText* AsTextImpl() const; 86 87 private: 88 std::string text_; 89 }; 90 91 class XmlAttr { 92 public: 93 XmlAttr* NextAttr() const { return next_attr_; } 94 const QName& Name() const { return name_; } 95 const std::string& Value() const { return value_; } 96 97 private: 98 friend class XmlElement; 99 100 explicit XmlAttr(const QName& name, const std::string& value) : 101 next_attr_(NULL), 102 name_(name), 103 value_(value) { 104 } 105 explicit XmlAttr(const XmlAttr& att) : 106 next_attr_(NULL), 107 name_(att.name_), 108 value_(att.value_) { 109 } 110 111 XmlAttr* next_attr_; 112 QName name_; 113 std::string value_; 114 }; 115 116 class XmlElement : public XmlChild { 117 public: 118 explicit XmlElement(const QName& name); 119 explicit XmlElement(const QName& name, bool useDefaultNs); 120 explicit XmlElement(const XmlElement& elt); 121 122 virtual ~XmlElement(); 123 124 const QName& Name() const { return name_; } 125 void SetName(const QName& name) { name_ = name; } 126 127 const std::string BodyText() const; 128 void SetBodyText(const std::string& text); 129 130 const QName FirstElementName() const; 131 132 XmlAttr* FirstAttr(); 133 const XmlAttr* FirstAttr() const 134 { return const_cast<XmlElement *>(this)->FirstAttr(); } 135 136 // Attr will return an empty string if the attribute isn't there: 137 // use HasAttr to test presence of an attribute. 138 const std::string Attr(const StaticQName& name) const; 139 const std::string Attr(const QName& name) const; 140 bool HasAttr(const StaticQName& name) const; 141 bool HasAttr(const QName& name) const; 142 void SetAttr(const QName& name, const std::string& value); 143 void ClearAttr(const QName& name); 144 145 XmlChild* FirstChild(); 146 const XmlChild* FirstChild() const { 147 return const_cast<XmlElement *>(this)->FirstChild(); 148 } 149 150 XmlElement* FirstElement(); 151 const XmlElement* FirstElement() const { 152 return const_cast<XmlElement *>(this)->FirstElement(); 153 } 154 155 XmlElement* NextElement(); 156 const XmlElement* NextElement() const { 157 return const_cast<XmlElement *>(this)->NextElement(); 158 } 159 160 XmlElement* FirstWithNamespace(const std::string& ns); 161 const XmlElement* FirstWithNamespace(const std::string& ns) const { 162 return const_cast<XmlElement *>(this)->FirstWithNamespace(ns); 163 } 164 165 XmlElement* NextWithNamespace(const std::string& ns); 166 const XmlElement* NextWithNamespace(const std::string& ns) const { 167 return const_cast<XmlElement *>(this)->NextWithNamespace(ns); 168 } 169 170 XmlElement* FirstNamed(const StaticQName& name); 171 const XmlElement* FirstNamed(const StaticQName& name) const { 172 return const_cast<XmlElement *>(this)->FirstNamed(name); 173 } 174 175 XmlElement* FirstNamed(const QName& name); 176 const XmlElement* FirstNamed(const QName& name) const { 177 return const_cast<XmlElement *>(this)->FirstNamed(name); 178 } 179 180 XmlElement* NextNamed(const StaticQName& name); 181 const XmlElement* NextNamed(const StaticQName& name) const { 182 return const_cast<XmlElement *>(this)->NextNamed(name); 183 } 184 185 XmlElement* NextNamed(const QName& name); 186 const XmlElement* NextNamed(const QName& name) const { 187 return const_cast<XmlElement *>(this)->NextNamed(name); 188 } 189 190 // Finds the first element named 'name'. If that element can't be found then 191 // adds one and returns it. 192 XmlElement* FindOrAddNamedChild(const QName& name); 193 194 const std::string TextNamed(const QName& name) const; 195 196 void InsertChildAfter(XmlChild* predecessor, XmlChild* new_child); 197 void RemoveChildAfter(XmlChild* predecessor); 198 199 void AddParsedText(const char* buf, int len); 200 // Note: CDATA is not supported by XMPP, therefore using this function will 201 // generate non-XMPP compatible XML. 202 void AddCDATAText(const char* buf, int len); 203 void AddText(const std::string& text); 204 void AddText(const std::string& text, int depth); 205 void AddElement(XmlElement* child); 206 void AddElement(XmlElement* child, int depth); 207 void AddAttr(const QName& name, const std::string& value); 208 void AddAttr(const QName& name, const std::string& value, int depth); 209 void ClearNamedChildren(const QName& name); 210 void ClearAttributes(); 211 void ClearChildren(); 212 213 static XmlElement* ForStr(const std::string& str); 214 std::string Str() const; 215 216 bool IsCDATA() const { return cdata_; } 217 218 protected: 219 virtual bool IsTextImpl() const; 220 virtual XmlElement* AsElementImpl() const; 221 virtual XmlText* AsTextImpl() const; 222 223 private: 224 QName name_; 225 XmlAttr* first_attr_; 226 XmlAttr* last_attr_; 227 XmlChild* first_child_; 228 XmlChild* last_child_; 229 bool cdata_; 230 }; 231 232 } // namespace buzz 233 234 #endif // WEBRTC_LIBJINGLE_XMLLITE_XMLELEMENT_H_ 235