gloox  0.9.9.12
tag.h
1 /*
2  Copyright (c) 2005-2008 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #ifndef TAG_H__
15 #define TAG_H__
16 
17 #include "gloox.h"
18 
19 #include <string>
20 #include <list>
21 #include <utility>
22 
23 namespace gloox
24 {
25 
32  class GLOOX_API Tag
33  {
34  public:
38  typedef std::pair<std::string, std::string> Attribute;
39 
43  typedef std::list<Attribute> AttributeList;
44 
48  typedef std::list<Tag*> TagList;
49 
54  GLOOX_DEPRECATED_CTOR Tag();
55 
63  explicit Tag( const std::string& name, const std::string& cdata = "", bool incoming = false );
64 
74  explicit Tag( Tag *parent, const std::string& name, const std::string& cdata = "",
75  bool incoming = false );
76 
86  explicit Tag( const std::string& name, const std::string& attrib, const std::string& value,
87  bool incoming = false );
88 
100  explicit Tag( Tag *parent, const std::string& name, const std::string& attrib, const std::string& value,
101  bool incoming = false );
102 
106  virtual ~Tag();
107 
113  virtual const std::string xml() const;
114 
120  virtual void addAttribute( const std::string& name, const std::string& value );
121 
128  virtual void addAttribute( const std::string& name, int value );
129 
136  virtual void addAttribute( const std::string& name, long value );
137 
143  virtual void setAttributes( const AttributeList& attributes ) { m_attribs = attributes; }
144 
149  virtual void addChild( Tag *child );
150 
156  virtual void addChildCopy( const Tag *child );
157 
162  virtual void setCData( const std::string& cdata )
163  { m_cdata = m_incoming ? relax( cdata ) : cdata; }
164 
169  virtual void addCData( const std::string& cdata )
170  { m_cdata += m_incoming ? relax( cdata ) : cdata; }
171 
176  virtual const std::string& name() const { return m_name; }
177 
182  virtual const std::string& cdata() const { return m_cdata; }
183 
188  virtual AttributeList& attributes() { return m_attribs; }
189 
194  virtual const AttributeList& attributes() const { return m_attribs; }
195 
200  virtual TagList& children() { return m_children; }
201 
206  virtual const TagList& children() const { return m_children; }
207 
213  virtual const std::string findAttribute( const std::string& name ) const;
214 
221  virtual bool hasAttribute( const std::string& name, const std::string& value = "" ) const;
222 
229  virtual Tag* findChild( const std::string& name ) const;
230 
239  virtual Tag* findChild( const std::string& name, const std::string& attr,
240  const std::string& value = "" ) const;
241 
250  virtual inline bool hasChild( const std::string& name, const std::string& attr = "",
251  const std::string& value = "" ) const
252  { return findChild( name, attr, value ) ? true : false; }
253 
261  virtual Tag* findChildWithAttrib( const std::string& attr, const std::string& value = "" ) const;
262 
270  virtual inline bool hasChildWithAttrib( const std::string& attr,
271  const std::string& value = "" ) const
272  { return findChildWithAttrib( attr, value ) ? true : false; }
273 
281  TagList findChildren( const std::string& name ) const;
282 
288  void removeChild( Tag *tag ) { m_children.remove(tag); }
289 
295  virtual GLOOX_DEPRECATED bool empty() const { return m_name.empty(); }
296 
304  bool hasChildWithCData( const std::string& name, const std::string& cdata ) const;
305 
310  Tag* parent() const { return m_parent; }
311 
316  virtual StanzaType type() const { return m_type; }
317 
323  virtual Tag* clone() const;
324 
335  Tag* findTag( const std::string& expression );
336 
346  Tag::TagList findTagList( const std::string& expression );
347 
353  bool operator==( const Tag &right ) const;
354 
360  bool operator!=( const Tag &right ) const { return !( *this == right ); }
361 
365  operator bool() const { return m_valid; }
366 
372  static const std::string escape( std::string what );
373 
379  static const std::string relax( std::string what );
380 
381  protected:
386  {
389  XPUnexpectedToken
390  };
391 
392  AttributeList m_attribs;
393  std::string m_name;
394  std::string m_cdata;
395  TagList m_children;
396  Tag *m_parent;
397  StanzaType m_type;
398  bool m_incoming;
399 
400  private:
401  enum TokenType
402  {
403  XTNone,
404  XTLeftParenthesis,
405  XTRightParenthesis,
406  XTNodeSet,
407  XTInteger,
408  XTElement,
409  XTLeftBracket,
410  XTRightBracket,
411  XTFunction,
412  XTAsterisk,
413  XTAttribute,
414  XTLiteralInside,
415  XTLiteral,
416  XTDot,
417  XTDoubleDot,
418  XTOperatorOr,
419  XTOperatorAnd,
420  XTOperatorEq,
421  XTOperatorNe,
422  XTOperatorGt,
423  XTOperatorLt,
424  XTOperatorLtEq,
425  XTOperatorGtEq,
426  XTOperatorPlus,
427  XTOperatorMinus,
428  XTOperatorMul,
429  XTOperatorDiv,
430  XTOperatorMod,
431  XTUnion,
432  XTSlash,
433  XTDoubleSlash
434  };
435 
436 
437  Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone );
438 
439  void closePreviousToken( Tag**, Tag**, TokenType&, std::string& );
440  void addToken( Tag **root, Tag **current, TokenType type, const std::string& token );
441  void addOperator( Tag **root, Tag **current, Tag *arg, TokenType type,
442  const std::string& token );
443  bool addPredicate( Tag **root, Tag **current, Tag *token );
444 
445  TagList findChildren( const TagList& list, const std::string& name ) const;
446  Tag::TagList evaluateTagList( Tag *token );
447  Tag::TagList evaluateUnion( Tag *token );
448  Tag::TagList allDescendants();
449 
450  static TokenType getType( const std::string& c );
451 
452  static bool isWhitespace( const char c );
453  bool isNumber();
454 
455  bool evaluateBoolean( Tag *token );
456  bool evaluatePredicate( Tag *token ) { return evaluateBoolean( token ); }
457  bool evaluateEquals( Tag *token );
458 
459  static void add( Tag::TagList& one, const Tag::TagList& two );
460 
461  bool m_valid;
462  };
463 
464 }
465 
466 #endif // TAG_H__