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 Jingle,
00096
00097 Description,
00098 PayloadType,
00099
00100 Transport,
00101 Candidate,
00102
00103 Body,
00104
00105 Feature,
00106 Bind,
00107 Resource,
00108
00109 Jid,
00110 Username,
00111 Password,
00112 Digest,
00113 Required,
00114 Dtmf,
00115 DtmfMethod,
00116 Command,
00117 Text,
00118 Item,
00119 Group,
00120 Unknown,
00121 Invalid,
00122 };
00123
00128 XMLElement();
00129
00134 XMLElement(const XMLElement& src);
00135
00144 XMLElement(const XMLElement& src, bool response, bool result);
00145
00154 XMLElement(const char* name, NamedList* attributes = 0, const char* text = 0);
00155
00164 XMLElement(Type type, NamedList* attributes = 0, const char* text = 0);
00165
00175 XMLElement(NamedList& src, const char* prefix);
00176
00180 virtual ~XMLElement();
00181
00186 inline Type type() const
00187 { return m_type; }
00188
00193 inline const char* name() const
00194 { return valid() ? m_element->Value() : 0; }
00195
00201 inline bool nameIs(const char* text) const
00202 { return (text && name() && (0 == ::strcmp(name(),text))); }
00203
00208 inline bool valid() const
00209 { return m_element != 0; }
00210
00215 inline void changeType(Type t)
00216 { m_type = t; }
00217
00223 void toString(String& dest, bool unclose = false) const;
00224
00230 void toList(NamedList& dest, const char* prefix);
00231
00237 void setAttribute(const char* name, const char* value);
00238
00244 inline void setAttributeValid(const char* name, const String& value) {
00245 if (value)
00246 setAttribute(name,value);
00247 }
00248
00254 inline void setAttribute(const char* name, int value) {
00255 String s(value);
00256 setAttribute(name,s);
00257 }
00258
00264 const char* getAttribute(const char* name) const;
00265
00272 inline bool getAttribute(const char* name, String& value) const {
00273 value = getAttribute(name);
00274 return 0 != value.length();
00275 }
00276
00283 bool hasAttribute(const char* name, const char* value) const;
00284
00289 const char* getText() const;
00290
00295 void addChild(XMLElement* element);
00296
00303 XMLElement* findFirstChild(const char* name = 0);
00304
00311 inline XMLElement* findFirstChild(Type type)
00312 { return findFirstChild(typeName(type)); }
00313
00319 inline bool hasChild(const char* name) {
00320 XMLElement* tmp = findFirstChild(name);
00321 bool ok = (0 != tmp);
00322 TelEngine::destruct(tmp);
00323 return ok;
00324 }
00325
00331 inline bool hasChild(Type type)
00332 { return hasChild(typeName(type)); }
00333
00341 XMLElement* findNextChild(XMLElement* element, const char* name = 0);
00342
00350 inline XMLElement* findNextChild(XMLElement* element, Type type)
00351 { return findNextChild(element,typeName(type)); }
00352
00357 inline const TiXmlAttribute* firstAttribute() const
00358 { return valid() ? m_element->FirstAttribute() : 0; }
00359
00365 static inline const char* typeName(Type type)
00366 { return lookup(type,s_names); }
00367
00374 static inline bool isType(const char* txt, Type type) {
00375 const char* s = typeName(type);
00376 return (txt && s && (0 == ::strcmp(txt,s)));
00377 }
00378
00382 virtual void* getObject(const String& name) const {
00383 if (name == "XMLElement")
00384 return (void*)this;
00385 return GenObject::getObject(name);
00386 }
00387
00391 virtual const String& toString() const
00392 { return m_name; }
00393
00397 virtual void destruct() {
00398 if (m_owner && m_element)
00399 delete m_element;
00400 m_element = 0;
00401 GenObject::destruct();
00402 }
00403
00413 static XMLElement* getXml(NamedList& list, bool stole = false,
00414 const char* name = "xml", const char* value = 0);
00415
00416 protected:
00426 XMLElement(TiXmlElement* element, bool owner);
00427
00432 inline TiXmlElement* get() const
00433 { return m_element; }
00434
00440 TiXmlElement* releaseOwnership();
00441
00445 static TokenDict s_names[];
00446
00447 private:
00448
00449 inline void setType() {
00450 m_name = name();
00451 m_type = (Type)lookup(name(),s_names,Unknown);
00452 }
00453
00454 Type m_type;
00455 bool m_owner;
00456 String m_name;
00457 TiXmlElement* m_element;
00458 };
00459
00465 class YJINGLE_API XMLParser : public TiXmlDocument, public Mutex
00466 {
00467 public:
00472 inline XMLParser()
00473 : TiXmlDocument(), Mutex(true), m_findstart(true)
00474 {}
00475
00479 virtual ~XMLParser()
00480 {}
00481
00490 bool consume(const char* data, u_int32_t len);
00491
00498 XMLElement* extract();
00499
00504 inline unsigned int bufLen() const
00505 { return m_buffer.length(); }
00506
00511 inline void getBuffer(String& dest) const
00512 { dest = m_buffer; }
00513
00517 void reset();
00518
00522 static u_int32_t s_maxDataBuffer;
00523
00527 static TiXmlEncoding s_xmlEncoding;
00528
00529 private:
00530 String m_buffer;
00531 bool m_findstart;
00532 };
00533
00538 class YJINGLE_API XMLElementOut : public RefObject
00539 {
00540 public:
00547 inline XMLElementOut(XMLElement* element, const char* senderID = 0,
00548 bool unclose = false)
00549 : m_element(element), m_offset(0), m_id(senderID), m_unclose(unclose),
00550 m_sent(false)
00551 {}
00552
00557 virtual ~XMLElementOut()
00558 { TelEngine::destruct(m_element); }
00559
00564 inline XMLElement* element() const
00565 { return m_element; }
00566
00571 inline bool sent() const
00572 { return m_sent; }
00573
00578 inline String& buffer()
00579 { return m_buffer; }
00580
00585 inline const String& id() const
00586 { return m_id; }
00587
00592 inline u_int32_t dataCount()
00593 { return m_buffer.length() - m_offset; }
00594
00600 inline const char* getData(u_int32_t& nCount) {
00601 if (!m_buffer)
00602 prepareToSend();
00603 nCount = dataCount();
00604 return m_buffer.c_str() + m_offset;
00605 }
00606
00611 inline void dataSent(u_int32_t nCount) {
00612 m_sent = true;
00613 m_offset += nCount;
00614 if (m_offset > m_buffer.length())
00615 m_offset = m_buffer.length();
00616 }
00617
00623 inline XMLElement* release() {
00624 XMLElement* e = m_element;
00625 m_element = 0;
00626 return e;
00627 }
00628
00633 inline void toBuffer(String& buffer)
00634 { if (m_element) m_element->toString(buffer,m_unclose); }
00635
00639 inline void prepareToSend()
00640 { toBuffer(m_buffer); }
00641
00642 private:
00643 XMLElement* m_element;
00644 String m_buffer;
00645 u_int32_t m_offset;
00646 String m_id;
00647 bool m_unclose;
00648 bool m_sent;
00649 };
00650
00651 };
00652
00653 #endif
00654
00655