• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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