Fix language getting reset to system default on saving preferences
[amule.git] / src / utils / fileview / Print.cpp
blob3f844f9e95419091b08c5355d1a6750de8edeb4d
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_*
35 #include "../../NetworkFunctions.h" // Needed for Uint32toStringIP
37 #include <cctype>
38 #include <map>
39 #include <iostream>
41 SDMODE g_stringDecodeMode;
43 wxString MakePrintableString(const wxString& s)
45 wxString str = s;
46 unsigned c = 0;
47 for (unsigned i = 0; i < str.length(); i++) {
48 c |= (wxChar) str[i];
51 if (c <= 0xff && GetStringsMode() != SD_NONE) {
52 wxCharBuffer buf = str.To8BitData();
53 wxString test = UTF82unicode(buf.data());
54 if (!test.empty()) {
55 str = test;
56 c = 0;
57 for (unsigned i = 0; i < str.length(); i++) {
58 c |= (wxChar) str[i];
63 wxString retval = wxT("\"");
65 if (GetStringsMode() == SD_DISPLAY) {
66 retval += str;
67 } else if (GetStringsMode() == SD_UTF8) {
68 str = wxString::From8BitData((const char *)str.utf8_str());
69 c = 0xff;
72 if (GetStringsMode() != SD_DISPLAY) {
73 for (unsigned i = 0; i < str.length(); i++) {
74 if (GetStringsMode() == SD_NONE ? ((unsigned)str[i] >= ' ' && (unsigned)str[i] <= 0x7f) : std::isprint(str[i])) {
75 retval += str[i];
76 } else if (c <= 0xff) {
77 retval += wxString::Format(wxT("\\x%02x"), str[i]);
78 } else {
79 retval += wxString::Format(wxT("\\u%04x"), str[i]);
84 retval += wxT("\"");
85 return retval;
88 std::ostream& operator<<(std::ostream& x, const CTimeT& y)
90 if ((time_t)y != 0) {
91 wxDateTime dt((time_t)y);
92 return x << (time_t)y << " (" << dt.Format(wxDefaultDateTimeFormat, wxDateTime::UTC) << " UTC)";
93 } else {
94 return x << "0 (Never)";
98 std::ostream& operator<<(std::ostream& x, const CKadIP& ip)
100 return x << hex(ip) << " (" << Uint32toStringIP(wxUINT32_SWAP_ALWAYS(ip)) << ')';
103 std::ostream& operator<<(std::ostream& x, const CeD2kIP& ip)
105 return x << hex(ip) << " (" << Uint32toStringIP(ip) << ')';
108 static inline wxString TagNameString(const wxString& name)
110 if (name.length() == 1) {
111 return wxString::Format(wxT("\"\\x%02x\""), name[0]);
112 } else if (name.length() > 1) {
113 if (name[0] == FT_GAPSTART || name[0] == FT_GAPEND) {
114 return wxString::Format(wxT("\"\\x%02x"), name[0]) + name.substr(1) + wxT("\"");
117 return wxT("\"") + name + wxT("\"");
120 #define TEST_VALUE(VALUE) if (value == VALUE) return #VALUE; else
122 const char* DecodeTagNameID(uint8_t value)
124 TEST_VALUE(FT_FILENAME)
125 TEST_VALUE(FT_FILESIZE)
126 TEST_VALUE(FT_FILESIZE_HI)
127 TEST_VALUE(FT_FILETYPE)
128 TEST_VALUE(FT_FILEFORMAT)
129 TEST_VALUE(FT_LASTSEENCOMPLETE)
130 TEST_VALUE(FT_TRANSFERRED)
131 TEST_VALUE(FT_GAPSTART)
132 TEST_VALUE(FT_GAPEND)
133 TEST_VALUE(FT_PARTFILENAME)
134 TEST_VALUE(FT_OLDDLPRIORITY)
135 TEST_VALUE(FT_STATUS)
136 TEST_VALUE(FT_SOURCES)
137 TEST_VALUE(FT_PERMISSIONS)
138 TEST_VALUE(FT_OLDULPRIORITY)
139 TEST_VALUE(FT_DLPRIORITY)
140 TEST_VALUE(FT_ULPRIORITY)
141 TEST_VALUE(FT_KADLASTPUBLISHKEY)
142 TEST_VALUE(FT_KADLASTPUBLISHSRC)
143 TEST_VALUE(FT_FLAGS)
144 TEST_VALUE(FT_DL_ACTIVE_TIME)
145 TEST_VALUE(FT_CORRUPTEDPARTS)
146 TEST_VALUE(FT_DL_PREVIEW)
147 TEST_VALUE(FT_KADLASTPUBLISHNOTES)
148 TEST_VALUE(FT_AICH_HASH)
149 TEST_VALUE(FT_COMPLETE_SOURCES)
150 TEST_VALUE(FT_PUBLISHINFO)
151 TEST_VALUE(FT_ATTRANSFERRED)
152 TEST_VALUE(FT_ATREQUESTED)
153 TEST_VALUE(FT_ATACCEPTED)
154 TEST_VALUE(FT_CATEGORY)
155 TEST_VALUE(FT_ATTRANSFERREDHI)
156 TEST_VALUE(FT_MEDIA_ARTIST)
157 TEST_VALUE(FT_MEDIA_ALBUM)
158 TEST_VALUE(FT_MEDIA_TITLE)
159 TEST_VALUE(FT_MEDIA_LENGTH)
160 TEST_VALUE(FT_MEDIA_BITRATE)
161 TEST_VALUE(FT_MEDIA_CODEC)
162 TEST_VALUE(FT_FILERATING)
163 return "??";
166 const char* DecodeTagName(const wxString& value)
168 TEST_VALUE(TAG_FILENAME)
169 TEST_VALUE(TAG_FILESIZE)
170 TEST_VALUE(TAG_FILESIZE_HI)
171 TEST_VALUE(TAG_FILETYPE)
172 TEST_VALUE(TAG_FILEFORMAT)
173 TEST_VALUE(TAG_COLLECTION)
174 TEST_VALUE(TAG_PART_PATH)
175 TEST_VALUE(TAG_PART_HASH)
176 TEST_VALUE(TAG_COPIED)
177 TEST_VALUE(TAG_GAP_START)
178 TEST_VALUE(TAG_GAP_END)
179 TEST_VALUE(TAG_DESCRIPTION)
180 TEST_VALUE(TAG_PING)
181 TEST_VALUE(TAG_FAIL)
182 TEST_VALUE(TAG_PREFERENCE)
183 TEST_VALUE(TAG_PORT)
184 TEST_VALUE(TAG_IP_ADDRESS)
185 TEST_VALUE(TAG_VERSION)
186 TEST_VALUE(TAG_TEMPFILE)
187 TEST_VALUE(TAG_PRIORITY)
188 TEST_VALUE(TAG_STATUS)
189 TEST_VALUE(TAG_SOURCES)
190 TEST_VALUE(TAG_AVAILABILITY)
191 TEST_VALUE(TAG_PERMISSIONS)
192 TEST_VALUE(TAG_QTIME)
193 TEST_VALUE(TAG_PARTS)
194 TEST_VALUE(TAG_PUBLISHINFO)
195 TEST_VALUE(TAG_MEDIA_ARTIST)
196 TEST_VALUE(TAG_MEDIA_ALBUM)
197 TEST_VALUE(TAG_MEDIA_TITLE)
198 TEST_VALUE(TAG_MEDIA_LENGTH)
199 TEST_VALUE(TAG_MEDIA_BITRATE)
200 TEST_VALUE(TAG_MEDIA_CODEC)
201 TEST_VALUE(TAG_ENCRYPTION)
202 TEST_VALUE(TAG_FILERATING)
203 TEST_VALUE(TAG_BUDDYHASH)
204 TEST_VALUE(TAG_CLIENTLOWID)
205 TEST_VALUE(TAG_SERVERPORT)
206 TEST_VALUE(TAG_SERVERIP)
207 TEST_VALUE(TAG_SOURCEUPORT)
208 TEST_VALUE(TAG_SOURCEPORT)
209 TEST_VALUE(TAG_SOURCEIP)
210 TEST_VALUE(TAG_SOURCETYPE)
211 return "??";
214 const char* DecodeTagType(uint8_t value)
216 TEST_VALUE(TAGTYPE_HASH16)
217 TEST_VALUE(TAGTYPE_STRING)
218 TEST_VALUE(TAGTYPE_UINT32)
219 TEST_VALUE(TAGTYPE_FLOAT32)
220 TEST_VALUE(TAGTYPE_BOOL)
221 TEST_VALUE(TAGTYPE_BOOLARRAY)
222 TEST_VALUE(TAGTYPE_BLOB)
223 TEST_VALUE(TAGTYPE_UINT16)
224 TEST_VALUE(TAGTYPE_UINT8)
225 TEST_VALUE(TAGTYPE_BSOB)
226 TEST_VALUE(TAGTYPE_UINT64)
227 TEST_VALUE(TAGTYPE_STR1)
228 TEST_VALUE(TAGTYPE_STR2)
229 TEST_VALUE(TAGTYPE_STR3)
230 TEST_VALUE(TAGTYPE_STR4)
231 TEST_VALUE(TAGTYPE_STR5)
232 TEST_VALUE(TAGTYPE_STR6)
233 TEST_VALUE(TAGTYPE_STR7)
234 TEST_VALUE(TAGTYPE_STR8)
235 TEST_VALUE(TAGTYPE_STR9)
236 TEST_VALUE(TAGTYPE_STR10)
237 TEST_VALUE(TAGTYPE_STR11)
238 TEST_VALUE(TAGTYPE_STR12)
239 TEST_VALUE(TAGTYPE_STR13)
240 TEST_VALUE(TAGTYPE_STR14)
241 TEST_VALUE(TAGTYPE_STR15)
242 TEST_VALUE(TAGTYPE_STR16)
243 TEST_VALUE(TAGTYPE_STR17)
244 TEST_VALUE(TAGTYPE_STR18)
245 TEST_VALUE(TAGTYPE_STR19)
246 TEST_VALUE(TAGTYPE_STR20)
247 TEST_VALUE(TAGTYPE_STR21)
248 TEST_VALUE(TAGTYPE_STR22)
249 return "??";
252 const char* DecodeServerTagNameID(uint8_t value)
254 TEST_VALUE(ST_SERVERNAME)
255 TEST_VALUE(ST_DESCRIPTION)
256 TEST_VALUE(ST_PING)
257 TEST_VALUE(ST_FAIL)
258 TEST_VALUE(ST_PREFERENCE)
259 TEST_VALUE(ST_DYNIP)
260 TEST_VALUE(ST_LASTPING_DEPRECATED)
261 TEST_VALUE(ST_MAXUSERS)
262 TEST_VALUE(ST_SOFTFILES)
263 TEST_VALUE(ST_HARDFILES)
264 TEST_VALUE(ST_LASTPING)
265 TEST_VALUE(ST_VERSION)
266 TEST_VALUE(ST_UDPFLAGS)
267 TEST_VALUE(ST_AUXPORTSLIST)
268 TEST_VALUE(ST_LOWIDUSERS)
269 TEST_VALUE(ST_UDPKEY)
270 TEST_VALUE(ST_UDPKEYIP)
271 TEST_VALUE(ST_TCPPORTOBFUSCATION)
272 TEST_VALUE(ST_UDPPORTOBFUSCATION)
273 return "??";
276 const char* DecodeFriendTagNameID(uint8_t value)
278 TEST_VALUE(FF_NAME)
279 return "??";
282 typedef std::map<uint32_t, const char*> FlagMap;
284 class CFlagDecoder
286 public:
287 void AddFlag(uint32_t bit, const char* name)
289 m_flags[bit] = name;
292 wxString DecodeFlags(uint32_t flags)
294 uint32_t cur_flag = 1;
295 wxString result;
296 while (flags) {
297 if (flags & 1) {
298 if (!result.empty()) {
299 result += wxT(" | ");
301 FlagMap::const_iterator it = m_flags.find(cur_flag);
302 if (it != m_flags.end()) {
303 result += wxString::FromAscii(it->second);
304 } else {
305 result += wxString::Format(wxT("%#x"), cur_flag);
308 cur_flag <<= 1;
309 flags >>= 1;
311 return result;
314 private:
315 FlagMap m_flags;
318 #define ADD_DECODER_FLAG(decoder, FLAG) decoder.AddFlag(FLAG, #FLAG)
320 std::ostream& operator<<(std::ostream& out, const CTag& tag)
322 out << "{ ";
323 if (tag.GetName().empty()) {
324 out << hex(tag.GetNameID()) << ' ' << DecodeTagNameID(tag.GetNameID());
325 } else {
326 out << TagNameString(tag.GetName()) << ' ';
327 bool name_decoded = false;
328 if (tag.IsInt() && tag.GetName().length() > 1) {
329 wxCharBuffer ascii_name = tag.GetName().ToAscii();
330 char gap_mark = ascii_name ? ascii_name[(size_t)0] : 0;
331 if (gap_mark == FT_GAPSTART || gap_mark == FT_GAPEND) {
332 unsigned long gapkey;
333 if (tag.GetName().Mid(1).ToULong(&gapkey)) {
334 out << DecodeTagNameID(gap_mark) << wxString::Format(wxT("[%lu]"), gapkey);
335 name_decoded = true;
339 if (!name_decoded) {
340 out << DecodeTagName(tag.GetName());
343 out << ", " << (unsigned)tag.GetType() << ' ' << DecodeTagType(tag.GetType()) << ", ";
344 if (tag.IsInt()) {
345 if (tag.GetName() == TAG_SOURCEIP) {
346 out << CKadIP(tag.GetInt());
347 } else if (tag.GetName() == TAG_SERVERIP) {
348 out << CeD2kIP(tag.GetInt());
349 } else if (tag.GetName() == TAG_ENCRYPTION) {
350 uint8_t enc = tag.GetInt();
351 out << hex(enc);
352 if (enc) {
353 CFlagDecoder decoder;
354 decoder.AddFlag(0x01, "CryptSupported");
355 decoder.AddFlag(0x02, "CryptRequested");
356 decoder.AddFlag(0x04, "CryptRequired");
357 decoder.AddFlag(0x08, "SupportsDirectCallback");
358 out << " (" << decoder.DecodeFlags(enc) << ')';
360 } else if (tag.GetNameID() == FT_LASTSEENCOMPLETE
361 || tag.GetNameID() == FT_KADLASTPUBLISHSRC
362 || tag.GetNameID() == FT_KADLASTPUBLISHNOTES
363 || tag.GetNameID() == FT_KADLASTPUBLISHKEY
365 out << CTimeT(tag.GetInt());
366 } else if (tag.GetName() == TAG_FILESIZE
367 || tag.GetNameID() == FT_FILESIZE
368 || tag.GetNameID() == FT_TRANSFERRED
369 || tag.GetNameID() == FT_ATTRANSFERRED
371 out << tag.GetInt() << " (" << CastItoXBytes(tag.GetInt()) << ')';
372 } else if (tag.GetNameID() == FT_ULPRIORITY
373 || tag.GetNameID() == FT_DLPRIORITY
374 || tag.GetNameID() == FT_OLDULPRIORITY
375 || tag.GetNameID() == FT_OLDDLPRIORITY
377 out << tag.GetInt() << ' ';
378 switch (tag.GetInt()) {
379 case PR_VERYLOW: out << "PR_VERYLOW"; break;
380 case PR_LOW: out << "PR_LOW"; break;
381 case PR_NORMAL: out << "PR_NORMAL"; break;
382 case PR_HIGH: out << "PR_HIGH"; break;
383 case PR_VERYHIGH: out << "PR_VERYHIGH"; break;
384 case PR_AUTO: out << "PR_AUTO"; break;
385 case PR_POWERSHARE: out << "PR_POWERSHARE"; break;
387 } else {
388 out << tag.GetInt();
390 } else if (tag.IsStr()) {
391 out << MakePrintableString(tag.GetStr());
392 } else if (tag.IsFloat()) {
393 out << tag.GetFloat();
394 } else if (tag.IsHash()) {
395 out << tag.GetHash();
396 } else if (tag.IsBlob()) {
397 out << wxString::Format(wxT("(size = %u)"), tag.GetBlobSize());
398 } else if (tag.IsBsob()) {
399 out << wxString::Format(wxT("(size = %u)"), tag.GetBsobSize());
400 } else {
401 out << "(...)";
403 out << " }";
404 return out;
407 std::ostream& operator<<(std::ostream& out, const CServerTag& tag)
409 out << "{ ";
410 if (tag.GetName().empty()) {
411 out << hex(tag.GetNameID()) << ' ' << DecodeServerTagNameID(tag.GetNameID());
412 } else {
413 out << TagNameString(tag.GetName());
415 out << ", " << (unsigned)tag.GetType() << ' ' << DecodeTagType(tag.GetType()) << ", ";
416 if (tag.IsInt()) {
417 if (tag.GetNameID() == ST_DYNIP || tag.GetNameID() == ST_UDPKEYIP) {
418 out << CeD2kIP(tag.GetInt());
419 } else if (tag.GetNameID() == ST_UDPKEY) {
420 out << hex((uint32_t)tag.GetInt());
421 } else if (tag.GetNameID() == ST_UDPFLAGS) {
422 uint32_t flags = tag.GetInt();
423 out << hex(flags);
424 if (flags) {
425 CFlagDecoder decoder;
426 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_EXT_GETSOURCES);
427 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_EXT_GETFILES);
428 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_NEWTAGS);
429 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_UNICODE);
430 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_EXT_GETSOURCES2);
431 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_LARGEFILES);
432 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_UDPOBFUSCATION);
433 ADD_DECODER_FLAG(decoder, SRV_UDPFLG_TCPOBFUSCATION);
434 out << " (" << decoder.DecodeFlags(flags) << ')';
436 } else if (tag.GetNameID() == ST_PREFERENCE) {
437 out << tag.GetInt() << ' ';
438 switch (tag.GetInt()) {
439 case 0: out << "SRV_PR_NORMAL"; break;
440 case 1: out << "SRV_PR_HIGH"; break;
441 case 2: out << "SRV_PR_LOW"; break;
442 default: out << "??";
444 } else {
445 out << tag.GetInt();
447 } else if (tag.IsStr()) {
448 out << MakePrintableString(tag.GetStr());
449 } else if (tag.IsFloat()) {
450 out << tag.GetFloat();
451 } else if (tag.IsHash()) {
452 out << tag.GetHash();
453 } else if (tag.IsBlob()) {
454 out << wxString::Format(wxT("(size = %u)"), tag.GetBlobSize());
455 } else if (tag.IsBsob()) {
456 out << wxString::Format(wxT("(size = %u)"), tag.GetBsobSize());
457 } else {
458 out << "(...)";
460 out << " }";
461 return out;
464 std::ostream& operator<<(std::ostream& out, const CFriendTag& tag)
466 out << "{ ";
467 if (tag.GetName().empty()) {
468 out << hex(tag.GetNameID()) << ' ' << DecodeFriendTagNameID(tag.GetNameID());
469 } else {
470 out << TagNameString(tag.GetName());
472 out << ", " << (unsigned)tag.GetType() << ' ' << DecodeTagType(tag.GetType()) << ", ";
473 if (tag.IsInt()) {
474 out << tag.GetInt();
475 } else if (tag.IsStr()) {
476 out << MakePrintableString(tag.GetStr());
477 } else if (tag.IsFloat()) {
478 out << tag.GetFloat();
479 } else if (tag.IsHash()) {
480 out << tag.GetHash();
481 } else if (tag.IsBlob()) {
482 out << wxString::Format(wxT("(size = %u)"), tag.GetBlobSize());
483 } else if (tag.IsBsob()) {
484 out << wxString::Format(wxT("(size = %u)"), tag.GetBsobSize());
485 } else {
486 out << "(...)";
488 out << " }";
489 return out;