2 // This file is part of the aMule Project.
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)
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.
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"
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
> {
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
++) {
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
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
;
106 CPartFile_Encoder(CPartFile
*file
);
109 CPartFile_Encoder(int size
);
111 ~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
);
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
{
138 CKnownFile_Encoder(CKnownFile
*file
);
139 ~CKnownFile_Encoder();
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
);
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());
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());
182 std::map
<void *, CValueMap
> m_obj_map
;
184 CValueMap
&GetValueMap(void *object
)
186 return m_obj_map
[object
];
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
;
209 class ExternalConn
: public wxEvtHandler
212 typedef std::set
<CECServerSocket
*> SocketSet
;
213 SocketSet socket_list
;
216 ExternalConn(amuleIPV4Address addr
, wxString
*msg
);
219 wxSocketServer
*m_ECServer
;
220 ECNotifier
*m_ec_notifier
;
222 void AddSocket(CECServerSocket
*s
);
223 void RemoveSocket(CECServerSocket
*s
);
224 void KillAllSockets();
227 // event handlers (these functions should _not_ be virtual)
228 void OnServerEvent(wxSocketEvent
& event
);
229 DECLARE_EVENT_TABLE()
232 class ECUpdateMsgSource
{
234 virtual ~ECUpdateMsgSource()
237 virtual CECPacket
*GetNextPacket() = 0;
240 class ECPartFileMsgSource
: public ECUpdateMsgSource
{
243 bool m_comment_changed
;
249 std::map
<CMD4Hash
, PARTFILE_STATUS
> m_dirty_status
;
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
{
265 bool m_comment_changed
;
270 std::map
<CMD4Hash
, KNOWNFILE_STATUS
> m_dirty_status
;
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
{
283 virtual CECPacket
*GetNextPacket();
286 class ECStatusMsgSource
: public ECUpdateMsgSource
{
287 uint32 m_last_ed2k_status_sent
;
288 uint32 m_last_kad_status_sent
;
291 uint32
GetEd2kStatus();
292 uint32
GetKadStatus();
296 virtual CECPacket
*GetNextPacket();
299 class ECSearchMsgSource
: public ECUpdateMsgSource
{
306 std::map
<CMD4Hash
, SEARCHFILE_STATUS
> m_dirty_status
;
310 void SetDirty(CSearchFile
*file
);
311 void SetChildDirty(CSearchFile
*file
);
315 virtual CECPacket
*GetNextPacket();
320 // designated priority for each type of update
322 enum EC_SOURCE_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
[]);
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