Yate
|
00001 00024 #ifndef __XMLPARSER_H 00025 #define __XMLPARSER_H 00026 00027 #include <yateclass.h> 00028 #include <tinyxml.h> 00029 00030 #ifdef _WINDOWS 00031 00032 #ifdef LIBYJINGLE_EXPORTS 00033 #define YJINGLE_API __declspec(dllexport) 00034 #else 00035 #ifndef LIBYJINGLE_STATIC 00036 #define YJINGLE_API __declspec(dllimport) 00037 #endif 00038 #endif 00039 00040 #endif /* _WINDOWS */ 00041 00042 #ifndef YJINGLE_API 00043 #define YJINGLE_API 00044 #endif 00045 00049 namespace TelEngine { 00050 00051 #define XMLPARSER_MAXDATABUFFER 8192 // Default max data buffer 00052 00053 class XMLElement; 00054 class XMLParser; 00055 class XMLElementOut; 00056 00061 class YJINGLE_API XMLElement : public GenObject 00062 { 00063 friend class XMLParser; 00064 public: 00068 enum Type { 00069 // *** Stream related elements 00070 StreamStart, // stream:stream 00071 StreamEnd, // /stream:stream 00072 StreamError, // stream::error 00073 StreamFeatures, // stream::features 00074 Register, // register 00075 Starttls, // starttls 00076 Handshake, // handshake 00077 Auth, // auth 00078 Challenge, // challenge 00079 Abort, // abort 00080 Aborted, // aborted 00081 Response, // response 00082 Proceed, // proceed 00083 Success, // success 00084 Failure, // failure 00085 Mechanisms, // mechanisms 00086 Mechanism, // mechanism 00087 Session, // session 00088 // *** Stanzas 00089 Iq, // iq 00090 Message, // message 00091 Presence, // presence 00092 // *** Stanza children 00093 Error, // error 00094 Query, // query 00095 VCard, // vCard 00096 Jingle, // session 00097 // Description 00098 Description, // description 00099 PayloadType, // payload-type 00100 // Transport 00101 Transport, // transport 00102 Candidate, // candidate 00103 // Message 00104 Body, // body 00105 Subject, // subject 00106 // Resources 00107 Feature, // feature 00108 Bind, // bind 00109 Resource, // resource 00110 // Jingle session info 00111 Transfer, // transfer 00112 Hold, // hold 00113 Active, // active 00114 Ringing, // ringing 00115 Mute, // mute 00116 // Miscellaneous 00117 Registered, // registered 00118 Remove, // remove 00119 Jid, // jid 00120 Username, // username 00121 Password, // password 00122 Digest, // digest 00123 Required, // required 00124 Dtmf, // dtmf 00125 DtmfMethod, // dtmf-method 00126 Command, // command 00127 Text, // text 00128 Item, // item 00129 Group, // group 00130 Reason, // reason 00131 Content, // content 00132 Parameter, // parameter 00133 Crypto, // crypto 00134 CryptoRequired, // crypto-required 00135 Trying, // trying 00136 Received, // received 00137 File, // file 00138 Offer, // offer 00139 Request, // request 00140 StreamHost, // streamhost 00141 StreamHostUsed, // streamhost-used 00142 Unknown, // Any text 00143 Invalid, // m_element is 0 00144 }; 00145 00150 XMLElement(); 00151 00156 XMLElement(const XMLElement& src); 00157 00166 XMLElement(const XMLElement& src, bool response, bool result); 00167 00176 XMLElement(const char* name, NamedList* attributes = 0, const char* text = 0); 00177 00186 XMLElement(Type type, NamedList* attributes = 0, const char* text = 0); 00187 00197 XMLElement(NamedList& src, const char* prefix); 00198 00202 virtual ~XMLElement(); 00203 00208 inline Type type() const 00209 { return m_type; } 00210 00215 inline const char* name() const 00216 { return valid() ? m_element->Value() : 0; } 00217 00223 inline bool nameIs(const char* text) const 00224 { return (text && name() && (0 == ::strcmp(name(),text))); } 00225 00230 inline bool valid() const 00231 { return m_element != 0; } 00232 00237 inline void changeType(Type t) 00238 { m_type = t; } 00239 00245 void toString(String& dest, bool unclose = false) const; 00246 00252 void toList(NamedList& dest, const char* prefix); 00253 00259 void setAttribute(const char* name, const char* value); 00260 00266 inline void setAttributeValid(const char* name, const String& value) { 00267 if (value) 00268 setAttribute(name,value); 00269 } 00270 00276 inline void setAttribute(const char* name, int value) { 00277 String s(value); 00278 setAttribute(name,s); 00279 } 00280 00286 const char* getAttribute(const char* name) const; 00287 00294 inline bool getAttribute(const char* name, String& value) const { 00295 value = getAttribute(name); 00296 return 0 != value.length(); 00297 } 00298 00303 void getAttributes(NamedList& dest) const; 00304 00311 bool hasAttribute(const char* name, const char* value) const; 00312 00317 const char* getText() const; 00318 00323 void addChild(XMLElement* element); 00324 00333 XMLElement* removeChild(const char* name = 0); 00334 00343 inline XMLElement* removeChild(Type type) 00344 { return removeChild(typeName(type)); } 00345 00352 XMLElement* findFirstChild(const char* name = 0); 00353 00360 inline XMLElement* findFirstChild(Type type) 00361 { return findFirstChild(typeName(type)); } 00362 00368 inline bool hasChild(const char* name) { 00369 XMLElement* tmp = findFirstChild(name); 00370 bool ok = (0 != tmp); 00371 TelEngine::destruct(tmp); 00372 return ok; 00373 } 00374 00380 inline bool hasChild(Type type) 00381 { return hasChild(typeName(type)); } 00382 00390 XMLElement* findNextChild(XMLElement* element, const char* name = 0); 00391 00399 inline XMLElement* findNextChild(XMLElement* element, Type type) 00400 { return findNextChild(element,typeName(type)); } 00401 00406 inline const TiXmlAttribute* firstAttribute() const 00407 { return valid() ? m_element->FirstAttribute() : 0; } 00408 00414 static inline const char* typeName(Type type) 00415 { return lookup(type,s_names); } 00416 00423 static inline bool isType(const char* txt, Type type) { 00424 const char* s = typeName(type); 00425 return (txt && s && (0 == ::strcmp(txt,s))); 00426 } 00427 00431 virtual void* getObject(const String& name) const { 00432 if (name == "XMLElement") 00433 return (void*)this; 00434 return GenObject::getObject(name); 00435 } 00436 00440 virtual const String& toString() const 00441 { return m_name; } 00442 00446 virtual void destruct() { 00447 if (m_owner && m_element) 00448 delete m_element; 00449 m_element = 0; 00450 GenObject::destruct(); 00451 } 00452 00462 static XMLElement* getXml(NamedList& list, bool stole = false, 00463 const char* name = "xml", const char* value = 0); 00464 00468 static TokenDict s_names[]; 00469 00470 protected: 00480 XMLElement(TiXmlElement* element, bool owner); 00481 00486 inline TiXmlElement* get() const 00487 { return m_element; } 00488 00494 TiXmlElement* releaseOwnership(); 00495 00496 private: 00497 // Set this object's type from m_element's name 00498 inline void setType() { 00499 m_name = name(); 00500 m_type = (Type)lookup(name(),s_names,Unknown); 00501 } 00502 00503 Type m_type; // Element's type 00504 bool m_owner; // Owner flag. If true, this object owns the XML element 00505 String m_name; // The name of this element 00506 TiXmlElement* m_element; // The underlying XML element 00507 }; 00508 00514 class YJINGLE_API XMLParser : public TiXmlDocument, public Mutex 00515 { 00516 public: 00521 inline XMLParser() 00522 : TiXmlDocument(), Mutex(true), m_findstart(true) 00523 {} 00524 00528 virtual ~XMLParser() 00529 {} 00530 00539 bool consume(const char* data, u_int32_t len); 00540 00547 XMLElement* extract(); 00548 00553 inline unsigned int bufLen() const 00554 { return m_buffer.length(); } 00555 00560 inline void getBuffer(String& dest) const 00561 { dest = m_buffer; } 00562 00566 void reset(); 00567 00571 static u_int32_t s_maxDataBuffer; 00572 00576 static TiXmlEncoding s_xmlEncoding; 00577 00578 private: 00579 String m_buffer; // Input data buffer 00580 bool m_findstart; // Search for stream start tag or not 00581 }; 00582 00587 class YJINGLE_API XMLElementOut : public RefObject 00588 { 00589 public: 00596 inline XMLElementOut(XMLElement* element, const char* senderID = 0, 00597 bool unclose = false) 00598 : m_element(element), m_offset(0), m_id(senderID), m_unclose(unclose), 00599 m_sent(false) 00600 {} 00601 00606 virtual ~XMLElementOut() 00607 { TelEngine::destruct(m_element); } 00608 00613 inline XMLElement* element() const 00614 { return m_element; } 00615 00620 inline bool sent() const 00621 { return m_sent; } 00622 00627 inline String& buffer() 00628 { return m_buffer; } 00629 00634 inline const String& id() const 00635 { return m_id; } 00636 00641 inline u_int32_t dataCount() 00642 { return m_buffer.length() - m_offset; } 00643 00649 inline const char* getData(u_int32_t& nCount) { 00650 if (!m_buffer) 00651 prepareToSend(); 00652 nCount = dataCount(); 00653 return m_buffer.c_str() + m_offset; 00654 } 00655 00660 inline void dataSent(u_int32_t nCount) { 00661 m_sent = true; 00662 m_offset += nCount; 00663 if (m_offset > m_buffer.length()) 00664 m_offset = m_buffer.length(); 00665 } 00666 00672 inline XMLElement* release() { 00673 XMLElement* e = m_element; 00674 m_element = 0; 00675 return e; 00676 } 00677 00682 inline void toBuffer(String& buffer) 00683 { if (m_element) m_element->toString(buffer,m_unclose); } 00684 00688 inline void prepareToSend() 00689 { toBuffer(m_buffer); } 00690 00691 private: 00692 XMLElement* m_element; // The XML element 00693 String m_buffer; // Data to send 00694 u_int32_t m_offset; // Offset to send 00695 String m_id; // Sender's id 00696 bool m_unclose; // Close or not the element's tag 00697 bool m_sent; // Sent flag (true if an attempt to send was done) 00698 }; 00699 00700 }; 00701 00702 #endif /* __XMLPARSER_H */ 00703 00704 /* vi: set ts=8 sw=4 sts=4 noet: */