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 )
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
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.
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 EXTERNALCONN_H
27 #define EXTERNALCONN_H
31 #include <ec/cpp/ECSpecialTags.h>
33 #include "amuleIPV4Address.h" // for amuleIPV4Address
34 #include "RLE.h" // for RLE
35 #include "DownloadQueue.h"
42 // E - type of encoder
43 // C - type of container in theApp
44 template <class T
, class E
, class C
>
45 class CFileEncoderMap
: public std::map
<T
*, E
> {
47 void UpdateEncoders(C
*container
)
49 // check if encoder contains files that no longer in container
50 // or, we have new files without encoder yet
51 std::set
<T
*> curr_files
, dead_files
;
52 for (unsigned int i
= 0; i
< container
->GetFileCount(); i
++) {
53 // cast for case of 'const'
54 T
*cur_file
= (T
*)container
->GetFileByIndex(i
);
55 curr_files
.insert(cur_file
);
56 if ( this->count(cur_file
) == 0 ) {
57 this->operator [](cur_file
) = E(cur_file
);
61 // curr_files set is created to minimize lookup time in download queue,
62 // since GetFileByID have loop inside leading to O(n), in this case
63 // it will mean O(n^2)
64 typename
std::map
<T
*, E
>::iterator i
;
65 for(i
= this->begin(); i
!= this->end(); i
++) {
66 if ( curr_files
.count(i
->first
) == 0 ) {
67 dead_files
.insert(i
->first
);
70 typename
std::set
<T
*>::iterator j
;
71 for(j
= dead_files
.begin(); j
!= dead_files
.end(); j
++) {
78 * PartStatus strings are quite long - RLE encoding will help.
80 * Instead of sending each time full part-status string, send
81 * RLE encoded difference from previous one.
83 * However, gap status is different - it's already kind of RLE
84 * encoding, so futher compression will help a litter (Shannon
85 * theorem). Instead, calculate diff between list of gaps.
87 class CPartFile_Encoder
{
89 // List of gaps sent to particular client. Since clients
90 // can request lists in different time, they can get
92 PartFileEncoderData m_enc_data
;
94 // gaps are also RLE encoded, but list have variable size by it's nature.
95 // so realloc buffer when needed.
96 // This buffer only needed on core-side, where list is turned into array
97 // before passing to RLE. Decoder will just use RLE internal buffer
98 // Buffer can be static, since it is accessed with mutex locked
99 typedef std::vector
<uint64
> GapBuffer
;
100 static GapBuffer m_gap_buffer
;
105 CPartFile_Encoder(CPartFile
*file
);
108 CPartFile_Encoder(int size
);
110 ~CPartFile_Encoder();
115 CPartFile_Encoder(const CPartFile_Encoder
&obj
);
117 CPartFile_Encoder
&operator=(const CPartFile_Encoder
&obj
);
119 // encode - take data from m_file
120 void Encode(CECTag
*parent_tag
);
124 m_enc_data
.ResetEncoder();
128 typedef CFileEncoderMap
<CPartFile
, CPartFile_Encoder
, CDownloadQueue
> CPartFile_Encoder_Map
;
131 * Encode 'obtained parts' info to be sent to remote gui
133 class CKnownFile_Encoder
{
137 CKnownFile_Encoder(CKnownFile
*file
);
138 ~CKnownFile_Encoder();
141 CKnownFile_Encoder();
143 CKnownFile_Encoder(const CKnownFile_Encoder
&obj
);
145 CKnownFile_Encoder
&operator=(const CKnownFile_Encoder
&obj
);
146 // encode - take data from m_file
147 void Encode(CECTag
*parent_tag
);
151 m_enc_data
.ResetEncoder();
155 typedef CFileEncoderMap
<CKnownFile
, CKnownFile_Encoder
, CSharedFileList
> CKnownFile_Encoder_Map
;
157 template <class T
, ec_tagname_t OP
>
158 class CTagSet
: public std::set
<T
> {
159 void InSet(const CECTag
*tag
, uint32
)
161 this->insert(tag
->GetInt());
163 void InSet(const CECTag
*tag
, CMD4Hash
)
165 this->insert(tag
->GetMD4Data());
168 CTagSet(const CECPacket
*request
) : std::set
<T
>()
170 for (unsigned int i
= 0;i
< request
->GetTagCount();i
++) {
171 const CECTag
*tag
= request
->GetTagByIndex(i
);
172 if ( tag
->GetTagName() == OP
) {
173 this->InSet(tag
, T());
181 std::map
<void *, CValueMap
> m_obj_map
;
183 CValueMap
&GetValueMap(void *object
)
185 return m_obj_map
[object
];
190 return m_obj_map
.size();
193 void RemoveDeleted(std::set
<void *>& WXUNUSED(current_set
))
195 for(std::map<void *, CValueMap>::iterator i = m_obj_map.begin(); i != m_obj_map.end(); i++) {
196 if ( !current_set.count(i->first) ) {
197 m_obj_map.erase(i->first);
205 class CECServerSocket
;
208 class ExternalConn
: public wxEvtHandler
211 typedef std::set
<CECServerSocket
*> SocketSet
;
212 SocketSet socket_list
;
215 ExternalConn(amuleIPV4Address addr
, wxString
*msg
);
218 wxSocketServer
*m_ECServer
;
220 static CECPacket
*ProcessRequest2(
221 const CECPacket
*request
,
222 CPartFile_Encoder_Map
&,
223 CKnownFile_Encoder_Map
&,
226 static CECPacket
*Authenticate(const CECPacket
*);
228 void AddSocket(CECServerSocket
*s
);
229 void RemoveSocket(CECServerSocket
*s
);
230 void KillAllSockets();
233 // event handlers (these functions should _not_ be virtual)
234 void OnServerEvent(wxSocketEvent
& event
);
235 DECLARE_EVENT_TABLE()
238 #endif // EXTERNALCONN_H
239 // File_checked_for_headers