Upstream tarball 10002
[amule.git] / src / ExternalConn.h
blob398f07c274b9a8f631a1a2b9d5b8e9fa39e34ae9
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 Kry ( elkry@users.sourceforge.net / http://www.amule.org )
5 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Copyright (c) 2008 Froenchenko Leonid (lfroen@gmail.com)
7 //
8 // Any parts of this program derived from the xMule, lMule or eMule project,
9 // or contributed by third-party developers are copyrighted by their
10 // respective authors.
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #ifndef EXTERNALCONN_H
28 #define EXTERNALCONN_H
32 #include <ec/cpp/ECSpecialTags.h>
34 #include "amuleIPV4Address.h" // for amuleIPV4Address
35 #include "RLE.h" // for RLE
36 #include "DownloadQueue.h"
38 class wxSocketServer;
39 class wxSocketEvent;
42 // T - type of item
43 // E - type of encoder
44 // C - type of container in theApp
45 template <class T, class E, class C>
46 class CFileEncoderMap : public std::map<T *, E> {
47 public:
48 void UpdateEncoders(C *container)
50 // check if encoder contains files that no longer in container
51 // or, we have new files without encoder yet
52 std::set<T *> curr_files, dead_files;
53 for (unsigned int i = 0; i < container->GetFileCount(); i++) {
54 // cast for case of 'const'
55 T *cur_file = (T *)container->GetFileByIndex(i);
56 curr_files.insert(cur_file);
57 if ( this->count(cur_file) == 0 ) {
58 this->operator [](cur_file) = E(cur_file);
62 // curr_files set is created to minimize lookup time in download queue,
63 // since GetFileByID have loop inside leading to O(n), in this case
64 // it will mean O(n^2)
65 typename std::map<T *, E>::iterator i;
66 for(i = this->begin(); i != this->end(); i++) {
67 if ( curr_files.count(i->first) == 0 ) {
68 dead_files.insert(i->first);
71 typename std::set<T *>::iterator j;
72 for(j = dead_files.begin(); j != dead_files.end(); j++) {
73 this->erase(*j);
78 /*!
79 * PartStatus strings are quite long - RLE encoding will help.
81 * Instead of sending each time full part-status string, send
82 * RLE encoded difference from previous one.
84 * However, gap status is different - it's already kind of RLE
85 * encoding, so futher compression will help a litter (Shannon
86 * theorem). Instead, calculate diff between list of gaps.
88 class CPartFile_Encoder {
90 // List of gaps sent to particular client. Since clients
91 // can request lists in different time, they can get
92 // different results
93 PartFileEncoderData m_enc_data;
95 // gaps are also RLE encoded, but list have variable size by it's nature.
96 // so realloc buffer when needed.
97 // This buffer only needed on core-side, where list is turned into array
98 // before passing to RLE. Decoder will just use RLE internal buffer
99 // Buffer can be static, since it is accessed with mutex locked
100 typedef std::vector<uint64> GapBuffer;
101 static GapBuffer m_gap_buffer;
103 CPartFile *m_file;
104 public:
105 // encoder side
106 CPartFile_Encoder(CPartFile *file);
108 // decoder side
109 CPartFile_Encoder(int size);
111 ~CPartFile_Encoder();
113 // stl side :)
114 CPartFile_Encoder();
116 CPartFile_Encoder(const CPartFile_Encoder &obj);
118 CPartFile_Encoder &operator=(const CPartFile_Encoder &obj);
120 // encode - take data from m_file
121 void Encode(CECTag *parent_tag);
123 void ResetEncoder()
125 m_enc_data.ResetEncoder();
129 typedef CFileEncoderMap<CPartFile , CPartFile_Encoder, CDownloadQueue> CPartFile_Encoder_Map;
132 * Encode 'obtained parts' info to be sent to remote gui
134 class CKnownFile_Encoder {
135 RLE_Data m_enc_data;
136 CKnownFile *m_file;
137 public:
138 CKnownFile_Encoder(CKnownFile *file);
139 ~CKnownFile_Encoder();
141 // stl side :)
142 CKnownFile_Encoder();
144 CKnownFile_Encoder(const CKnownFile_Encoder &obj);
146 CKnownFile_Encoder &operator=(const CKnownFile_Encoder &obj);
147 // encode - take data from m_file
148 void Encode(CECTag *parent_tag);
150 void ResetEncoder()
152 m_enc_data.ResetEncoder();
156 typedef CFileEncoderMap<CKnownFile , CKnownFile_Encoder, CSharedFileList> CKnownFile_Encoder_Map;
158 template <class T, ec_tagname_t OP>
159 class CTagSet : public std::set<T> {
160 void InSet(const CECTag *tag, uint32)
162 this->insert(tag->GetInt());
164 void InSet(const CECTag *tag, CMD4Hash)
166 this->insert(tag->GetMD4Data());
168 public:
169 CTagSet(const CECPacket *request) : std::set<T>()
171 for (unsigned int i = 0;i < request->GetTagCount();i++) {
172 const CECTag *tag = request->GetTagByIndex(i);
173 if ( tag->GetTagName() == OP ) {
174 this->InSet(tag, T());
181 class CObjTagMap {
182 std::map<void *, CValueMap> m_obj_map;
183 public:
184 CValueMap &GetValueMap(void *object)
186 return m_obj_map[object];
189 size_t size()
191 return m_obj_map.size();
194 void RemoveDeleted(std::set<void *>& WXUNUSED(current_set))
196 for(std::map<void *, CValueMap>::iterator i = m_obj_map.begin(); i != m_obj_map.end(); i++) {
197 if ( !current_set.count(i->first) ) {
198 m_obj_map.erase(i->first);
206 class CECServerSocket;
207 class ECNotifier;
209 class ExternalConn : public wxEvtHandler
211 private:
212 typedef std::set<CECServerSocket *> SocketSet;
213 SocketSet socket_list;
215 public:
216 ExternalConn(amuleIPV4Address addr, wxString *msg);
217 ~ExternalConn();
219 wxSocketServer *m_ECServer;
220 ECNotifier *m_ec_notifier;
222 void AddSocket(CECServerSocket *s);
223 void RemoveSocket(CECServerSocket *s);
224 void KillAllSockets();
226 private:
227 // event handlers (these functions should _not_ be virtual)
228 void OnServerEvent(wxSocketEvent& event);
229 DECLARE_EVENT_TABLE()
232 class ECUpdateMsgSource {
233 public:
234 virtual ~ECUpdateMsgSource()
237 virtual CECPacket *GetNextPacket() = 0;
240 class ECPartFileMsgSource : public ECUpdateMsgSource {
241 typedef struct {
242 bool m_new;
243 bool m_comment_changed;
244 bool m_removed;
245 bool m_finished;
246 bool m_dirty;
247 CPartFile *m_file;
248 } PARTFILE_STATUS;
249 std::map<CMD4Hash, PARTFILE_STATUS> m_dirty_status;
250 public:
251 ECPartFileMsgSource();
253 void SetDirty(CPartFile *file);
254 void SetNew(CPartFile *file);
255 void SetCompleted(CPartFile *file);
256 void SetRemoved(CPartFile *file);
258 virtual CECPacket *GetNextPacket();
262 class ECKnownFileMsgSource : public ECUpdateMsgSource {
263 typedef struct {
264 bool m_new;
265 bool m_comment_changed;
266 bool m_removed;
267 bool m_dirty;
268 CKnownFile *m_file;
269 } KNOWNFILE_STATUS;
270 std::map<CMD4Hash, KNOWNFILE_STATUS> m_dirty_status;
271 public:
272 ECKnownFileMsgSource();
274 void SetDirty(CKnownFile *file);
275 void SetNew(CKnownFile *file);
276 void SetRemoved(CKnownFile *file);
278 virtual CECPacket *GetNextPacket();
281 class ECClientMsgSource : public ECUpdateMsgSource {
282 public:
283 virtual CECPacket *GetNextPacket();
286 class ECStatusMsgSource : public ECUpdateMsgSource {
287 uint32 m_last_ed2k_status_sent;
288 uint32 m_last_kad_status_sent;
289 void *m_server;
291 uint32 GetEd2kStatus();
292 uint32 GetKadStatus();
293 public:
294 ECStatusMsgSource();
296 virtual CECPacket *GetNextPacket();
299 class ECSearchMsgSource : public ECUpdateMsgSource {
300 typedef struct {
301 bool m_new;
302 bool m_child_dirty;
303 bool m_dirty;
304 CSearchFile *m_file;
305 } SEARCHFILE_STATUS;
306 std::map<CMD4Hash, SEARCHFILE_STATUS> m_dirty_status;
307 public:
308 ECSearchMsgSource();
310 void SetDirty(CSearchFile *file);
311 void SetChildDirty(CSearchFile *file);
313 void FlushStatus();
315 virtual CECPacket *GetNextPacket();
318 class ECNotifier {
320 // designated priority for each type of update
322 enum EC_SOURCE_PRIO {
323 EC_PARTFILE = 0,
324 EC_SEARCH,
325 EC_CLIENT,
326 EC_STATUS,
327 EC_KNOWN,
329 EC_STATUS_LAST_PRIO
332 //ECUpdateMsgSource *m_msg_source[EC_STATUS_LAST_PRIO];
333 std::map<CECServerSocket *, ECUpdateMsgSource **> m_msg_source;
335 void NextPacketToSocket();
337 CECPacket *GetNextPacket(ECUpdateMsgSource *msg_source_array[]);
338 public:
339 ECNotifier();
341 void Add_EC_Client(CECServerSocket *sock);
342 void Remove_EC_Client(CECServerSocket *sock);
344 CECPacket *GetNextPacket(CECServerSocket *sock);
347 // Interface to notification macros
349 void DownloadFile_SetDirty(CPartFile *file);
350 void DownloadFile_RemoveFile(CPartFile *file);
351 void DownloadFile_RemoveSource(CPartFile *file);
352 void DownloadFile_AddFile(CPartFile *file);
353 void DownloadFile_AddSource(CPartFile *file);
355 void Status_ConnectionState();
356 void Status_QueueCount();
357 void Status_UserCount();
359 void SharedFile_AddFile(CKnownFile *file);
360 void SharedFile_RemoveFile(CKnownFile *file);
361 void SharedFile_RemoveAllFiles();
366 #endif // EXTERNALCONN_H
367 // File_checked_for_headers