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
53 * Class to hold IPv4 address.
58 EC_IPv4_t(uint32 ip
, uint16 port
)
61 m_ip
[1] = (ip
>> 8) & 0xff;
62 m_ip
[2] = (ip
>> 16) & 0xff;
63 m_ip
[3] = (ip
>> 24) & 0xff;
69 return m_ip
[0] | (m_ip
[1] << 8) | (m_ip
[2] << 16) | (m_ip
[3] << 24);
72 std::string
StringIPSTL(bool brackets
= true)
74 std::ostringstream string_ip
;
75 if (brackets
) string_ip
<< "[";
76 string_ip
<< (int)m_ip
[0] << "." << (int)m_ip
[1] << "." << (int)m_ip
[2] << "." << (int)m_ip
[3] << ":" << m_port
;
77 if (brackets
) string_ip
<< "]";
78 return string_ip
.str();
81 #ifdef USE_WX_EXTENSIONS
82 wxString
StringIP(bool brackets
= true) {
83 return char2unicode(StringIPSTL(brackets
).c_str());
93 * High level EC packet TAGs handler class
98 CECTag(ec_tagname_t name
, unsigned int length
, const void *data
);
99 // tag for custom data: just init object, alloc buffer and return pointer
100 CECTag(ec_tagname_t name
, unsigned int length
, void **dataptr
);
101 // Routines for special data types.
102 CECTag(ec_tagname_t name
, bool data
);
103 CECTag(ec_tagname_t name
, uint8_t data
);
104 CECTag(ec_tagname_t name
, uint16_t data
);
105 CECTag(ec_tagname_t name
, uint32_t data
);
106 CECTag(ec_tagname_t name
, uint64_t data
);
107 CECTag(ec_tagname_t name
, double data
);
108 CECTag(ec_tagname_t name
, const std::string
& data
);
109 CECTag(ec_tagname_t name
, const EC_IPv4_t
& data
);
110 CECTag(ec_tagname_t name
, const CMD4Hash
& data
);
111 #ifdef USE_WX_EXTENSIONS
112 CECTag(ec_tagname_t name
, const wxString
& data
);
113 CECTag(ec_tagname_t name
, const wxChar
* data
);
115 CECTag(ec_tagname_t name
, const char* data
) { ConstructStringTag(name
, data
); }
117 CECTag(const CECTag
& tag
);
120 CECTag
& operator=(const CECTag
& rhs
);
121 bool operator==(const CECTag
& tag
) const;
122 bool operator!=(const CECTag
& tag
) const { return !(*this == tag
); }
123 bool AddTag(const CECTag
& tag
, CValueMap
* valuemap
= NULL
);
124 void AddTag(ec_tagname_t name
, uint64_t data
, CValueMap
* valuemap
= NULL
);
125 void AddTag(ec_tagname_t name
, const CMD4Hash
& data
, CValueMap
* valuemap
);
126 #ifdef USE_WX_EXTENSIONS
127 void AddTag(ec_tagname_t name
, const wxString
& data
, CValueMap
* valuemap
= NULL
);
130 const CECTag
* GetFirstTagSafe() const { return m_tagList
.empty() ? &s_theNullTag
: & *m_tagList
.begin(); }
132 const CECTag
* GetTagByName(ec_tagname_t name
) const;
133 CECTag
* GetTagByName(ec_tagname_t name
);
134 const CECTag
* GetTagByNameSafe(ec_tagname_t name
) const;
136 size_t GetTagCount() const { return m_tagList
.size(); }
137 bool HasChildTags() const { return !m_tagList
.empty(); }
138 const void * GetTagData() const {
139 EC_ASSERT(m_dataType
== EC_TAGTYPE_CUSTOM
);
142 uint16_t GetTagDataLen() const { return m_dataLen
; }
143 uint32_t GetTagLen() const;
144 ec_tagname_t
GetTagName() const { return m_tagName
; }
146 // Retrieving special data types
147 uint64_t GetInt() const;
148 bool IsInt() const { return m_dataType
>= EC_TAGTYPE_UINT8
&& m_dataType
<= EC_TAGTYPE_UINT64
; }
149 double GetDoubleData() const;
150 std::string
GetStringDataSTL() const;
151 bool IsString() const { return m_dataType
== EC_TAGTYPE_STRING
; }
153 #ifdef USE_WX_EXTENSIONS
154 wxString
GetStringData() const;
155 void SetStringData(const wxString
& s
);
158 EC_IPv4_t
GetIPv4Data() const;
159 CMD4Hash
GetMD4Data() const;
161 void DebugPrint(int level
, bool print_empty
) const;
162 void swap(CECTag
& t
);
164 // If tag exists, return its value and store it in target (if target != NULL)
165 // Else return safe value and don't touch target
166 // Allows for one function for old and new style.
167 bool AssignIfExist(ec_tagname_t tagname
, bool *target
) const;
168 uint8_t AssignIfExist(ec_tagname_t tagname
, uint8_t *target
) const;
169 uint16_t AssignIfExist(ec_tagname_t tagname
, uint16_t *target
) const;
170 uint32_t AssignIfExist(ec_tagname_t tagname
, uint32_t *target
) const;
171 uint64_t AssignIfExist(ec_tagname_t tagname
, uint64_t *target
) const;
172 time_t AssignIfExist(ec_tagname_t tagname
, time_t *target
) const;
173 double AssignIfExist(ec_tagname_t tagname
, double *target
) const;
174 float AssignIfExist(ec_tagname_t tagname
, float *target
) const;
175 CMD4Hash
AssignIfExist(ec_tagname_t tagname
, CMD4Hash
*target
) const;
176 std::string
AssignIfExist(ec_tagname_t tagname
, std::string
*target
) const;
177 #ifdef USE_WX_EXTENSIONS
178 wxString
AssignIfExist(ec_tagname_t tagname
, wxString
*target
) const;
181 // If tag exists, return true and store it in target
182 // Else return false and don't touch target
183 bool AssignIfExist(ec_tagname_t tagname
, bool &target
) const;
184 bool AssignIfExist(ec_tagname_t tagname
, uint8_t &target
) const;
185 bool AssignIfExist(ec_tagname_t tagname
, uint16_t &target
) const;
186 bool AssignIfExist(ec_tagname_t tagname
, uint32_t &target
) const;
187 bool AssignIfExist(ec_tagname_t tagname
, uint64_t &target
) const;
188 bool AssignIfExist(ec_tagname_t tagname
, time_t &target
) const;
189 bool AssignIfExist(ec_tagname_t tagname
, double &target
) const;
190 bool AssignIfExist(ec_tagname_t tagname
, float &target
) const;
191 bool AssignIfExist(ec_tagname_t tagname
, CMD4Hash
&target
) const;
192 bool AssignIfExist(ec_tagname_t tagname
, std::string
&target
) const;
193 #ifdef USE_WX_EXTENSIONS
194 bool AssignIfExist(ec_tagname_t tagname
, wxString
&target
) const;
199 uint8_t GetType() const { return m_dataType
; }
201 bool ReadFromSocket(CECSocket
& socket
);
202 bool WriteTag(CECSocket
& socket
) const;
203 bool ReadChildren(CECSocket
& socket
);
204 bool WriteChildren(CECSocket
& socket
) const;
207 // To init. the automatic int data
208 void InitInt(uint64_t data
);
210 ec_tagname_t m_tagName
;
211 ec_tagtype_t m_dataType
;
212 ec_taglen_t m_dataLen
;
214 void NewData() { m_tagData
= new char[m_dataLen
]; }
216 typedef std::list
<CECTag
> TagList
;
219 static const CECTag s_theNullTag
;
221 // To be used by the string constructors.
222 void ConstructStringTag(ec_tagname_t name
, const std::string
& data
);
225 // Iteration through child tags
226 typedef TagList::const_iterator const_iterator
;
227 const_iterator
begin() const { return m_tagList
.begin(); }
228 const_iterator
end() const { return m_tagList
.end(); }
235 * Note, that an "empty" tag is empty because it contains no data, but it still
236 * may contain children.
238 class CECEmptyTag
: public CECTag
{
240 CECEmptyTag(ec_tagname_t name
= 0) : CECTag(name
, 0, (const void *) NULL
) {}
246 * This is just to easily overcome ctor ambiguity. It's prettier to write
247 * CECIntTag(name, some_value)
249 * CECTag(name, (uint64)value)
251 class CECIntTag
: public CECTag
{
253 CECIntTag(ec_tagname_t name
, uint64 data
) : CECTag(name
, data
) {}
257 // File_checked_for_headers