Bug Summary

File:rootdir/src/StatTree.cpp
Warning:line 110, column 31
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name StatTree.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -D USE_WX_EXTENSIONS -I /usr/lib/x86_64-linux-gnu/wx/include/gtk3-unicode-3.2 -I /usr/include/wx-3.2 -D _FILE_OFFSET_BITS=64 -D WXUSINGDLL -D __WXGTK__ -D ENABLE_IP2COUNTRY=1 -I ./libs -I libs -I ./include -D CLIENT_GUI -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-register -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2025-01-17-210641-60100-1 -x c++ StatTree.cpp
1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2005-2011 Dévai Tamás ( gonosztopi@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.
10//
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.
15//
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
24//
25
26#include "StatTree.h"
27
28#include <wx/intl.h>
29#include "OtherFunctions.h"
30
31#ifndef CLIENT_GUI1
32
33#include <common/Format.h> // Needed for CFormat
34
35#define a_brackets_b(a,b) (a + wxT(" (")L" (" + b + wxT(")")L")")
36
37#endif /* !CLIENT_GUI */
38
39#include <ec/cpp/ECTag.h> // Needed for CECTag
40
41#ifdef CLIENT_GUI1
42 #include <ec/cpp/ECSpecialTags.h> // Needed for CEC_StatTree_Node_Tag
43
44#else
45
46uint32_t NewStatTreeItemId()
47{
48 static uint32_t lastid = 0;
49
50 return ++lastid;
51}
52#endif
53
54/* CStatTreeItemBase */
55
56#ifdef CLIENT_GUI1
57CStatTreeItemBase::CStatTreeItemBase(const CECTag *tag)
58 : m_label(static_cast<const CEC_StatTree_Node_Tag*>(tag)->GetDisplayString()),
59 m_uniqueid(tag->GetTagByNameSafe(EC_TAG_STATTREE_NODEID)->GetInt())
60{
61 wxASSERT(tag->GetTagName() == EC_TAG_STATTREE_NODE)do { if ( tag->GetTagName() == EC_TAG_STATTREE_NODE ) { } else
if ( wxTheAssertHandler && (wxOnAssert("StatTree.cpp"
, 61, __FUNCTION__, "tag->GetTagName() == EC_TAG_STATTREE_NODE"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
62
63 for (CECTag::const_iterator it = tag->begin(); it != tag->end(); ++it) {
64 const CECTag *tmp = & *it;
65 if (tmp->GetTagName() == EC_TAG_STATTREE_NODE) {
66 m_children.push_back(new CStatTreeItemBase(tmp));
67 }
68 }
69}
70#endif /* CLIENT_GUI */
71
72CStatTreeItemBase::~CStatTreeItemBase()
73{
74 DeleteContents(m_children);
75}
76
77#ifndef CLIENT_GUI1
78CStatTreeItemBase* CStatTreeItemBase::AddChild(
79 CStatTreeItemBase* child,
80 uint32_t id,
81 bool skipOneLevel)
82{
83 wxMutexLocker lock(m_lock);
84
85 if (skipOneLevel) {
86 child->m_parent = m_parent;
87 } else {
88 child->m_parent = this;
89 }
90 child->m_id = id;
91
92 if (m_flags & stSortChildren) {
93 std::list<CStatTreeItemBase*>::iterator it = m_children.begin();
94 while (it != m_children.end() && id < (*it)->m_id) {
95 ++it;
96 }
97 m_children.insert(it, child);
98 } else {
99 m_children.push_back(child);
100 }
101 return child;
102}
103#endif /* !CLIENT_GUI */
104
105bool CStatTreeItemBase::HasVisibleChildren()
106{
107 wxMutexLocker lock(m_lock);
108
109 for (std::list<CStatTreeItemBase*>::const_iterator it = m_children.begin();
110 it != m_children.end(); ++it) {
This statement is never executed
111 if ((*it)->IsVisible()) {
112 return true;
113 }
114 }
115 return false;
116}
117
118#ifndef CLIENT_GUI1
119bool CStatTreeItemBase::HasChildWithId(uint32_t id)
120{
121 wxMutexLocker lock(m_lock);
122
123 for (std::list<CStatTreeItemBase*>::const_iterator it = m_children.begin();
124 it != m_children.end(); ++it) {
125 if ((*it)->m_id == id) {
126 return true;
127 }
128 }
129 return false;
130}
131
132CStatTreeItemBase* CStatTreeItemBase::GetChildById(uint32_t id)
133{
134 wxMutexLocker lock(m_lock);
135
136 for (std::list<CStatTreeItemBase*>::const_iterator it = m_children.begin();
137 it != m_children.end(); ++it) {
138 if ((*it)->m_id == id) {
139 return *it;
140 }
141 }
142 return NULL__null;
143}
144
145// Note: these functions do not lock the list, because it is already locked at the time they're called
146StatTreeItemIterator CStatTreeItemBase::GetFirstVisibleChild(uint32_t max_children)
147{
148 StatTreeItemIterator it = m_children.begin();
149 m_visible_counter = --max_children;
150 while (it != m_children.end() && !(*it)->IsVisible()) ++it;
151 return it;
152}
153
154void CStatTreeItemBase::GetNextVisibleChild(StatTreeItemIterator& it)
155{
156 if (m_flags & stCapChildren) {
157 if (m_visible_counter == 0) {
158 it = m_children.end();
159 return;
160 } else {
161 --m_visible_counter;
162 }
163 }
164 if (it != m_children.end()) ++it;
165 while (it != m_children.end() && !(*it)->IsVisible()) ++it;
166}
167
168//
169// Anything below is only for core.
170//
171
172bool CStatTreeItemBase::ValueSort(const CStatTreeItemBase* a, const CStatTreeItemBase* b)
173{
174 if (a->m_id < 0x00000100 || a->m_id > 0x7fffffff || b->m_id < 0x00000100 || b->m_id > 0x7fffffff) {
175 return a->m_id > b->m_id;
176 } else {
177 return dynamic_cast<const CStatTreeItemCounter*>(a)->GetValue() > dynamic_cast<const CStatTreeItemCounter*>(b)->GetValue();
178 }
179}
180
181#ifndef AMULE_DAEMON
182wxString CStatTreeItemBase::GetDisplayString() const
183{
184 return wxGetTranslation(m_label);
185}
186#endif
187
188CECTag *CStatTreeItemBase::CreateECTag(uint32_t max_children)
189{
190 if (IsVisible()) {
191 wxMutexLocker lock(m_lock);
192 CECTag *tag = new CECTag(EC_TAG_STATTREE_NODE, m_label);
193 tag->AddTag(CECTag(EC_TAG_STATTREE_NODEID, m_uniqueid));
194 AddECValues(tag);
195 m_visible_counter = max_children - 1;
196 for (std::list<CStatTreeItemBase*>::const_iterator it = m_children.begin();
197 it != m_children.end(); ++it) {
198 CECTag *tmp = (*it)->CreateECTag(max_children);
199 if (tmp) {
200 tag->AddTag(*tmp);
201 delete tmp;
202 if (m_flags & stCapChildren) {
203 if (m_visible_counter == 0) {
204 break;
205 } else {
206 --m_visible_counter;
207 }
208 }
209 }
210 }
211 return tag;
212 } else {
213 return NULL__null;
214 }
215}
216
217
218/* CStatTreeItemSimple */
219
220#ifndef AMULE_DAEMON
221wxString CStatTreeItemSimple::GetDisplayString() const
222{
223 switch (m_valuetype) {
224 case vtInteger:
225 switch (m_displaymode) {
226 case dmTime: return CFormat(wxGetTranslation(m_label)) % CastSecondsToHM(m_intvalue);
227 case dmBytes: return CFormat(wxGetTranslation(m_label)) % CastItoXBytes(m_intvalue);
228 default: return CFormat(wxGetTranslation(m_label)) % m_intvalue;
229 }
230 case vtFloat: return CFormat(wxGetTranslation(m_label)) % m_floatvalue;
231 case vtString: return CFormat(wxGetTranslation(m_label)) % m_stringvalue;
232 default: return wxGetTranslation(m_label);
233 }
234}
235#endif
236
237bool CStatTreeItemSimple::IsVisible() const
238{
239 if (m_flags & stHideIfZero) {
240 switch (m_valuetype) {
241 case vtInteger: return m_intvalue != 0;
242 case vtFloat: return m_floatvalue != 0.0;
243 case vtString: return !m_stringvalue.IsEmpty();
244 default: return false;
245 }
246 }
247 return true;
248}
249
250void CStatTreeItemSimple::AddECValues(CECTag *tag) const
251{
252 switch (m_valuetype) {
253 case vtInteger: {
254 if (m_displaymode == dmTime) {
255 CECTag value(EC_TAG_STAT_NODE_VALUE, (uint32)m_intvalue);
256 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_TIME));
257 tag->AddTag(value);
258 } else {
259 CECTag value(EC_TAG_STAT_NODE_VALUE, (uint64)m_intvalue);
260 if (m_displaymode == dmBytes) {
261 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
262 }
263 tag->AddTag(value);
264 }
265 break;
266 }
267 case vtFloat: {
268 CECTag value(EC_TAG_STAT_NODE_VALUE, m_floatvalue);
269 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_DOUBLE));
270 tag->AddTag(value);
271 break;
272 }
273 case vtString: {
274 CECTag value(EC_TAG_STAT_NODE_VALUE, m_stringvalue);
275 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_STRING));
276 tag->AddTag(value);
277 break;
278 }
279 default:
280 break;
281 }
282}
283
284
285/* CStatTreeItemCounterTmpl */
286
287#ifndef AMULE_DAEMON
288template<typename _Tp>
289wxString CStatTreeItemCounterTmpl<_Tp>::GetDisplayString() const
290{
291 wxString my_label = wxGetTranslation(m_label);
292 // This is needed for client names, for example
293 if (my_label == m_label) {
294 if (m_label.Right(4) == wxT(": %s")L": %s") {
295 my_label = wxGetTranslation(
296 m_label.Mid(0, m_label.Length() - 4)) +
297 wxString(wxT(": %s")L": %s");
298 }
299 }
300 CFormat label(my_label);
301 if (m_displaymode == dmBytes) {
302 return label % CastItoXBytes(m_value);
303 } else {
304 wxString result = CFormat(wxT("%u")L"%u") % m_value;
305 if ((m_flags & stShowPercent) && m_parent) {
306 result += CFormat(wxT(" (%.2f%%)")L" (%.2f%%)") % ((double(m_value) / dynamic_cast<CStatTreeItemCounterTmpl<_Tp>*>(m_parent)->m_value) * 100.0);
307 }
308 return label % result;
309 }
310}
311
312template wxString CStatTreeItemCounter::GetDisplayString() const;
313template wxString CStatTreeItemNativeCounter::GetDisplayString() const;
314
315#endif
316
317template<typename _Tp>
318void CStatTreeItemCounterTmpl<_Tp>::AddECValues(CECTag *tag) const
319{
320 CECTag value(EC_TAG_STAT_NODE_VALUE, (uint64)m_value);
321 if (m_displaymode == dmBytes) {
322 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
323 } else {
324 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_ISTRING));
325 if ((m_flags & stShowPercent) && m_parent) {
326 CECTag tmp(EC_TAG_STAT_NODE_VALUE,
327 (double(m_value) / dynamic_cast<CStatTreeItemCounterTmpl<_Tp>*>(m_parent)->m_value) * 100.0);
328 tmp.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_DOUBLE));
329 value.AddTag(tmp);
330 }
331 }
332 tag->AddTag(value);
333}
334
335template void CStatTreeItemCounter::AddECValues(CECTag *tag) const;
336template void CStatTreeItemNativeCounter::AddECValues(CECTag *tag) const;
337
338/* CStatTreeItemUlDlCounter */
339
340#ifndef AMULE_DAEMON
341wxString CStatTreeItemUlDlCounter::GetDisplayString() const
342{
343 return CFormat(wxGetTranslation(m_label)) %
344 a_brackets_b(CastItoXBytes(m_value), CastItoXBytes(m_value + m_totalfunc()));
345}
346#endif
347
348void CStatTreeItemUlDlCounter::AddECValues(CECTag *tag) const
349{
350 CECTag value(EC_TAG_STAT_NODE_VALUE, m_value);
351 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
352 CECTag tmp(EC_TAG_STAT_NODE_VALUE, m_value + m_totalfunc());
353 tmp.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
354 value.AddTag(tmp);
355 tag->AddTag(value);
356}
357
358
359/* CStatTreeItemCounterMax */
360
361#ifndef AMULE_DAEMON
362wxString CStatTreeItemCounterMax::GetDisplayString() const
363{
364 return CFormat(wxGetTranslation(m_label)) % m_value;
365}
366#endif
367
368void CStatTreeItemCounterMax::AddECValues(CECTag *tag) const
369{
370 tag->AddTag(CECTag(EC_TAG_STAT_NODE_VALUE, (uint64)m_value));
371}
372
373
374/* CStatTreeItemPackets */
375
376#ifndef AMULE_DAEMON
377wxString CStatTreeItemPackets::GetDisplayString() const
378{
379 return CFormat(wxGetTranslation(m_label)) %
380 a_brackets_b(CastItoXBytes(m_bytes), CastItoIShort(m_packets));
381}
382#endif
383
384void CStatTreeItemPackets::AddECValues(CECTag *tag) const
385{
386 CECTag value(EC_TAG_STAT_NODE_VALUE, m_bytes);
387 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
388 CECTag tmp(EC_TAG_STAT_NODE_VALUE, (uint64)m_packets);
389 tmp.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_ISHORT));
390 value.AddTag(tmp);
391 tag->AddTag(value);
392}
393
394
395/* CStatTreeItemPacketTotals */
396
397#ifndef AMULE_DAEMON
398wxString CStatTreeItemPacketTotals::GetDisplayString() const
399{
400 uint32_t tmp_packets = m_packets;
401 uint64_t tmp_bytes = m_bytes;
402 for (std::vector<CStatTreeItemPackets*>::const_iterator it = m_counters.begin();
403 it != m_counters.end(); ++it) {
404 tmp_packets += (*it)->m_packets;
405 tmp_bytes += (*it)->m_bytes;
406 }
407
408 return CFormat(wxGetTranslation(m_label)) %
409 a_brackets_b(CastItoXBytes(tmp_bytes), CastItoIShort(tmp_packets));
410}
411#endif
412
413void CStatTreeItemPacketTotals::AddECValues(CECTag *tag) const
414{
415 uint32_t tmp_packets = m_packets;
416 uint64_t tmp_bytes = m_bytes;
417 for (std::vector<CStatTreeItemPackets*>::const_iterator it = m_counters.begin();
418 it != m_counters.end(); ++it) {
419 tmp_packets += (*it)->m_packets;
420 tmp_bytes += (*it)->m_bytes;
421 }
422
423 CECTag value(EC_TAG_STAT_NODE_VALUE, tmp_bytes);
424 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
425 CECTag tmp(EC_TAG_STAT_NODE_VALUE, (uint64)tmp_packets);
426 tmp.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_ISHORT));
427 value.AddTag(tmp);
428 tag->AddTag(value);
429}
430
431
432/* CStatTreeItemTimer */
433
434#ifndef AMULE_DAEMON
435wxString CStatTreeItemTimer::GetDisplayString() const
436{
437 return CFormat(wxGetTranslation(m_label)) %
438 CastSecondsToHM(m_value ? GetTimerSeconds() : 0);
439}
440#endif
441
442void CStatTreeItemTimer::AddECValues(CECTag *tag) const
443{
444 CECTag value(EC_TAG_STAT_NODE_VALUE,
445 m_value ? (uint32)GetTimerSeconds() : (uint32)0);
446 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_TIME));
447 tag->AddTag(value);
448}
449
450
451/* CStatTreeItemAverage */
452
453#ifndef AMULE_DAEMON
454wxString CStatTreeItemAverage::GetDisplayString() const
455{
456 if ((*m_divisor) != 0) {
457 switch (m_displaymode) {
458 case dmBytes:
459 return CFormat(wxGetTranslation(m_label)) %
460 CastItoXBytes((*m_dividend)/(*m_divisor));
461 case dmTime:
462 return CFormat(wxGetTranslation(m_label)) %
463 CastSecondsToHM((*m_dividend)/(*m_divisor));
464 default:
465 return CFormat(wxGetTranslation(m_label)) %
466 (CFormat(wxT("%u")L"%u") % ((uint64)(*m_dividend)/(*m_divisor))).GetString();
467 }
468 } else {
469 return CFormat(wxGetTranslation(m_label)) % wxT("-")L"-";
470 }
471}
472#endif
473
474void CStatTreeItemAverage::AddECValues(CECTag *tag) const
475{
476 if ((*m_divisor) != 0) {
477 uint64 data = (*m_dividend)/(*m_divisor);
478 if (m_displaymode == dmTime) {
479 CECTag value(EC_TAG_STAT_NODE_VALUE, (uint32)data);
480 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_TIME));
481 tag->AddTag(value);
482 } else {
483 CECTag value(EC_TAG_STAT_NODE_VALUE, data);
484 if (m_displaymode == dmBytes) {
485 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_BYTES));
486 }
487 tag->AddTag(value);
488 }
489 } else {
490 CECTag value(EC_TAG_STAT_NODE_VALUE, wxString(wxT("-")L"-"));
491 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_STRING));
492 tag->AddTag(value);
493 }
494}
495
496
497/* CStatTreeItemAverageSpeed */
498
499#ifndef AMULE_DAEMON
500wxString CStatTreeItemAverageSpeed::GetDisplayString() const
501{
502 uint64 time = m_timer->GetTimerSeconds();
503 if (time) {
504 return CFormat(wxGetTranslation(m_label)) % CastItoSpeed((*m_counter)/time);
505 } else {
506 return CFormat(wxGetTranslation(m_label)) % CastItoSpeed(0);
507 }
508}
509#endif
510
511void CStatTreeItemAverageSpeed::AddECValues(CECTag *tag) const
512{
513 uint64 time = m_timer->GetTimerSeconds();
514 if (time) {
515 CECTag value(EC_TAG_STAT_NODE_VALUE, (uint32)((*m_counter)/time));
516 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_SPEED));
517 tag->AddTag(value);
518 } else {
519 CECTag value(EC_TAG_STAT_NODE_VALUE, (uint32)0);
520 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_SPEED));
521 tag->AddTag(value);
522 }
523}
524
525
526/* CStatTreeItemRatio */
527
528wxString CStatTreeItemRatio::GetString() const
529{
530 wxString ret;
531 double v1 = m_counter1->GetValue();
532 double v2 = m_counter2->GetValue();
533 if (v1 > 0 && v2 > 0) {
534 if (v2 < v1) {
535 ret = CFormat(wxT("%.2f : 1")L"%.2f : 1") % (v1 / v2);
536 } else {
537 ret = CFormat(wxT("1 : %.2f")L"1 : %.2f") % (v2 / v1);
538 }
539
540 if (m_totalfunc1 && m_totalfunc2) {
541 double t1 = m_totalfunc1() + v1;
542 double t2 = m_totalfunc2() + v2;
543 if (t2 < t1) {
544 ret += CFormat(wxT(" (%.2f : 1)")L" (%.2f : 1)") % (t1 / t2);
545 } else {
546 ret += CFormat(wxT(" (1 : %.2f)")L" (1 : %.2f)") % (t2 / t1);
547 }
548 }
549 } else {
550 ret = _("Not available")wxGetTranslation(("Not available"));
551 }
552 return ret;
553}
554
555#ifndef AMULE_DAEMON
556wxString CStatTreeItemRatio::GetDisplayString() const
557{
558 return CFormat(wxGetTranslation(m_label)) % GetString();
559}
560#endif
561
562void CStatTreeItemRatio::AddECValues(CECTag *tag) const
563{
564 CECTag value(EC_TAG_STAT_NODE_VALUE, GetString());
565 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_STRING));
566 tag->AddTag(value);
567}
568
569
570/* CStatTreeItemReconnects */
571
572#ifndef AMULE_DAEMON
573wxString CStatTreeItemReconnects::GetDisplayString() const
574{
575 return CFormat(wxGetTranslation(m_label)) % (m_value ? m_value - 1 : 0);
576}
577#endif
578
579void CStatTreeItemReconnects::AddECValues(CECTag *tag) const
580{
581 tag->AddTag(CECTag(EC_TAG_STAT_NODE_VALUE,
582 m_value ? (uint64)(m_value - 1) : (uint64)0));
583}
584
585/* CStatTreeItemMaxConnLimitReached */
586
587#ifndef AMULE_DAEMON
588wxString CStatTreeItemMaxConnLimitReached::GetDisplayString() const
589{
590 if (m_count) {
591 return CFormat(wxGetTranslation(m_label)) %
592 (CFormat(wxT("%i : %s %s")L"%i : %s %s") % m_count % m_time.FormatISODate() % m_time.FormatISOTime());
593 } else {
594 return CFormat(wxGetTranslation(m_label)) % _("Never")wxGetTranslation(("Never"));
595 }
596}
597#endif
598
599void CStatTreeItemMaxConnLimitReached::AddECValues(CECTag *tag) const
600{
601 wxString result;
602 if (m_count) {
603 result = CFormat(wxT("%i : %s %s")L"%i : %s %s") % m_count % m_time.FormatISODate() % m_time.FormatISOTime();
604 } else {
605 result = wxTRANSLATE("Never")"Never";
606 }
607 CECTag value(EC_TAG_STAT_NODE_VALUE, result);
608 value.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE, (uint8)EC_VALUE_STRING));
609 tag->AddTag(value);
610}
611
612/* CStatTreeItemTotalClients */
613
614#ifndef AMULE_DAEMON
615wxString CStatTreeItemTotalClients::GetDisplayString() const
616{
617 return CFormat(wxGetTranslation(m_label)) %
618 (m_known->GetValue() + m_unknown->GetValue()) %
619 m_known->GetValue();
620}
621#endif
622
623void CStatTreeItemTotalClients::AddECValues(CECTag *tag) const
624{
625 CECTag value1(EC_TAG_STAT_NODE_VALUE,
626 (uint64)(m_known->GetValue() + m_unknown->GetValue()));
627 tag->AddTag(value1);
628 CECTag value2(EC_TAG_STAT_NODE_VALUE,
629 (uint64)m_known->GetValue());
630 tag->AddTag(value2);
631}
632
633#endif /* !CLIENT_GUI */
634// File_checked_for_headers