2 // This file is part of the aMule Project.
4 // Copyright (c) 2004-2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #ifdef USE_WX_EXTENSIONS
33 #include <wx/string.h> // Do_not_auto_remove
34 #include <common/StringFunctions.h>
36 #define EC_ASSERT(x) wxASSERT(x)
38 #define EC_ASSERT(x) assert(x)
41 /* aMule/libcommon generic includes */
42 #include "../../../MD4Hash.h" // Needed for CMD4Hash
44 /* EC specific includes */
45 #include "ECCodes.h" // Needed for EC types
46 #include "ECTagTypes.h" // Needed for TagTypes
52 * Class to hold IPv4 address.
57 EC_IPv4_t(uint32 ip
, uint16 port
)
60 m_ip
[1] = (ip
>> 8) & 0xff;
61 m_ip
[2] = (ip
>> 16) & 0xff;
62 m_ip
[3] = (ip
>> 24) & 0xff;
68 return m_ip
[0] | (m_ip
[1] << 8) | (m_ip
[2] << 16) | (m_ip
[3] << 24);
71 std::string
StringIPSTL(bool brackets
= true)
73 std::ostringstream string_ip
;
74 if (brackets
) string_ip
<< "[";
75 string_ip
<< (int)m_ip
[0] << "." << (int)m_ip
[1] << "." << (int)m_ip
[2] << "." << (int)m_ip
[3] << ":" << m_port
;
76 if (brackets
) string_ip
<< "]";
77 return string_ip
.str();
80 #ifdef USE_WX_EXTENSIONS
81 wxString
StringIP(bool brackets
= true) {
82 return char2unicode(StringIPSTL(brackets
).c_str());
92 * High level EC packet TAGs handler class
97 CECTag(ec_tagname_t name
, unsigned int length
, const void *data
, bool copy
= true);
98 // tag for custom data: just init object, alloc buffer and return pointer
99 CECTag(ec_tagname_t name
, unsigned int length
, void **dataptr
);
100 // Routines for special data types.
101 CECTag(ec_tagname_t name
, uint8_t data
);
102 CECTag(ec_tagname_t name
, uint16_t data
);
103 CECTag(ec_tagname_t name
, uint32_t data
);
104 CECTag(ec_tagname_t name
, uint64_t data
);
105 CECTag(ec_tagname_t name
, double data
);
106 CECTag(ec_tagname_t name
, const std::string
& data
);
107 CECTag(ec_tagname_t name
, const EC_IPv4_t
& data
);
108 CECTag(ec_tagname_t name
, const CMD4Hash
& data
);
109 #ifdef USE_WX_EXTENSIONS
110 CECTag(ec_tagname_t name
, const wxString
& data
);
112 CECTag(const CECTag
& tag
);
115 CECTag
& operator=(const CECTag
& rhs
);
116 bool AddTag(const CECTag
& tag
);
117 const CECTag
* GetTagByIndex(unsigned int index
) const
118 { return ((index
>= m_tagList
.size()) ? NULL
: &m_tagList
[index
]); }
119 CECTag
* GetTagByIndex(unsigned int index
)
120 { return ((index
>= m_tagList
.size()) ? NULL
: &m_tagList
[index
]); }
121 const CECTag
* GetTagByIndexSafe(unsigned int index
) const
122 { const CECTag
* result
= GetTagByIndex(index
); return result
? result
: &s_theNullTag
; }
124 const CECTag
* GetTagByName(ec_tagname_t name
) const;
125 CECTag
* GetTagByName(ec_tagname_t name
);
126 const CECTag
* GetTagByNameSafe(ec_tagname_t name
) const;
128 uint16_t GetTagCount(void) const { return m_tagList
.size(); }
129 const void * GetTagData(void) const {
130 EC_ASSERT(m_dataType
== EC_TAGTYPE_CUSTOM
);
133 uint16_t GetTagDataLen() const { return m_dataLen
; }
134 uint32_t GetTagLen() const;
135 ec_tagname_t
GetTagName() const { return m_tagName
; }
137 // Retrieving special data types
138 uint64_t GetInt() const;
139 double GetDoubleData() const;
140 std::string
GetStringDataSTL() const;
142 #ifdef USE_WX_EXTENSIONS
143 wxString
GetStringData() const;
146 EC_IPv4_t
GetIPv4Data() const;
147 CMD4Hash
GetMD4Data() const;
150 void AssignIfExist(ec_tagname_t tagname
, uint8_t &target
)
152 CECTag
*tag
= GetTagByName(tagname
);
154 EC_ASSERT((tag
->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType
== EC_TAGTYPE_UNKNOWN
));
155 target
= tag
->GetInt();
158 void AssignIfExist(ec_tagname_t tagname
, uint16_t &target
)
160 CECTag
*tag
= GetTagByName(tagname
);
163 (tag
->GetType() == EC_TAGTYPE_UINT16
)
164 || (tag
->GetType() == EC_TAGTYPE_UINT8
)
165 || (m_dataType
== EC_TAGTYPE_UNKNOWN
)
167 target
= tag
->GetInt();
170 void AssignIfExist(ec_tagname_t tagname
, uint32_t &target
)
172 CECTag
*tag
= GetTagByName(tagname
);
175 (tag
->GetType() == EC_TAGTYPE_UINT32
)
176 || (tag
->GetType() == EC_TAGTYPE_UINT16
)
177 || (tag
->GetType() == EC_TAGTYPE_UINT8
)
178 || (m_dataType
== EC_TAGTYPE_UNKNOWN
)
180 target
= tag
->GetInt();
183 void AssignIfExist(ec_tagname_t tagname
, uint64_t &target
)
185 CECTag
*tag
= GetTagByName(tagname
);
186 if ( tag
) target
= tag
->GetInt();
188 void AssignIfExist(ec_tagname_t tagname
, double &target
)
190 CECTag
*tag
= GetTagByName(tagname
);
191 if ( tag
) target
= tag
->GetDoubleData();
193 void AssignIfExist(ec_tagname_t tagname
, CMD4Hash
&target
)
195 CECTag
*tag
= GetTagByName(tagname
);
196 if ( tag
) target
= tag
->GetMD4Data();
198 void AssignIfExist(ec_tagname_t tagname
, std::string
&target
)
200 CECTag
*tag
= GetTagByName(tagname
);
201 if ( tag
) target
= tag
->GetStringDataSTL();
204 #ifdef USE_WX_EXTENSIONS
205 void AssignIfExist(ec_tagname_t tagname
, wxString
&target
)
207 CECTag
*tag
= GetTagByName(tagname
);
208 if ( tag
) target
= tag
->GetStringData();
214 uint8_t GetType() const { return m_dataType
; }
228 CECTag(const CECSocket
&)
229 : m_error(0), m_tagData(NULL
), m_state(bsName
), m_dataLen(0), m_dataType(EC_TAGTYPE_UNKNOWN
), m_dynamic(true), m_haschildren(false)
232 bool ReadFromSocket(CECSocket
& socket
);
233 bool WriteTag(CECSocket
& socket
) const;
234 bool ReadChildren(CECSocket
& socket
);
235 bool WriteChildren(CECSocket
& socket
) const;
237 const void * m_tagData
;
241 bool IsOk() const { return m_state
== bsFinished
; }
244 // Special type used to invoke the Null tag constructor
245 struct NullTagConstructorSelector
{ };
247 // To init. the automatic int data
248 void InitInt(uint64_t data
);
250 // Special constructor to construct the Null tag.
251 explicit CECTag(const NullTagConstructorSelector
*);
253 ec_tagname_t m_tagName
;
254 ec_taglen_t m_dataLen
;
255 mutable ec_tagtype_t m_dataType
;
258 typedef std::vector
<CECTag
> TagList
;
263 static const CECTag s_theNullTag
;
264 static const uint32_t s_theNullTagData
[4];
266 // To be used by the string constructors.
267 void ConstructStringTag(ec_tagname_t name
, const std::string
& data
);
274 * Note, that an "empty" tag is empty because it contains no data, but it still
275 * may contain children.
277 class CECEmptyTag
: public CECTag
{
279 CECEmptyTag(ec_tagname_t name
) : CECTag(name
, 0, NULL
, false) {}
281 CECEmptyTag(const CECSocket
& socket
) : CECTag(socket
) {}
285 // File_checked_for_headers