• 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 _xmlelement_h_
29 #define _xmlelement_h_
30 
31 #include <iosfwd>
32 #include <string>
33 #include "talk/base/scoped_ptr.h"
34 #include "talk/xmllite/qname.h"
35 
36 namespace buzz {
37 
38 extern const QName QN_EMPTY;
39 extern const QName QN_XMLNS;
40 
41 
42 class XmlChild;
43 class XmlText;
44 class XmlElement;
45 class XmlAttr;
46 
47 class XmlChild {
48 friend class XmlElement;
49 
50 public:
51 
NextChild()52   XmlChild * NextChild() { return pNextChild_; }
NextChild()53   const XmlChild * NextChild() const { return pNextChild_; }
54 
IsText()55   bool IsText() const { return IsTextImpl(); }
56 
AsElement()57   XmlElement * AsElement() { return AsElementImpl(); }
AsElement()58   const XmlElement * AsElement() const { return AsElementImpl(); }
59 
AsText()60   XmlText * AsText() { return AsTextImpl(); }
AsText()61   const XmlText * AsText() const { return AsTextImpl(); }
62 
63 
64 protected:
65 
XmlChild()66   XmlChild() :
67     pNextChild_(NULL) {
68   }
69 
70   virtual bool IsTextImpl() const = 0;
71   virtual XmlElement * AsElementImpl() const = 0;
72   virtual XmlText * AsTextImpl() const = 0;
73 
74 
75   virtual ~XmlChild();
76 
77 private:
78   XmlChild(const XmlChild & noimpl);
79 
80   XmlChild * pNextChild_;
81 
82 };
83 
84 class XmlText : public XmlChild {
85 public:
XmlText(const std::string & text)86   explicit XmlText(const std::string & text) :
87     XmlChild(),
88     text_(text) {
89   }
XmlText(const XmlText & t)90   explicit XmlText(const XmlText & t) :
91     XmlChild(),
92     text_(t.text_) {
93   }
XmlText(const char * cstr,size_t len)94   explicit XmlText(const char * cstr, size_t len) :
95     XmlChild(),
96     text_(cstr, len) {
97   }
98   virtual ~XmlText();
99 
Text()100   const std::string & Text() const { return text_; }
101   void SetText(const std::string & text);
102   void AddParsedText(const char * buf, int len);
103   void AddText(const std::string & text);
104 
105 protected:
106   virtual bool IsTextImpl() const;
107   virtual XmlElement * AsElementImpl() const;
108   virtual XmlText * AsTextImpl() const;
109 
110 private:
111   std::string text_;
112 };
113 
114 class XmlAttr {
115 friend class XmlElement;
116 
117 public:
NextAttr()118   XmlAttr * NextAttr() const { return pNextAttr_; }
Name()119   const QName & Name() const { return name_; }
Value()120   const std::string & Value() const { return value_; }
121 
122 private:
XmlAttr(const QName & name,const std::string & value)123   explicit XmlAttr(const QName & name, const std::string & value) :
124     pNextAttr_(NULL),
125     name_(name),
126     value_(value) {
127   }
XmlAttr(const XmlAttr & att)128   explicit XmlAttr(const XmlAttr & att) :
129     pNextAttr_(NULL),
130     name_(att.name_),
131     value_(att.value_) {
132   }
133 
134   XmlAttr * pNextAttr_;
135   QName name_;
136   std::string value_;
137 };
138 
139 class XmlElement : public XmlChild {
140 public:
141   explicit XmlElement(const QName & name);
142   explicit XmlElement(const QName & name, bool useDefaultNs);
143   explicit XmlElement(const XmlElement & elt);
144 
145   virtual ~XmlElement();
146 
Name()147   const QName& Name() const { return name_; }
SetName(const QName & name)148   void SetName(const QName& name) { name_ = name; }
149 
150   const std::string & BodyText() const;
151   void SetBodyText(const std::string & text);
152 
153   const QName & FirstElementName() const;
154 
155   XmlAttr * FirstAttr();
FirstAttr()156   const XmlAttr * FirstAttr() const
157     { return const_cast<XmlElement *>(this)->FirstAttr(); }
158 
159   //! Attr will return STR_EMPTY if the attribute isn't there:
160   //! use HasAttr to test presence of an attribute.
161   const std::string & Attr(const QName & name) const;
162   bool HasAttr(const QName & name) const;
163   void SetAttr(const QName & name, const std::string & value);
164   void ClearAttr(const QName & name);
165 
166   XmlChild * FirstChild();
FirstChild()167   const XmlChild * FirstChild() const
168     { return const_cast<XmlElement *>(this)->FirstChild(); }
169 
170   XmlElement * FirstElement();
FirstElement()171   const XmlElement * FirstElement() const
172     { return const_cast<XmlElement *>(this)->FirstElement(); }
173 
174   XmlElement * NextElement();
NextElement()175   const XmlElement * NextElement() const
176     { return const_cast<XmlElement *>(this)->NextElement(); }
177 
178   XmlElement * FirstWithNamespace(const std::string & ns);
FirstWithNamespace(const std::string & ns)179   const XmlElement * FirstWithNamespace(const std::string & ns) const
180     { return const_cast<XmlElement *>(this)->FirstWithNamespace(ns); }
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   XmlElement * FirstNamed(const QName & name);
FirstNamed(const QName & name)187   const XmlElement * FirstNamed(const QName & name) const
188     { return const_cast<XmlElement *>(this)->FirstNamed(name); }
189 
190   XmlElement * NextNamed(const QName & name);
NextNamed(const QName & name)191   const XmlElement * NextNamed(const QName & name) const
192     { return const_cast<XmlElement *>(this)->NextNamed(name); }
193 
194   // Finds the first element named 'name'.  If that element can't be found then
195   // adds one and returns it.
196   XmlElement* FindOrAddNamedChild(const QName& name);
197 
198   const std::string & TextNamed(const QName & name) const;
199 
200   void InsertChildAfter(XmlChild * pPredecessor, XmlChild * pNewChild);
201   void RemoveChildAfter(XmlChild * pPredecessor);
202 
203   void AddParsedText(const char * buf, int len);
204   // Note: CDATA is not supported by XMPP, therefore using this function will
205   // generate non-XMPP compatible XML.
206   void AddCDATAText(const char * buf, int len);
207   void AddText(const std::string & text);
208   void AddText(const std::string & text, int depth);
209   void AddElement(XmlElement * pelChild);
210   void AddElement(XmlElement * pelChild, int depth);
211   void AddAttr(const QName & name, const std::string & value);
212   void AddAttr(const QName & name, const std::string & value, int depth);
213   void ClearNamedChildren(const QName & name);
214   void ClearAttributes();
215   void ClearChildren();
216 
217   static XmlElement * ForStr(const std::string & str);
218   std::string Str() const;
219 
220   void Print(std::ostream * pout, std::string xmlns[], int xmlnsCount) const;
221 
IsCDATA()222   bool IsCDATA() const { return cdata_; }
223 
224 protected:
225   virtual bool IsTextImpl() const;
226   virtual XmlElement * AsElementImpl() const;
227   virtual XmlText * AsTextImpl() const;
228 
229 private:
230   QName name_;
231   XmlAttr * pFirstAttr_;
232   XmlAttr * pLastAttr_;
233   XmlChild * pFirstChild_;
234   XmlChild * pLastChild_;
235   bool cdata_;
236 };
237 
238 }
239 #endif
240