00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef TAG_H__
00015 #define TAG_H__
00016
00017 #include "gloox.h"
00018
00019 #include <string>
00020 #include <list>
00021 #include <utility>
00022
00023 namespace gloox
00024 {
00025
00032 class GLOOX_API Tag
00033 {
00034 public:
00038 typedef std::pair<std::string, std::string> Attribute;
00039
00043 typedef std::list<Attribute> AttributeList;
00044
00048 typedef std::list<Tag*> TagList;
00049
00054 GLOOX_DEPRECATED_CTOR Tag();
00055
00063 explicit Tag( const std::string& name, const std::string& cdata = "", bool incoming = false );
00064
00074 explicit Tag( Tag *parent, const std::string& name, const std::string& cdata = "",
00075 bool incoming = false );
00076
00086 explicit Tag( const std::string& name, const std::string& attrib, const std::string& value,
00087 bool incoming = false );
00088
00100 explicit Tag( Tag *parent, const std::string& name, const std::string& attrib, const std::string& value,
00101 bool incoming = false );
00102
00106 virtual ~Tag();
00107
00113 virtual const std::string xml() const;
00114
00120 virtual void addAttribute( const std::string& name, const std::string& value );
00121
00128 virtual void addAttribute( const std::string& name, int value );
00129
00136 virtual void addAttribute( const std::string& name, long value );
00137
00143 virtual void setAttributes( const AttributeList& attributes ) { m_attribs = attributes; }
00144
00149 virtual void addChild( Tag *child );
00150
00156 virtual void addChildCopy( const Tag *child );
00157
00162 virtual void setCData( const std::string& cdata )
00163 { m_cdata = m_incoming ? relax( cdata ) : cdata; }
00164
00169 virtual void addCData( const std::string& cdata )
00170 { m_cdata += m_incoming ? relax( cdata ) : cdata; }
00171
00176 virtual const std::string& name() const { return m_name; }
00177
00182 virtual const std::string& cdata() const { return m_cdata; }
00183
00188 virtual AttributeList& attributes() { return m_attribs; }
00189
00194 virtual const AttributeList& attributes() const { return m_attribs; }
00195
00200 virtual TagList& children() { return m_children; }
00201
00206 virtual const TagList& children() const { return m_children; }
00207
00213 virtual const std::string findAttribute( const std::string& name ) const;
00214
00221 virtual bool hasAttribute( const std::string& name, const std::string& value = "" ) const;
00222
00229 virtual Tag* findChild( const std::string& name ) const;
00230
00239 virtual Tag* findChild( const std::string& name, const std::string& attr,
00240 const std::string& value = "" ) const;
00241
00250 virtual inline bool hasChild( const std::string& name, const std::string& attr = "",
00251 const std::string& value = "" ) const
00252 { return findChild( name, attr, value ) ? true : false; }
00253
00261 virtual Tag* findChildWithAttrib( const std::string& attr, const std::string& value = "" ) const;
00262
00270 virtual inline bool hasChildWithAttrib( const std::string& attr,
00271 const std::string& value = "" ) const
00272 { return findChildWithAttrib( attr, value ) ? true : false; }
00273
00281 TagList findChildren( const std::string& name ) const;
00282
00288 void removeChild( Tag *tag ) { m_children.remove(tag); }
00289
00295 virtual GLOOX_DEPRECATED bool empty() const { return m_name.empty(); }
00296
00304 bool hasChildWithCData( const std::string& name, const std::string& cdata ) const;
00305
00310 Tag* parent() const { return m_parent; }
00311
00316 virtual StanzaType type() const { return m_type; }
00317
00323 virtual Tag* clone() const;
00324
00335 Tag* findTag( const std::string& expression );
00336
00346 Tag::TagList findTagList( const std::string& expression );
00347
00353 bool operator==( const Tag &right ) const;
00354
00360 bool operator!=( const Tag &right ) const { return !( *this == right ); }
00361
00365 operator bool() const { return m_valid; }
00366
00372 static const std::string escape( std::string what );
00373
00379 static const std::string relax( std::string what );
00380
00381 protected:
00385 enum XPathError
00386 {
00387 XPNoError,
00388 XPExpectedLeftOperand,
00389 XPUnexpectedToken
00390 };
00391
00392 AttributeList m_attribs;
00393 std::string m_name;
00394 std::string m_cdata;
00395 TagList m_children;
00396 Tag *m_parent;
00397 StanzaType m_type;
00398 bool m_incoming;
00399
00400 private:
00401 enum TokenType
00402 {
00403 XTNone,
00404 XTLeftParenthesis,
00405 XTRightParenthesis,
00406 XTNodeSet,
00407 XTInteger,
00408 XTElement,
00409 XTLeftBracket,
00410 XTRightBracket,
00411 XTFunction,
00412 XTAsterisk,
00413 XTAttribute,
00414 XTLiteralInside,
00415 XTLiteral,
00416 XTDot,
00417 XTDoubleDot,
00418 XTOperatorOr,
00419 XTOperatorAnd,
00420 XTOperatorEq,
00421 XTOperatorNe,
00422 XTOperatorGt,
00423 XTOperatorLt,
00424 XTOperatorLtEq,
00425 XTOperatorGtEq,
00426 XTOperatorPlus,
00427 XTOperatorMinus,
00428 XTOperatorMul,
00429 XTOperatorDiv,
00430 XTOperatorMod,
00431 XTUnion,
00432 XTSlash,
00433 XTDoubleSlash
00434 };
00435
00436
00437 Tag* parse( const std::string& expression, unsigned& len, TokenType border = XTNone );
00438
00439 void closePreviousToken( Tag**, Tag**, TokenType&, std::string& );
00440 void addToken( Tag **root, Tag **current, TokenType type, const std::string& token );
00441 void addOperator( Tag **root, Tag **current, Tag *arg, TokenType type,
00442 const std::string& token );
00443 bool addPredicate( Tag **root, Tag **current, Tag *token );
00444
00445 TagList findChildren( const TagList& list, const std::string& name ) const;
00446 Tag::TagList evaluateTagList( Tag *token );
00447 Tag::TagList evaluateUnion( Tag *token );
00448 Tag::TagList allDescendants();
00449
00450 static TokenType getType( const std::string& c );
00451
00452 static bool isWhitespace( const char c );
00453 bool isNumber();
00454
00455 bool evaluateBoolean( Tag *token );
00456 bool evaluatePredicate( Tag *token ) { return evaluateBoolean( token ); }
00457 bool evaluateEquals( Tag *token );
00458
00459 static void add( Tag::TagList& one, const Tag::TagList& two );
00460
00461 bool m_valid;
00462 };
00463
00464 }
00465
00466 #endif // TAG_H__