Upstream tarball 20080905
[amule.git] / src / utils / fileview / Print.cpp
blobe3a21f5f45769b63ce831a073f1ab9186085b56e
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2008 Dévai Tamás ( gonosztopi@amule.org )
5 // Copyright (c) 2008 aMule Team ( admin@amule.org / http://www.amule.org )
6 //
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
9 // respective authors.
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.
20 //
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 #include "Print.h"
27 #include <wx/datetime.h>
28 #include <tags/FileTags.h>
29 #include <tags/ServerTags.h>
30 #include <tags/TagTypes.h>
31 #include <protocol/ed2k/Client2Server/UDP.h>
32 #include "../../OtherFunctions.h"
33 #include "../../Friend.h" // Needed for FF_NAME
34 #include ".././KnownFile.h" // Needed for PR_*
36 #include <cctype>
37 #include <map>
38 #include <iostream>
40 SDMODE g_stringDecodeMode;
42 wxString MakePrintableString(const wxString& s)
44 wxString str = s;
45 unsigned c = 0;
46 for (unsigned i = 0; i < str.length(); i++) {
47 c |= str[i];
49 if (GetStringsMode() != SD_NONE) {
50 while (c <= 0xff) {
51 // check for utf-8 -- wx conversion sucks
52 char* buf = new char[str.length() + 1];
53 for (unsigned i = 0; i < str.length(); i++) {
54 buf[i] = str[i];
56 buf[str.length()] = '\0';
57 wxString tmp = UTF82unicode(buf);
58 delete [] buf;
59 if (tmp.empty() || tmp == str) {
60 break;
61 } else {
62 str = tmp;
63 c = 0;
64 for (unsigned i = 0; i < str.length(); i++) {
65 c |= str[i];
70 wxString retval = wxT("\"");
72 if (GetStringsMode() == SD_DISPLAY) {
73 retval += str;
74 } else if (GetStringsMode() == SD_UTF8) {
75 str = wxString::From8BitData((const char *)str.utf8_str());
76 c = 0xff;
79 if (GetStringsMode() != SD_DISPLAY) {
80 for (unsigned i = 0; i < str.length(); i++) {
81 if (GetStringsMode() == SD_NONE ? ((unsigned)str[i] >= ' ' && (unsigned)str[i] <= 0x7f) : std::isprint(str[i])) {
82 retval += str[i];
83 } else if (c <= 0xff) {
84 retval += wxString::Format(wxT("\\x%02x"), str[i]);
85 } else {
86 retval += wxString::Format(wxT("\\u%04x"), str[i]);
91 retval += wxT("\"");
92 return retval;
95 static inline wxString Uint32toStringIP(uint32_t ip)
97 return wxString::Format(wxT("%u.%u.%u.%u"), (uint8_t)ip, (uint8_t)(ip>>8), (uint8_t)(ip>>16), (uint8_t)(ip>>24));
100 std::ostream& operator<<(std::ostream& x, const CTimeT& y)
102 if ((time_t)y != 0) {
103 wxDateTime dt((time_t)y);
104 return x << (time_t)y << " (" << dt.Format(wxDefaultDateTimeFormat, wxDateTime::UTC) << " UTC)";
105 } else {
106 return x << "0 (Never)";
110 std::ostream& operator<<(std::ostream& x, const CKadIP& ip)
112 return x << hex(ip) << " (" << Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)) << ')';
115 std::ostream& operator<<(std::ostream& x, const CeD2kIP& ip)
117 return x << hex(ip) << " (" << Uint32toStringIP(ip) << ')';
120 static inline wxString TagNameString(const wxString& name)
122 if (name.length() == 1) {
123 return wxString::Format(wxT("\"\\x%02x\""), name[0]);
124 } else if (name.length() > 1) {
125 if (name[0] == FT_GAPSTART || name[0] == FT_GAPEND) {
126 return wxString::Format(wxT("\"\\x%02x"), name[0]) + name.substr(1) + wxT("\"");
129 return wxT("\"") + name + wxT("\"");
132 #define TEST_VALUE(VALUE) if (value == VALUE) return #VALUE; else
134 const char* DecodeTagNameID(uint8_t value)
136 TEST_VALUE(FT_FILENAME)
137 TEST_VALUE(FT_FILESIZE)
138 TEST_VALUE(FT_FILESIZE_HI)
139 TEST_VALUE(FT_FILETYPE)
140 TEST_VALUE(FT_FILEFORMAT)
141 TEST_VALUE(FT_LASTSEENCOMPLETE)
142 TEST_VALUE(FT_TRANSFERRED)
143 TEST_VALUE(FT_GAPSTART)
144 TEST_VALUE(FT_GAPEND)
145 TEST_VALUE(FT_PARTFILENAME)
146 TEST_VALUE(FT_OLDDLPRIORITY)
147 TEST_VALUE(FT_STATUS)
148 TEST_VALUE(FT_SOURCES)
149 TEST_VALUE(FT_PERMISSIONS)
150 TEST_VALUE(FT_OLDULPRIORITY)
151 TEST_VALUE(FT_DLPRIORITY)
152 TEST_VALUE(FT_ULPRIORITY)
153 TEST_VALUE(FT_KADLASTPUBLISHKEY)
154 TEST_VALUE(FT_KADLASTPUBLISHSRC)
155 TEST_VALUE(FT_FLAGS)
156 TEST_VALUE(FT_DL_ACTIVE_TIME)
157 TEST_VALUE(FT_CORRUPTEDPARTS)
158 TEST_VALUE(FT_DL_PREVIEW)
159 TEST_VALUE(FT_KADLASTPUBLISHNOTES)
160 TEST_VALUE(FT_AICH_HASH)
161 TEST_VALUE(FT_COMPLETE_SOURCES)
162 TEST_VALUE(FT_PUBLISHINFO)
163 TEST_VALUE(FT_ATTRANSFERRED)
164 TEST_VALUE(FT_ATREQUESTED)
165 TEST_VALUE(FT_ATACCEPTED)
166 TEST_VALUE(FT_CATEGORY)
167 TEST_VALUE(FT_ATTRANSFERREDHI)
168 TEST_VALUE(FT_MEDIA_ARTIST)
169 TEST_VALUE(FT_MEDIA_ALBUM)
170 TEST_VALUE(FT_MEDIA_TITLE)
171 TEST_VALUE(FT_MEDIA_LENGTH)
172 TEST_VALUE(FT_MEDIA_BITRATE)
173 TEST_VALUE(FT_MEDIA_CODEC)
174 TEST_VALUE(FT_FILERATING)
175 return "??";
178 const char* DecodeTagName(const wxString& value)
180 TEST_VALUE(TAG_FILENAME)
181 TEST_VALUE(TAG_FILESIZE)
182 TEST_VALUE(TAG_FILESIZE_HI)
183 TEST_VALUE(TAG_FILETYPE)
184 TEST_VALUE(TAG_FILEFORMAT)
185 TEST_VALUE(TAG_COLLECTION)
186 TEST_VALUE(TAG_PART_PATH)
187 TEST_VALUE(TAG_PART_HASH)
188 TEST_VALUE(TAG_COPIED)
189 TEST_VALUE(TAG_GAP_START)
190 TEST_VALUE(TAG_GAP_END)
191 TEST_VALUE(TAG_DESCRIPTION)
192 TEST_VALUE(TAG_PING)
193 TEST_VALUE(TAG_FAIL)
194 TEST_VALUE(TAG_PREFERENCE)
195 TEST_VALUE(TAG_PORT)
196 TEST_VALUE(TAG_IP_ADDRESS)
197 TEST_VALUE(TAG_VERSION)
198 TEST_VALUE(TAG_TEMPFILE)
199 TEST_VALUE(TAG_PRIORITY)
200 TEST_VALUE(TAG_STATUS)
201 TEST_VALUE(TAG_SOURCES)
202 TEST_VALUE(TAG_AVAILABILITY)
203 TEST_VALUE(TAG_PERMISSIONS)
204 TEST_VALUE(TAG_QTIME)
205 TEST_VALUE(TAG_PARTS)
206 TEST_VALUE(TAG_PUBLISHINFO)
207 TEST_VALUE(TAG_MEDIA_ARTIST)
208 TEST_VALUE(TAG_MEDIA_ALBUM)
209 TEST_VALUE(TAG_MEDIA_TITLE)
210 TEST_VALUE(TAG_MEDIA_LENGTH)
211 TEST_VALUE(TAG_MEDIA_BITRATE)
212 TEST_VALUE(TAG_MEDIA_CODEC)
213 TEST_VALUE(TAG_ENCRYPTION)
214 TEST_VALUE(TAG_FILERATING)
215 TEST_VALUE(TAG_BUDDYHASH)
216 TEST_VALUE(TAG_CLIENTLOWID)
217 TEST_VALUE(TAG_SERVERPORT)
218 TEST_VALUE(TAG_SERVERIP)
219 TEST_VALUE(TAG_SOURCEUPORT)
220 TEST_VALUE(TAG_SOURCEPORT)
221 TEST_VALUE(TAG_SOURCEIP)
222 TEST_VALUE(TAG_SOURCETYPE)
223 return "??";
226 const char* DecodeTagType(uint8_t value)
228 TEST_VALUE(TAGTYPE_HASH16)
229 TEST_VALUE(TAGTYPE_STRING)
230 TEST_VALUE(TAGTYPE_UINT32)
231 TEST_VALUE(TAGTYPE_FLOAT32)
232 TEST_VALUE(TAGTYPE_BOOL)
233 TEST_VALUE(TAGTYPE_BOOLARRAY)
234 TEST_VALUE(TAGTYPE_BLOB)
235 TEST_VALUE(TAGTYPE_UINT16)
236 TEST_VALUE(TAGTYPE_UINT8)
237 TEST_VALUE(TAGTYPE_BSOB)
238 TEST_VALUE(TAGTYPE_UINT64)
239 TEST_VALUE(TAGTYPE_STR1)
240 TEST_VALUE(TAGTYPE_STR2)
241 TEST_VALUE(TAGTYPE_STR3)
242 TEST_VALUE(TAGTYPE_STR4)
243 TEST_VALUE(TAGTYPE_STR5)
244 TEST_VALUE(TAGTYPE_STR6)
245 TEST_VALUE(TAGTYPE_STR7)
246 TEST_VALUE(TAGTYPE_STR8)
247 TEST_VALUE(TAGTYPE_STR9)
248 TEST_VALUE(TAGTYPE_STR10)
249 TEST_VALUE(TAGTYPE_STR11)
250 TEST_VALUE(TAGTYPE_STR12)
251 TEST_VALUE(TAGTYPE_STR13)
252 TEST_VALUE(TAGTYPE_STR14)
253 TEST_VALUE(TAGTYPE_STR15)
254 TEST_VALUE(TAGTYPE_STR16)
255 TEST_VALUE(TAGTYPE_STR17)
256 TEST_VALUE(TAGTYPE_STR18)
257 TEST_VALUE(TAGTYPE_STR19)
258 TEST_VALUE(TAGTYPE_STR20)
259 TEST_VALUE(TAGTYPE_STR21)
260 TEST_VALUE(TAGTYPE_STR22)
261 return "??";
264 const char* DecodeServerTagNameID(uint8_t value)
266 TEST_VALUE(ST_SERVERNAME)
267 TEST_VALUE(ST_DESCRIPTION)
268 TEST_VALUE(ST_PING)
269 TEST_VALUE(ST_FAIL)
270 TEST_VALUE(ST_PREFERENCE)
271 TEST_VALUE(ST_DYNIP)
272 TEST_VALUE(ST_LASTPING_DEPRECATED)
273 TEST_VALUE(ST_MAXUSERS)
274 TEST_VALUE(ST_SOFTFILES)
275 TEST_VALUE(ST_HARDFILES)
276 TEST_VALUE(ST_LASTPING)
277 TEST_VALUE(ST_VERSION)
278 TEST_VALUE(ST_UDPFLAGS)
279 TEST_VALUE(ST_AUXPORTSLIST)
280 TEST_VALUE(ST_LOWIDUSERS)
281 TEST_VALUE(ST_UDPKEY)
282 TEST_VALUE(ST_UDPKEYIP)
283 TEST_VALUE(ST_TCPPORTOBFUSCATION)
284 TEST_VALUE(ST_UDPPORTOBFUSCATION)
285 return "??";
288 const char* DecodeFriendTagNameID(uint8_t value)
290 TEST_VALUE(FF_NAME)
291 return "??";
294 typedef std::map<uint32_t, const char*> FlagMap;
296 class CFlagDecoder
298 public:
299 void AddFlag(uint32_t bit, const char* name)
301 m_flags[bit] = name;
304 wxString DecodeFlags(uint32_t flags)
306 uint32_t cur_flag = 1;
307 wxString result;
308 while (flags) {
309 if (flags & 1) {
310 if (!result.empty()) {
311 result += wxT(" | ");
313 FlagMap::const_iterator it = m_flags.find(cur_flag);
314 if (it != m_flags.end()) {
315 result += wxString::FromAscii(it->second);
316 } else {
317 result += wxString::Format(wxT("%#x"), cur_flag);
320 cur_flag <<= 1;
321 flags >>= 1;
323 return result;
326 private:
327 FlagMap m_flags;
330 #define ADD_DECODER_FLAG(decoder, FLAG) decoder.AddFlag(FLAG, #FLAG)
332 std::ostream& operator<<(std::ostream& out, const CTag& tag)
334 out << "{ ";
335 if (tag.GetName().empty()) {
336 out << hex(tag.GetNameID()) << ' ' << DecodeTagNameID(tag.GetNameID());
337 } else {
338 out << TagNameString(tag.GetName()) << ' ';
339 bool name_decoded = false;
340 if (tag.IsInt() && tag.GetName().length() > 1) {
341 wxCharBuffer ascii_name = tag.GetName().ToAscii();
342 char gap_mark = ascii_name ? ascii_name[(size_t)0] : 0;
343 if (gap_mark == FT_GAPSTART || gap_mark == FT_GAPEND) {
344 unsigned long gapkey;
345 if (tag.GetName().Mid(1).ToULong(&gapkey)) {
346 out << DecodeTagNameID(gap_mark) << wxString::Format(wxT("[%lu]"), gapkey);
347 name_decoded = true;
351 if (!name_decoded) {
352 out << DecodeTagName(tag.GetName());
355 out << ", " << (unsigned)tag.GetType() << ' ' << DecodeTagType(tag.GetType()) << ", ";
356 if (tag.IsInt()) {
357 if (tag.GetName() == TAG_SOURCEIP) {
358 out << CKadIP(tag.GetInt());
359 } else if (tag.GetName() == TAG_SERVERIP) {
360 out << CeD2kIP(tag.GetInt());
361 } else if (tag.GetName() == TAG_ENCRYPTION) {
362 uint8_t enc = tag.GetInt();
363 out << hex(enc);
364 if (enc) {
365 CFlagDecoder decoder;
366 decoder.AddFlag(0x01, "CryptSupported");
367 decoder.AddFlag(0x02, "CryptRequested");
368 decoder.AddFlag(0x04, "CryptRequired");
369 decoder.AddFlag(0x08, "SupportsDirectCallback");
370 out << " (" << decoder.DecodeFlags(enc) << ')';
372 } else if (tag.GetNameID() == FT_LASTSEENCOMPLETE
373 || tag.GetNameID() == FT_KADLASTPUBLISHSRC
374 || tag.GetNameID() == FT_KADLASTPUBLISHNOTES
375 || tag.GetNameID() == FT_KADLASTPUBLISHKEY
377 out << CTimeT(tag.GetInt());
378 } else if (tag.GetName() == TAG_FILESIZE
379 || tag.GetNameID() == FT_FILESIZE
380 || tag.GetNameID() == FT_TRANSFERRED
381 || tag.GetNameID() == FT_ATTRANSFERRED
383 out << tag.GetInt() << " (" << CastItoXBytes(tag.GetInt()) << ')';
384 } else if (tag.GetNameID() == FT_ULPRIORITY
385 || tag.GetNameID() == FT_DLPRIORITY
386 || tag.GetNameID() == FT_OLDULPRIORITY
387 || tag.GetNameID() == FT_OLDDLPRIORITY
389 out << tag.GetInt() << ' ';
390 switch (tag.GetInt()) {
391 case PR_VERYLOW: out << "PR_VERYLOW"; break;
392 case PR_LOW: out << "PR_LOW"; break;
393 case PR_NORMAL: out << "PR_NORMAL"; break;
394 case PR_HIGH: out << "PR_HIGH"; break;
395 case PR_VERYHIGH: out << "PR_VERYHIGH"; break;
396 case PR_AUTO: out << "PR_AUTO"; break;
397 case PR_POWERSHARE: out << "PR_POWERSHARE"; break;
399 } else {
400 out << tag.GetInt();
402 } else if (tag.IsStr()) {
403 out << MakePrintableString(tag.GetStr());
404 } else if (tag.IsFloat()) {
405 out << tag.GetFloat();
406 } else if (tag.IsHash()) {
407 out << tag.GetHash();
408 } else if (tag.IsBlob()) {
409 out << wxString::Format(wxT("(size = %u)"), tag.GetBlobSize());
410 } else if (tag.IsBsob()) {
411 out << wxString::Format(wxT("(size = %u)"), tag.GetBsobSize());
412 } else {
413 out << "(...)";
415 out << " }";
416 return out;
419 std::ostream& operator<<(std::ostream& out, const CServerTag& tag)
421 out << "{ ";
422 if (tag.GetName().empty()) {
423 out << hex(tag.GetNameID()) << ' ' << DecodeServerTagNameID(tag.GetNameID());
424 } else {
425 out << TagNameString(tag.GetName());
427 out << ", " << (unsigned)tag.GetType() << ' ' << DecodeTagType(tag.GetType()) << ", ";
428 if (tag.IsInt()) {
429 if (tag.GetNameID() == ST_DYNIP || tag.GetNameID() == ST_UDPKEYIP) {
430 out << CeD2kIP(tag.GetInt());
431 } else if (tag.GetNameID() == ST_UDPKEY) {
432 out << hex((uint32_t)tag.GetInt());
433 } else if (tag.GetNameID() == ST_UDPFLAGS) {
434 uint32_t flags = tag.GetInt();
435 out << hex(flags);
436 if (flags) {
437 CFlagDecoder decoder;
438 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_EXT_GETSOURCES);
439 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_EXT_GETFILES);
440 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_NEWTAGS);
441 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_UNICODE);
442 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_EXT_GETSOURCES2);
443 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_LARGEFILES);
444 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_UDPOBFUSCATION);
445 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_TCPOBFUSCATION);
446 out << " (" << decoder.DecodeFlags(flags) << ')';
448 } else if (tag.GetNameID() == ST_PREFERENCE) {
449 out << tag.GetInt() << ' ';
450 switch (tag.GetInt()) {
451 case 0: out << "SRV_PR_NORMAL"; break;
452 case 1: out << "SRV_PR_HIGH"; break;
453 case 2: out << "SRV_PR_LOW"; break;
454 default: out << "??";
456 } else {
457 out << tag.GetInt();
459 } else if (tag.IsStr()) {
460 out << MakePrintableString(tag.GetStr());
461 } else if (tag.IsFloat()) {
462 out << tag.GetFloat();
463 } else if (tag.IsHash()) {
464 out << tag.GetHash();
465 } else if (tag.IsBlob()) {
466 out << wxString::Format(wxT("(size = %u)"), tag.GetBlobSize());
467 } else if (tag.IsBsob()) {
468 out << wxString::Format(wxT("(size = %u)"), tag.GetBsobSize());
469 } else {
470 out << "(...)";
472 out << " }";
473 return out;
476 std::ostream& operator<<(std::ostream& out, const CFriendTag& tag)
478 out << "{ ";
479 if (tag.GetName().empty()) {
480 out << hex(tag.GetNameID()) << ' ' << DecodeFriendTagNameID(tag.GetNameID());
481 } else {
482 out << TagNameString(tag.GetName());
484 out << ", " << (unsigned)tag.GetType() << ' ' << DecodeTagType(tag.GetType()) << ", ";
485 if (tag.IsInt()) {
486 out << tag.GetInt();
487 } else if (tag.IsStr()) {
488 out << MakePrintableString(tag.GetStr());
489 } else if (tag.IsFloat()) {
490 out << tag.GetFloat();
491 } else if (tag.IsHash()) {
492 out << tag.GetHash();
493 } else if (tag.IsBlob()) {
494 out << wxString::Format(wxT("(size = %u)"), tag.GetBlobSize());
495 } else if (tag.IsBsob()) {
496 out << wxString::Format(wxT("(size = %u)"), tag.GetBsobSize());
497 } else {
498 out << "(...)";
500 out << " }";
501 return out;