Home | History | Annotate | Download | only in xmllite
      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