Upstream tarball 10148
[amule.git] / src / libs / ec / cpp / ECSocket.h
blob330b6c81faca180046123bc14ff39f54655e02de
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2004-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2004-2008 Angel Vidal Veiga ( kry@users.sourceforge.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #ifndef ECSOCKET_H
27 #define ECSOCKET_H
30 #include <deque> // Needed for std::deque
31 #include <memory> // Needed for std::auto_ptr // Do_not_auto_remove (mingw-gcc-3.4.5)
32 #include <string>
33 #include <vector>
35 #include <zlib.h> // Needed for packet (de)compression
36 #include "../../../Types.h" // Needed for uint32_t
38 #include <wx/defs.h> // Needed for wx/debug.h
39 #include <wx/debug.h> // Needed for wxASSERT
41 enum ECSocketErrors {
42 EC_ERROR_NOERROR,
43 EC_ERROR_INVOP,
44 EC_ERROR_IOERR,
45 EC_ERROR_INVADDR,
46 EC_ERROR_INVSOCK,
47 EC_ERROR_NOHOST,
48 EC_ERROR_INVPORT,
49 EC_ERROR_WOULDBLOCK,
50 EC_ERROR_TIMEDOUT,
51 EC_ERROR_MEMERR,
52 EC_ERROR_UNKNOWN
55 class CECPacket;
56 class CQueuedData;
58 /*! \class CECSocket
60 * \brief Socket handler for External Communications (EC).
62 * CECSocket takes care of the transmission of EC packets
65 class CECSocket{
66 friend class CECPacket;
67 friend class CECTag;
69 private:
70 static const unsigned int EC_SOCKET_BUFFER_SIZE = 2048;
71 static const unsigned int EC_HEADER_SIZE = 8;
72 const bool m_use_events;
74 // Output related data
75 std::list<CQueuedData *> m_output_queue;
77 // zlib (deflation) buffers
78 std::vector<unsigned char> m_in_ptr;
79 std::vector<unsigned char> m_out_ptr;
80 std::auto_ptr<CQueuedData> m_curr_rx_data;
81 std::auto_ptr<CQueuedData> m_curr_tx_data;
83 // This transfer only
84 uint32_t m_rx_flags;
85 uint32_t m_tx_flags;
86 size_t m_bytes_needed;
87 bool m_in_header;
90 uint32_t m_curr_packet_len;
91 z_stream m_z;
93 protected:
94 uint32_t m_my_flags;
95 bool m_haveNotificationSupport;
96 public:
97 CECSocket(bool use_events);
98 virtual ~CECSocket();
100 bool ConnectSocket(uint32_t ip, uint16_t port);
102 void CloseSocket() { InternalClose(); }
104 bool HaveNotificationSupport() const { return m_haveNotificationSupport; }
107 * Sends an EC packet and returns immediately.
109 * @param packet The CECPacket packet to be sent.
111 * This is an asynchronous call, the function returns
112 * immediately and the packet is sent on idle time.
114 * @note It's the caller's responsibilty to \c delete
115 * the \e packet.
117 void SendPacket(const CECPacket *packet);
120 * Sends an EC packet and waits for a reply.
122 * @param request The CECPacket packet to be sent.
123 * @return The reply packet for the request.
125 * Unlike SendPacket(), this call is synchronous and blocking.
126 * The packet is sent immediately (or at least as soon as possible),
127 * and the function does not return until a reply is received,
128 * or a timeout encountered.
130 * The returned packet will be allocated on the heap with \c new,
131 * or \c NULL is returned in case of an error (timeout).
133 * @note It's the caller's responsibilty to \c delete both
134 * request and reply.
136 * @note OnPacketReceived() won't be called for packets
137 * received via this function.
139 const CECPacket *SendRecvPacket(const CECPacket *request);
142 * Event handler function called when a new packet is received.
144 * @param packet The packet that has been received.
145 * @return The reply packet or \c NULL if no reply needed.
147 * In this function the application should process the received
148 * packet, and create a reply if necessary. The reply must be allocated
149 * on the heap with \c new. If no reply is necessary, the return
150 * value of the function should be \c NULL. The library will \c delete
151 * both packets.
153 * @note This function won't be called for packets received via the
154 * SendRecvPacket() function.
156 virtual const CECPacket *OnPacketReceived(const CECPacket *packet, uint32 trueSize);
159 * Get a message describing the error.
161 * @param error The code of the error for which a message should be returned.
162 * @return The text descibing the error.
164 virtual std::string GetLastErrorMsg();
167 * Error handler.
169 * This function is called when an error occurs. Use GetLastError() and
170 * GetErrorMsg() to find out the nature of the error.
172 * The default error handler prints out an error message in debug builds,
173 * and destroys the socket.
175 virtual void OnError();
179 * Socket lost event handler.
181 * This function is called when the socket is lost (either because of a network
182 * failure or because the remote end closed the socket gracefully).
184 * The default handler destroys the socket.
186 virtual void OnLost();
189 * Event handler for connection events.
191 * This function is called when a connection attempt succeeds.
193 virtual void OnConnect();
195 void OnInput();
196 void OnOutput();
198 bool WouldBlock() { return InternalGetLastError() == EC_ERROR_WOULDBLOCK; }
199 bool GotError() { return InternalGetLastError() != EC_ERROR_NOERROR; }
201 void SocketRead(void* ptr, size_t len) { InternalRead(ptr,len); }
202 void SocketWrite(const void* ptr, size_t len) { InternalWrite(ptr,len); }
203 bool SocketError() { return InternalError() && GotError(); }
204 bool SocketRealError();
206 size_t GetLastCount() { return InternalLastCount(); }
207 bool WaitSocketConnect(long secs = -1, long msecs = 0) { return InternalWaitOnConnect(secs,msecs); }
208 bool WaitSocketWrite(long secs = -1, long msecs = 0) { return InternalWaitForWrite(secs,msecs); }
209 bool WaitSocketRead(long secs = -1, long msecs = 0) { return InternalWaitForRead(secs,msecs); }
211 bool IsSocketConnected() { return InternalIsConnected(); }
213 void DestroySocket() { return InternalDestroy(); }
215 bool DataPending();
216 private:
217 const CECPacket *ReadPacket();
218 uint32 WritePacket(const CECPacket *packet);
220 // These 4 methods are to be used by CECPacket & CECTag
221 bool ReadNumber(void *buffer, size_t len);
222 bool ReadBuffer(void *buffer, size_t len);
223 bool ReadHeader();
225 bool WriteNumber(const void *buffer, size_t len);
226 bool WriteBuffer(const void *buffer, size_t len);
228 // Internal stuff
229 bool FlushBuffers();
231 size_t ReadBufferFromSocket(void *buffer, size_t len);
232 void WriteBufferToSocket(const void *buffer, size_t len);
234 /* virtuals */
235 virtual void WriteDoneAndQueueEmpty() = 0;
237 virtual bool InternalConnect(uint32_t ip, uint16_t port, bool wait) = 0;
239 virtual size_t InternalLastCount() = 0;
240 virtual bool InternalWaitOnConnect(long secs = -1, long msecs = 0) = 0;
241 virtual bool InternalWaitForWrite(long secs = -1, long msecs = 0) = 0;
242 virtual bool InternalWaitForRead(long secs = -1, long msecs = 0) = 0;
244 virtual int InternalGetLastError() = 0;
246 virtual void InternalClose() = 0;
247 virtual bool InternalError() = 0;
248 virtual void InternalRead(void* ptr, size_t len) = 0;
249 virtual void InternalWrite(const void* ptr, size_t len) = 0;
251 virtual bool InternalIsConnected() = 0;
252 virtual void InternalDestroy() = 0;
254 // Was login succesfull ?
255 virtual bool IsAuthorized() { return true; }
259 class CQueuedData
261 std::vector<unsigned char> m_data;
262 unsigned char *m_rd_ptr, *m_wr_ptr;
263 public:
264 CQueuedData(size_t len)
266 m_data(len)
268 m_rd_ptr = m_wr_ptr = &m_data[0];
271 ~CQueuedData() {}
273 void Rewind()
275 m_rd_ptr = m_wr_ptr = &m_data[0];
278 void Write(const void *data, size_t len);
279 void WriteAt(const void *data, size_t len, size_t off);
280 void Read(void *data, size_t len);
283 * Pass pointers to zlib. From now on, no Read() calls are allowed
285 void ToZlib(z_stream &m_z)
287 m_z.avail_in = (uInt)GetUnreadDataLength();
288 m_z.next_in = m_rd_ptr;
291 void WriteToSocket(CECSocket *sock);
292 void ReadFromSocket(CECSocket *sock, size_t len);
294 size_t ReadFromSocketAll(CECSocket *sock, size_t len);
296 size_t GetLength() const;
297 size_t GetDataLength() const;
298 size_t GetRemLength() const;
299 size_t GetUnreadDataLength() const;
302 #endif // ECSOCKET_H