Upstream tarball 20080304
[amule.git] / src / libs / ec / cpp / ECTag.h
blobf472c266a7b1b23952d24aefa420192e051a6548
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2004-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 //
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
8 // respective authors.
9 //
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.
19 //
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
25 #ifndef ECTAG_H
26 #define ECTAG_H
28 #include <iostream>
29 #include <sstream>
31 // Must be first!
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)
37 #else
38 #define EC_ASSERT(x) assert(x)
39 #endif
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
49 class CECSocket;
51 /**
52 * Class to hold IPv4 address.
54 class EC_IPv4_t {
55 public:
56 EC_IPv4_t() { }
57 EC_IPv4_t(uint32 ip, uint16 port)
59 m_ip[0] = ip & 0xff;
60 m_ip[1] = (ip >> 8) & 0xff;
61 m_ip[2] = (ip >> 16) & 0xff;
62 m_ip[3] = (ip >> 24) & 0xff;
63 m_port = port;
66 uint32 IP()
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());
84 #endif
86 uint8 m_ip[4];
87 uint16 m_port;
91 /**
92 * High level EC packet TAGs handler class
95 class CECTag {
96 public:
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);
111 #endif
112 CECTag(const CECTag& tag);
113 ~CECTag(void);
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);
131 return m_tagData;
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;
144 #endif
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);
153 if ( tag ) {
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);
161 if ( tag ) {
162 EC_ASSERT(
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);
173 if ( tag ) {
174 EC_ASSERT(
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();
210 #endif
212 protected:
214 uint8_t GetType() const { return m_dataType; }
216 enum BuildState {
217 bsName,
218 bsType,
219 bsLength,
220 bsLengthChld,
221 bsChildCnt,
222 bsChildren,
223 bsData1,
224 bsData2,
225 bsFinished
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;
236 int m_error;
237 const void * m_tagData;
239 BuildState m_state;
241 bool IsOk() const { return m_state == bsFinished; }
243 private:
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;
256 bool m_dynamic;
258 typedef std::vector<CECTag> TagList;
259 TagList m_tagList;
261 bool m_haschildren;
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);
272 * An empty TAG
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 {
278 public:
279 CECEmptyTag(ec_tagname_t name) : CECTag(name, 0, NULL, false) {}
280 protected:
281 CECEmptyTag(const CECSocket& socket) : CECTag(socket) {}
284 #endif /* ECTAG_H */
285 // File_checked_for_headers