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
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
00070 StreamStart,
00071 StreamEnd,
00072 StreamError,
00073 StreamFeatures,
00074 Register,
00075 Starttls,
00076 Handshake,
00077 Auth,
00078 Challenge,
00079 Abort,
00080 Aborted,
00081 Response,
00082 Proceed,
00083 Success,
00084 Failure,
00085 Mechanisms,
00086 Mechanism,
00087 Session,
00088
00089 Iq,
00090 Message,
00091 Presence,
00092
00093 Error,
00094 Query,
00095 VCard,
00096 Jingle,
00097
00098 Description,
00099 PayloadType,
00100
00101 Transport,
00102 Candidate,
00103
00104 Body,
00105 Subject,
00106
00107 Feature,
00108 Bind,
00109 Resource,
00110
00111 Transfer,
00112 Hold,
00113 Active,
00114 Ringing,
00115 Mute,
00116
00117 Registered,
00118 Remove,
00119 Jid,
00120 Username,
00121 Password,
00122 Digest,
00123 Required,
00124 Dtmf,
00125 DtmfMethod,
00126 Command,
00127 Text,
00128 Item,
00129 Group,
00130 Reason,
00131 Content,
00132 Parameter,
00133 Crypto,
00134 CryptoRequired,
00135 Trying,
00136 Received,
00137 File,
00138 Offer,
00139 Request,
00140 StreamHost,
00141 StreamHostUsed,
00142 Unknown,
00143 Invalid,
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
00498 inline void setType() {
00499 m_name = name();
00500 m_type = (Type)lookup(name(),s_names,Unknown);
00501 }
00502
00503 Type m_type;
00504 bool m_owner;
00505 String m_name;
00506 TiXmlElement* m_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;
00580 bool m_findstart;
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;
00693 String m_buffer;
00694 u_int32_t m_offset;
00695 String m_id;
00696 bool m_unclose;
00697 bool m_sent;
00698 };
00699
00700 };
00701
00702 #endif
00703
00704