Yate

xmlparser.h

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: */