gclientptr.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
20 
21 #ifndef G_SMTP_CLIENT_PTR_H
22 #define G_SMTP_CLIENT_PTR_H
23 
24 #include "gdef.h"
25 #include "gnet.h"
26 #include "gclient.h"
27 #include "gexception.h"
28 #include "gassert.h"
29 #include "gslot.h"
30 #include <memory>
31 
33 namespace GNet
34 {
35 
59 template <typename TClient>
60 class ClientPtr
61 {
62 public:
63  G_EXCEPTION( InvalidState , "invalid state of smtp client" ) ;
64 
65  explicit ClientPtr( TClient * p = NULL , bool preserve_resolver_info = false ) ;
67 
68  ~ClientPtr() ;
70 
71  bool busy() const ;
73 
74  void reset( TClient * p = NULL ) ;
76 
77  TClient * get() ;
79 
80  TClient * operator->() ;
82 
83  const TClient * operator->() const ;
85 
91 
94 
98 
99  ResolverInfo resolverInfo() const ;
101 
102  void releaseForExit() ;
106 
107  void cleanupForExit() ;
113 
114 private:
115  ClientPtr( const ClientPtr & ) ; // not implemented
116  void operator=( const ClientPtr & ) ; // not implemented
117  void doneSlot( std::string , bool ) ;
118  void eventSlot( std::string , std::string ) ;
119  void connectedSlot() ;
120  void connectSignalsToSlots() ;
121  void disconnectSignals() ;
122 
123 private:
124  TClient * m_p ;
125  bool m_update ;
126  ResolverInfo m_resolver_info ;
127  G::Signal2<std::string,bool> m_done_signal ;
128  G::Signal2<std::string,std::string> m_event_signal ;
129  G::Signal0 m_connected_signal ;
130 } ;
131 
132 template <typename TClient>
133 ClientPtr<TClient>::ClientPtr( TClient * p , bool update ) :
134  m_p(p) ,
135  m_update(update) ,
136  m_resolver_info(std::string(),std::string())
137 {
138  try
139  {
140  if( m_p != NULL )
141  {
142  m_resolver_info = m_p->resolverInfo() ;
143  }
144  connectSignalsToSlots() ;
145  }
146  catch(...)
147  {
149  throw ;
150  }
151 }
152 
153 template <typename TClient>
155 {
156  if( m_p != NULL )
157  {
158  disconnectSignals() ;
159  m_p->doDelete(std::string()) ;
160  }
161 }
162 
163 template <typename TClient>
165 {
166  if( m_p != NULL )
167  {
168  disconnectSignals() ;
169  m_p = NULL ;
170  }
171 }
172 
173 template <typename TClient>
175 {
176  if( m_p != NULL )
177  {
178  disconnectSignals() ;
179  TClient * p = m_p ;
180  m_p = NULL ;
181  p->doDeleteForExit() ;
182  }
183 }
184 
185 template <typename TClient>
187 {
188  if( m_p != NULL )
189  {
190  m_p->doneSignal().connect( G::slot(*this,&ClientPtr::doneSlot) ) ;
191  m_p->eventSignal().connect( G::slot(*this,&ClientPtr::eventSlot) ) ;
192  m_p->connectedSignal().connect( G::slot(*this,&ClientPtr::connectedSlot) ) ;
193  }
194 }
195 
196 template <typename TClient>
197 void ClientPtr<TClient>::reset( TClient * p )
198 {
199  disconnectSignals() ;
200 
201  TClient * old = m_p ;
202  m_p = p ;
203  if( old != NULL )
204  {
205  old->doDelete(std::string()) ;
206  }
207 
208  if( m_p != NULL && m_update )
209  {
210  m_p->updateResolverInfo( m_resolver_info ) ; // if host() and service() match
211  }
212 
213  connectSignalsToSlots() ;
214 }
215 
216 template <typename TClient>
218 {
219  return m_done_signal ;
220 }
221 
222 template <typename TClient>
224 {
225  return m_event_signal ;
226 }
227 
228 template <typename TClient>
230 {
231  return m_connected_signal ;
232 }
233 
234 template <typename TClient>
235 void ClientPtr<TClient>::doneSlot( std::string reason , bool retry )
236 {
237  G_ASSERT( m_p != NULL ) ;
238  disconnectSignals() ;
239  m_p = NULL ;
240  m_done_signal.emit( reason , retry ) ;
241 }
242 
243 template <typename TClient>
244 void ClientPtr<TClient>::disconnectSignals()
245 {
246  if( m_p != NULL )
247  {
248  m_p->doneSignal().disconnect() ;
249  m_p->eventSignal().disconnect() ;
250  m_p->connectedSignal().disconnect() ;
251  }
252 }
253 
254 template <typename TClient>
255 void ClientPtr<TClient>::connectedSlot()
256 {
257  G_ASSERT( m_p != NULL ) ;
258  m_resolver_info = m_p->resolverInfo() ;
259  m_connected_signal.emit() ;
260 }
261 
262 template <typename TClient>
263 void ClientPtr<TClient>::eventSlot( std::string s1 , std::string s2 )
264 {
265  m_event_signal.emit( s1 , s2 ) ;
266 }
267 
268 template <typename TClient>
270 {
271  return m_p ;
272 }
273 
274 template <typename TClient>
276 {
277  return m_p != NULL ;
278 }
279 
280 template <typename TClient>
282 {
283  if( m_p == NULL )
284  throw InvalidState() ;
285  return m_p ;
286 }
287 
288 template <typename TClient>
289 const TClient * ClientPtr<TClient>::operator->() const
290 {
291  if( m_p == NULL )
292  throw InvalidState() ;
293  return m_p ;
294 }
295 
296 template <typename TClient>
298 {
299  return m_resolver_info ;
300 }
301 
302 }
303 
304 #endif
TClient * get()
Returns the pointer, or NULL if deleted.
Definition: gclientptr.h:269
Network classes.
void releaseForExit()
Can be called on program termination when there may be no TimerList or EventLoop instances.
Definition: gclientptr.h:164
G::Signal2< std::string, std::string > & eventSignal()
Returns a signal which indicates something interesting.
Definition: gclientptr.h:223
Slot0 slot(T &object, void(T::*fn)())
Part of the slot/signal system.
Definition: gslot.h:156
A class that holds a host/service name pair and optionally the results of a name-to-address lookup...
Definition: gresolverinfo.h:48
ClientPtr(TClient *p=NULL, bool preserve_resolver_info=false)
Constructor.
Definition: gclientptr.h:133
void cleanupForExit()
Can be called on program termination when there may be no TimerList or EventLoop instances.
Definition: gclientptr.h:174
void reset(TClient *p=NULL)
Resets the pointer.
Definition: gclientptr.h:197
#define G_ASSERT(test)
Definition: gassert.h:30
~ClientPtr()
Destructor.
Definition: gclientptr.h:154
G::Signal2< std::string, bool > & doneSignal()
Returns a signal which indicates that client processing is complete and the client instance has delet...
Definition: gclientptr.h:217
Part of the slot/signal system.
Definition: gslot.h:138
#define G_EXCEPTION(class_name, description)
define as a function rather than a type if optimising for size
Definition: gexception.h:93
A smart pointer class for GNet::HeapClient.
Definition: gclientptr.h:60
G::Signal0 & connectedSignal()
Returns a signal which indicates that the connection has been established successfully.
Definition: gclientptr.h:229
TClient * operator->()
Returns the pointer. Throws if deleted.
Definition: gclientptr.h:281
ResolverInfo resolverInfo() const
Returns the current or last client's ResolverInfo.
Definition: gclientptr.h:297
void connect(Slot2< P1, P2 > slot)
Definition: gslot.h:295
bool busy() const
Returns true if the pointer is not NULL.
Definition: gclientptr.h:275