1 /*
2   Copyright (c) 2005-2019 by Jakob Schröter <js@camaya.net>
3   This file is part of the gloox library. http://camaya.net/gloox
4 
5   This software is distributed under a license. The full license
6   agreement can be found in the file LICENSE in this distribution.
7   This software may not be copied, modified, sold or distributed
8   other than expressed in the named license agreement.
9 
10   This software is distributed without any warranty.
11 */
12 
13 
14 #ifndef STANZA_H__
15 #define STANZA_H__
16 
17 #include "gloox.h"
18 #include "tag.h"
19 #include "jid.h"
20 #include "stanzaextension.h"
21 
22 namespace gloox
23 {
24 
25   class Error;
26 
27   /**
28    * @brief This is the base class for XMPP stanza abstractions.
29    *
30    * @author Jakob Schröter <js@camaya.net>
31    * @since 0.4
32    */
33   class GLOOX_API Stanza
34   {
35     public:
36       /**
37        * Virtual destructor.
38        */
39       virtual ~Stanza();
40 
41       /**
42        * Sets the 'from' address of the Stanza. This useful for @link gloox::Component Components @endlink.
43        * @param from The from address.
44        */
setFrom(const JID & from)45       void setFrom( const JID& from ) { m_from = from; }
46 
47       /**
48        * Returns the JID the stanza comes from.
49        * @return The origin of the stanza.
50        */
from()51       const JID& from() const { return m_from; }
52 
53       /**
54        * Returns the receiver of the stanza.
55        * @return The stanza's destination.
56        */
to()57       const JID& to() const { return m_to; }
58 
59       /**
60        * Returns the id of the stanza, if set.
61        * @return The ID of the stanza.
62        */
id()63       const std::string& id() const { return m_id; }
64 
65       /**
66        * A convenience function that returns the stanza error condition, if any.
67        * @return The stanza error condition, may be 0.
68        */
69       const Error* error() const;
70 
71       /**
72        * Retrieves the value of the xml:lang attribute of this stanza.
73        * Default is 'en'.
74        * @return The stanza's default language.
75        */
xmlLang()76       const std::string& xmlLang() const { return m_xmllang; }
77 
78       /**
79        * Use this function to add a StanzaExtension to this Stanza.
80        * @param se The StanzaExtension to add.
81        * @note The Stanza will become the owner of the StanzaExtension and
82        * will take care of deletion.
83        * @since 0.9
84        */
85       void addExtension( const StanzaExtension* se );
86 
87       /**
88        * Finds a StanzaExtension of a particular type.
89        * @param type StanzaExtensionType to search for.
90        * @return A pointer to the StanzaExtension, or 0 if none was found.
91        */
92       const StanzaExtension* findExtension( int type ) const;
93 
94       /**
95        * Finds a StanzaExtension of a particular type.
96        * Example:
97        * @code
98        * const MyExtension* c = presence.findExtension<MyExtension>( ExtMyExt );
99        * @endcode
100        * @param type The extension type to look for.
101        * @return The static_cast' type, or 0 if none was found.
102        */
103       template< class T >
findExtension(int type)104       inline const T* findExtension( int type ) const
105       {
106         return static_cast<const T*>( findExtension( type ) );
107       }
108 
109       /**
110        * Returns the list of the Stanza's extensions.
111        * @return The list of the Stanza's extensions.
112        */
extensions()113       const StanzaExtensionList& extensions() const { return m_extensionList; }
114 
115       /**
116        * Removes (deletes) all the stanza's extensions.
117        */
118       void removeExtensions();
119 
120       /**
121        * This function is used by StanzaExtensionFactory to signal ClientBase
122        * that this Stanza instance contains an embedded Stanza that needs to be
123        * checked for further StanzaExtensions.
124        * You should not need to use this function directly.
125        */
setEmbeddedStanza()126       void setEmbeddedStanza() { m_hasEmbeddedStanza = true; }
127 
128       /**
129        * This function indicates whether this Stanza instance contains an embedded
130        * Stanza that needs to be checked for further StanzaExtensions.
131        * You should not need to use this function directly.
132        * @return Whether this Stanza instance contains an embedded
133        * Stanza.
134        */
hasEmbeddedStanza()135       bool hasEmbeddedStanza() const { return m_hasEmbeddedStanza; }
136 
137       /**
138        * This function returns the embedded Stanza. It is only needed by
139        * ClientBase/StanzaExtensionFactory.
140        * If hasEmbeddedStanza() is true, this function checks every
141        * embedded StanzaExtension for an embedded Stanza and returns the first it finds.
142        * You should not need to use this function directly.
143        * @return The embedded Stanza. May be 0.
144        */
145       Stanza* embeddedStanza() const;
146 
147       /**
148        * This function returns the embedded Tag that the embedded Stanza is based on.
149        * It is only needed by ClientBase/StanzaExtensionFactory.
150        * If hasEmbeddedStanza() is true, this function checks every
151        * embedded StanzaExtension for an embedded Tag and returns the first it finds.
152        * You should not need to use this function directly.
153        *
154        * @return The embedded Tag. May be 0.
155        */
156       Tag* embeddedTag() const;
157 
158       /**
159        * Creates a Tag representation of the Stanza. The Tag is completely
160        * independent of the Stanza and will not be updated when the Stanza
161        * is modified.
162        * @return A pointer to a Tag representation. It is the job of the caller to delete the Tag.
163        */
164       virtual Tag* tag() const = 0;
165 
166     protected:
167       /**
168        * Creates a new Stanza, taking from and to addresses from the given Tag.
169        * @param tag The Tag to create the Stanza from.
170        * @since 1.0
171        */
172       Stanza( Tag* tag );
173 
174       /**
175        * Creates a new Stanza object and initializes the receiver's JID.
176        * @param to The receipient of the Stanza.
177        * @since 1.0
178        */
179       Stanza( const JID& to );
180 
181       StanzaExtensionList m_extensionList;
182       std::string m_id;
183       std::string m_xmllang;
184       JID m_from;
185       JID m_to;
186 
187       static const std::string& findLang( const StringMap* map,
188                                           const std::string& defaultData,
189                                           const std::string& lang );
190 
191       static void setLang( StringMap** map,
192                            std::string& defaultLang,
193                            const Tag* tag );
194 
195       static void setLang( StringMap** map,
196                            std::string& defaultLang,
197                            const std::string& data,
198                            const std::string& xmllang );
199 
200       static void getLangs( const StringMap* map,
201                             const std::string& defaultData,
202                             const std::string& name, Tag* tag );
203 
204     private:
205       Stanza( const Stanza& );
206 
207       bool m_hasEmbeddedStanza;
208 
209   };
210 
211 }
212 
213 #endif // STANZA_H__
214