Bug Summary

File:rootdir/src/libs/ec/cpp/ECTag.cpp
Warning:line 646, column 41
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

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 ECTag.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/libs/ec/cpp -fcoverage-compilation-dir=/rootdir/src/libs/ec/cpp -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I ../../../.. -D USE_WX_EXTENSIONS -I ../../../../src -I ../../../../src/libs -I ../../../../src/include -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 wxUSE_GUI=0 -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-081402-14897-1 -x c++ ECTag.cpp
1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2004-2011 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.
14//
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
23//
24
25#ifdef __DEBUG__
26#define DEBUG_EC_IMPLEMENTATION
27
28#include <common/Format.h> // Needed for CFormat
29#endif
30
31#include "ECTag.h" // Needed for ECTag
32#include "ECSocket.h" // Needed for CECSocket
33#include "ECSpecialTags.h" // Needed for CValueMap
34#include "ECID.h" // Needed for CECID
35
36/**********************************************************
37 * *
38 * CECTag class *
39 * *
40 **********************************************************/
41
42//! Defines the Null tag which may be returned by GetTagByNameSafe.
43const CECTag CECTag::s_theNullTag;
44
45/**
46 * Creates a new null-valued CECTag instance
47 *
48 * @see s_theNullTag
49 * @see GetTagByNameSafe
50 */
51CECTag::CECTag() :
52 m_tagName(0),
53 m_dataType(EC_TAGTYPE_UNKNOWN),
54 m_dataLen(0),
55 m_tagData(NULL__null) // All access functions check m_dataType, so no need to allocate a dummy buffer.
56{
57}
58
59/**
60 * Creates a new CECTag instance from the given data
61 *
62 * @param name TAG name
63 * @param length length of data buffer
64 * @param data TAG data
65 *
66 */
67CECTag::CECTag(ec_tagname_t name, unsigned int length, const void *data) : m_tagName(name)
68{
69 if (data) {
70 m_dataLen = length;
71 NewData();
72 memcpy(m_tagData, data, m_dataLen);
73 } else {
74 EC_ASSERT(length == 0)do { if ( length == 0 ) { } else if ( wxTheAssertHandler &&
(wxOnAssert("ECTag.cpp", 74, __FUNCTION__, "length == 0", (const
char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false; asm
volatile ("int $3"); } } while ( (void)0, 0 )
;
75 m_dataLen = 0;
76 m_tagData = NULL__null;
77 }
78 m_dataType = EC_TAGTYPE_CUSTOM;
79}
80
81/**
82 * Creates a new CECTag instance for custom data
83 *
84 * @param name TAG name
85 * @param length length of data buffer that will be alloc'ed
86 * @param dataptr pointer to a void pointer which will be assigned the internal TAG data buffer
87 *
88 * \note TAG data buffer has to be filled with valid data after the ctor
89 */
90CECTag::CECTag(ec_tagname_t name, unsigned int length, void **dataptr) : m_tagName(name)
91{
92 m_dataLen = length;
93 NewData();
94 *dataptr = m_tagData;
95 m_dataType = EC_TAGTYPE_CUSTOM;
96}
97
98/**
99 * Creates a new CECTag instance, which contains an IPv4 address.
100 *
101 * This function takes care of the endianness of the port number.
102 *
103 * @param name TAG name
104 * @param data The EC_IPv4_t class containing the IPv4 address.
105 *
106 * @see GetIPv4Data()
107 */
108CECTag::CECTag(ec_tagname_t name, const EC_IPv4_t& data) : m_tagName(name)
109{
110
111 m_dataLen = sizeof(EC_IPv4_t);
112 NewData();
113 RawPokeUInt32( reinterpret_cast<EC_IPv4_t *>(m_tagData)->m_ip, RawPeekUInt32( data.m_ip ) );
114 reinterpret_cast<EC_IPv4_t *>(m_tagData)->m_port = ENDIAN_HTONS(data.m_port)( ((wxUint16) ( (((wxUint16) (data.m_port) & (wxUint16) 0x00ffU
) << 8) | (((wxUint16) (data.m_port) & (wxUint16) 0xff00U
) >> 8))) )
;
115 m_dataType = EC_TAGTYPE_IPV4;
116}
117
118/**
119 * Creates a new CECTag instance, which contains a MD4 hash.
120 *
121 * This function takes care to store hash in network byte order.
122 *
123 * @param name TAG name
124 * @param data The CMD4Hash class containing the MD4 hash.
125 *
126 * @see GetMD4Data()
127 */
128CECTag::CECTag(ec_tagname_t name, const CMD4Hash& data) : m_tagName(name)
129{
130 m_dataLen = 16;
131 NewData();
132 RawPokeUInt64( m_tagData, RawPeekUInt64( data.GetHash() ) );
133 RawPokeUInt64( m_tagData + 8, RawPeekUInt64( data.GetHash() + 8 ) );
134 m_dataType = EC_TAGTYPE_HASH16;
135}
136
137/**
138 * Creates a new CECTag instance, which contains a string
139 *
140 * @param name TAG name
141 * @param data wxString object, it's contents are converted to UTF-8.
142 *
143 * @see GetStringDataSTL()
144 */
145CECTag::CECTag(ec_tagname_t name, const std::string& data) : m_tagName(name)
146{
147 ConstructStringTag(name, data);
148}
149
150/**
151 * Creates a new CECTag instance, which contains a string
152 *
153 * @param name TAG name
154 * @param data wxString object, it's contents are converted to UTF-8.
155 *
156 * @see GetStringData()
157 */
158CECTag::CECTag(ec_tagname_t name, const wxString& data)
159{
160 ConstructStringTag(name, (const char*)unicode2UTF8(data));
161}
162CECTag::CECTag(ec_tagname_t name, const wxChar* data)
163{
164 ConstructStringTag(name, (const char*)unicode2UTF8(data));
165}
166
167/**
168 * Copy constructor
169 */
170CECTag::CECTag(const CECTag& tag)
171{
172 m_tagData = NULL__null;
173 *this = tag;
174}
175
176/**
177 * Creates a new CECTag instance, which contains an int value.
178 *
179 * This takes care of endianness problems with numbers.
180 *
181 * @param name TAG name.
182 * @param data number.
183 *
184 * @see GetInt()
185 */
186CECTag::CECTag(ec_tagname_t name, bool data) : m_tagName(name)
187{
188 InitInt(data);
189}
190CECTag::CECTag(ec_tagname_t name, uint8 data) : m_tagName(name)
191{
192 InitInt(data);
193}
194CECTag::CECTag(ec_tagname_t name, uint16 data) : m_tagName(name)
195{
196 InitInt(data);
197}
198CECTag::CECTag(ec_tagname_t name, uint32 data) : m_tagName(name)
199{
200 InitInt(data);
201}
202CECTag::CECTag(ec_tagname_t name, uint64 data) : m_tagName(name)
203{
204 InitInt(data);
205}
206
207void CECTag::InitInt(uint64 data)
208{
209 if (data <= 0xFF) {
210 m_dataType = EC_TAGTYPE_UINT8;
211 m_dataLen = 1;
212 } else if (data <= 0xFFFF) {
213 m_dataType = EC_TAGTYPE_UINT16;
214 m_dataLen = 2;
215 } else if (data <= 0xFFFFFFFF) {
216 m_dataType = EC_TAGTYPE_UINT32;
217 m_dataLen = 4;
218 } else {
219 m_dataType = EC_TAGTYPE_UINT64;
220 m_dataLen = 8;
221 }
222
223 NewData();
224
225 switch (m_dataType) {
226 case EC_TAGTYPE_UINT8:
227 PokeUInt8( m_tagData, (uint8) data );
228 break;
229 case EC_TAGTYPE_UINT16:
230 RawPokeUInt16( m_tagData, ENDIAN_HTONS((uint16) data )( ((wxUint16) ( (((wxUint16) ((uint16) data) & (wxUint16)
0x00ffU) << 8) | (((wxUint16) ((uint16) data) & (wxUint16
) 0xff00U) >> 8))) )
);
231 break;
232 case EC_TAGTYPE_UINT32:
233 RawPokeUInt32( m_tagData, ENDIAN_HTONL((uint32) data )( ((wxUint32) ( (((wxUint32) ((uint32) data) & (wxUint32)
0x000000ffU) << 24) | (((wxUint32) ((uint32) data) &
(wxUint32) 0x0000ff00U) << 8) | (((wxUint32) ((uint32)
data) & (wxUint32) 0x00ff0000U) >> 8) | (((wxUint32
) ((uint32) data) & (wxUint32) 0xff000000U) >> 24))
) )
);
234 break;
235 case EC_TAGTYPE_UINT64:
236 RawPokeUInt64( m_tagData, ENDIAN_HTONLL(data)( ((wxUint64) ( (((wxUint64) (data) & (wxUint64) 0x00000000000000ffull
) << 56) | (((wxUint64) (data) & (wxUint64) 0x000000000000ff00ull
) << 40) | (((wxUint64) (data) & (wxUint64) 0x0000000000ff0000ull
) << 24) | (((wxUint64) (data) & (wxUint64) 0x00000000ff000000ull
) << 8) | (((wxUint64) (data) & (wxUint64) 0x000000ff00000000ull
) >> 8) | (((wxUint64) (data) & (wxUint64) 0x0000ff0000000000ull
) >> 24) | (((wxUint64) (data) & (wxUint64) 0x00ff000000000000ull
) >> 40) | (((wxUint64) (data) & (wxUint64) 0xff00000000000000ull
) >> 56))) )
);
237 break;
238 }
239}
240
241/**
242 * Creates a new CECTag instance, which contains a double precision floating point number
243 *
244 * @param name TAG name
245 * @param data double number
246 *
247 * @note The actual data is converted to string representation, because we have not found
248 * yet an effective and safe way to transmit floating point numbers.
249 *
250 * @see GetDoubleData()
251 */
252CECTag::CECTag(ec_tagname_t name, double data) : m_tagName(name)
253{
254 std::ostringstream double_str;
255 double_str << data;
256 std::string double_string = double_str.str();
257 const char * double_chr = double_string.c_str();
258 m_dataLen = (ec_taglen_t)strlen(double_chr) + 1;
259 NewData();
260 memcpy(m_tagData, double_chr, m_dataLen);
261 m_dataType = EC_TAGTYPE_DOUBLE;
262}
263
264/**
265 * Destructor - frees allocated data and deletes child TAGs.
266 */
267CECTag::~CECTag(void)
268{
269 delete [] m_tagData;
270}
271
272/**
273 * Copy assignment operator.
274 *
275 * std::vector uses this, but the compiler-supplied version wouldn't properly
276 * handle m_dynamic and m_tagData. This wouldn't be necessary if m_tagData
277 * was a smart pointer (Hi, Kry!).
278 */
279CECTag& CECTag::operator=(const CECTag& tag)
280{
281 if (&tag != this) {
282 m_tagName = tag.m_tagName;
283 m_dataLen = tag.m_dataLen;
284 m_dataType = tag.m_dataType;
285 delete [] m_tagData;
286 if (m_dataLen != 0) {
287 NewData();
288 memcpy(m_tagData, tag.m_tagData, m_dataLen);
289 } else {
290 m_tagData = NULL__null;
291 }
292 m_tagList.clear();
293 for (const_iterator it = tag.begin(); it != tag.end(); ++it) {
294 m_tagList.push_back(*it);
295 }
296 }
297 return *this;
298}
299
300/**
301 * Compare operator.
302 *
303 */
304bool CECTag::operator==(const CECTag& tag) const
305{
306 return m_dataType == tag.m_dataType
307 && m_tagName == tag.m_tagName
308 && m_dataLen == tag.m_dataLen
309 && (m_dataLen == 0
310 || !memcmp(m_tagData, tag.m_tagData, m_dataLen))
311 && m_tagList == tag.m_tagList;
312}
313
314/**
315 * Add a child tag to this one. The tag argument is reset to an empty tag.
316 *
317 * Be very careful that this method swallows the content of \e tag, leaving \e tag empty.
318 * Thus, the following code won't work as expected:
319 * \code
320 * {
321 * CECPacket *p = new CECPacket(whatever);
322 * CECTag *t1 = new CECTag(whatever);
323 * CECTag *t2 = new CECTag(whatever);
324 * p->AddTag(*t1);
325 * t1->AddTag(*t2); // t2 won't be part of p !!!
326 * }
327 * \endcode
328 *
329 * To get the desired results, the above should be replaced with something like:
330 *
331 * \code
332 * {
333 * CECPacket *p = new CECPacket(whatever);
334 * CECTag *t1 = new CECTag(whatever);
335 * CECTag *t2 = new CECTag(whatever);
336 * t1->AddTag(*t2);
337 * delete t2; // we can safely delete the now empty t2 here, because t1 holds its content
338 * p->AddTag(*t1);
339 * delete t1; // now p holds the content of both t1 and t2
340 * }
341 * \endcode
342 *
343 * Then why copying? The answer is to enable simplifying the code like this:
344 *
345 * \code
346 * {
347 * CECPacket *p = new CECPacket(whatever);
348 * CECTag t1(whatever);
349 * t1.AddTag(CECTag(whatever)); // t2 is now created on-the-fly
350 * p->AddTag(t1); // now p holds a copy of both t1 and t2
351 * }
352 * \endcode
353 *
354 * @param tag a CECTag class instance to add.
355 * @return \b true if tag was really added,
356 * \b false when it was omitted through valuemap or the limit for children
357 * is exceeded.
358 */
359bool CECTag::AddTag(const CECTag& tag, CValueMap* valuemap)
360{
361 if (valuemap) {
362 return valuemap->AddTag(tag, this);
363 }
364 // cannot have more than 64k tags
365 if (m_tagList.size() >= 0xffff) {
366 return false;
367 }
368
369 // First add an empty tag.
370 m_tagList.push_back(CECEmptyTag());
371 // Then exchange the data. The original tag will be destroyed right after this call anyway.
372 // UGLY - GCC allows a reference to an in place constructed object only to be passed as const.
373 // So pass it the way it wants it and then cheat and cast it back to non-const. :-/
374 CECTag& wtag = const_cast<CECTag&>(tag);
375 wtag.swap(m_tagList.back());
376 return true;
377}
378
379void CECTag::AddTag(ec_tagname_t name, uint64_t data, CValueMap* valuemap)
380{
381 if (valuemap) {
382 valuemap->CreateTag(name, data, this);
383 } else {
384 AddTag(CECTag(name, data));
385 }
386}
387
388void CECTag::AddTag(ec_tagname_t name, const wxString& data, CValueMap* valuemap)
389{
390 if (valuemap) {
391 valuemap->CreateTag(name, data, this);
392 } else {
393 AddTag(CECTag(name, data));
394 }
395}
396
397void CECTag::AddTag(ec_tagname_t name, const CMD4Hash& data, CValueMap* valuemap)
398{
399 if (valuemap) {
400 valuemap->CreateTag(name, data, this);
401 } else {
402 AddTag(CECTag(name, data));
403 }
404}
405
406void CECTag::swap(CECTag& t2)
407{
408 std::swap(m_tagName, t2.m_tagName);
409 std::swap(m_dataType, t2.m_dataType);
410 std::swap(m_dataLen, t2.m_dataLen);
411 std::swap(m_tagData, t2.m_tagData);
412 std::swap(m_tagList, t2.m_tagList);
413}
414
415bool CECTag::ReadFromSocket(CECSocket& socket)
416{
417 ec_tagname_t tmp_tagName;
418 if (!socket.ReadNumber(&tmp_tagName, sizeof(ec_tagname_t))) {
419 return false;
420 }
421 m_tagName = tmp_tagName >> 1;
422 bool hasChildren = (tmp_tagName & 0x01) != 0;
423
424 if (!socket.ReadNumber(&m_dataType, sizeof(ec_tagtype_t))) {
425 return false;
426 }
427
428 if (!socket.ReadNumber(&m_dataLen, sizeof(ec_taglen_t))) {
429 return false;
430 }
431
432 if (hasChildren && !ReadChildren(socket)) {
433 return false;
434 }
435
436 unsigned int tmp_len = m_dataLen;
437 m_dataLen = 0;
438 m_dataLen = tmp_len - GetTagLen();
439 if (m_dataLen > 0) {
440 NewData();
441 if (!socket.ReadBuffer(m_tagData, m_dataLen)) {
442 return false;
443 }
444 } else {
445 m_tagData = NULL__null;
446 }
447
448 return true;
449}
450
451
452bool CECTag::WriteTag(CECSocket& socket) const
453{
454 ec_tagname_t tmp_tagName = (m_tagName << 1) | (m_tagList.empty() ? 0 : 1);
455 ec_tagtype_t type = m_dataType;
456 ec_taglen_t tagLen = GetTagLen();
457 EC_ASSERT(type != EC_TAGTYPE_UNKNOWN)do { if ( type != EC_TAGTYPE_UNKNOWN ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 457, __FUNCTION__, "type != EC_TAGTYPE_UNKNOWN"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
458
459 if (!socket.WriteNumber(&tmp_tagName, sizeof(ec_tagname_t))) return false;
460 if (!socket.WriteNumber(&type, sizeof(ec_tagtype_t))) return false;
461 if (!socket.WriteNumber(&tagLen, sizeof(ec_taglen_t))) return false;
462
463 if (!m_tagList.empty()) {
464 if (!WriteChildren(socket)) return false;
465 }
466
467 if (m_dataLen > 0) {
468 if (m_tagData != NULL__null) { // This is here only to make sure everything, it should not be NULL at this point
469 if (!socket.WriteBuffer(m_tagData, m_dataLen)) return false;
470 }
471 }
472
473 return true;
474}
475
476bool CECTag::ReadChildren(CECSocket& socket)
477{
478 uint16 tmp_tagCount;
479 if (!socket.ReadNumber(&tmp_tagCount, sizeof(uint16))) {
480 return false;
481 }
482 m_tagList.clear();
483 for (int i = 0; i < tmp_tagCount; i++) {
484 m_tagList.push_back(CECTag());
485 CECTag& tag = m_tagList.back();
486 if (!tag.ReadFromSocket(socket)) {
487 return false;
488 }
489 }
490 return true;
491}
492
493bool CECTag::WriteChildren(CECSocket& socket) const
494{
495 uint16 tmp = (uint16)m_tagList.size();
496 if (!socket.WriteNumber(&tmp, sizeof(tmp))) return false;
497 for (const_iterator it = begin(); it != end(); ++it) {
498 if (!it->WriteTag(socket)) return false;
499 }
500 return true;
501}
502
503/**
504 * Finds the (first) child tag with given name.
505 *
506 * @param name TAG name to look for.
507 * @return the tag found, or NULL.
508 */
509const CECTag* CECTag::GetTagByName(ec_tagname_t name) const
510{
511 for (const_iterator it = begin(); it != end(); ++it) {
512 if (it->m_tagName == name) return & *it;
513 }
514 return NULL__null;
515}
516
517/**
518 * Finds the (first) child tag with given name.
519 *
520 * @param name TAG name to look for.
521 * @return the tag found, or NULL.
522 */
523CECTag* CECTag::GetTagByName(ec_tagname_t name)
524{
525 for (TagList::iterator it = m_tagList.begin(); it != m_tagList.end(); ++it) {
526 if (it->m_tagName == name) return & *it;
527 }
528 return NULL__null;
529}
530
531/**
532 * Finds the (first) child tag with given name.
533 *
534 * @param name TAG name to look for.
535 * @return the tag found, or a special null-valued tag otherwise.
536 *
537 * @see s_theNullTag
538 */
539const CECTag* CECTag::GetTagByNameSafe(ec_tagname_t name) const
540{
541 const CECTag* result = GetTagByName(name);
542 if (result == NULL__null)
543 result = &s_theNullTag;
544 return result;
545}
546
547/**
548 * Query TAG length that is suitable for the TAGLEN field (i.e.\
549 * without it's own header size).
550 *
551 * @return Tag length, containing its childs' length.
552 */
553uint32 CECTag::GetTagLen(void) const
554{
555 uint32 length = m_dataLen;
556 for (const_iterator it = begin(); it != end(); ++it) {
557 length += it->GetTagLen();
558 length += sizeof(ec_tagname_t) + sizeof(ec_tagtype_t) + sizeof(ec_taglen_t) + (it->HasChildTags() ? 2 : 0);
559 }
560 return length;
561}
562
563
564uint64_t CECTag::GetInt() const
565{
566 if (m_tagData == NULL__null) {
567 // Empty tag - This is NOT an error.
568 EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( m_dataType == EC_TAGTYPE_UNKNOWN ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 568, __FUNCTION__, "m_dataType == EC_TAGTYPE_UNKNOWN"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
569 return 0;
570 }
571
572 switch (m_dataType) {
573 case EC_TAGTYPE_UINT8:
574 return PeekUInt8(m_tagData);
575 case EC_TAGTYPE_UINT16:
576 return ENDIAN_NTOHS( RawPeekUInt16( m_tagData ) )( ((wxUint16) ( (((wxUint16) (RawPeekUInt16( m_tagData )) &
(wxUint16) 0x00ffU) << 8) | (((wxUint16) (RawPeekUInt16
( m_tagData )) & (wxUint16) 0xff00U) >> 8))) )
;
577 case EC_TAGTYPE_UINT32:
578 return ENDIAN_NTOHL( RawPeekUInt32( m_tagData ) )( ((wxUint32) ( (((wxUint32) (RawPeekUInt32( m_tagData )) &
(wxUint32) 0x000000ffU) << 24) | (((wxUint32) (RawPeekUInt32
( m_tagData )) & (wxUint32) 0x0000ff00U) << 8) | ((
(wxUint32) (RawPeekUInt32( m_tagData )) & (wxUint32) 0x00ff0000U
) >> 8) | (((wxUint32) (RawPeekUInt32( m_tagData )) &
(wxUint32) 0xff000000U) >> 24))) )
;
579 case EC_TAGTYPE_UINT64:
580 return ENDIAN_NTOHLL( RawPeekUInt64( m_tagData ) )( ((wxUint64) ( (((wxUint64) (RawPeekUInt64( m_tagData )) &
(wxUint64) 0x00000000000000ffull) << 56) | (((wxUint64
) (RawPeekUInt64( m_tagData )) & (wxUint64) 0x000000000000ff00ull
) << 40) | (((wxUint64) (RawPeekUInt64( m_tagData )) &
(wxUint64) 0x0000000000ff0000ull) << 24) | (((wxUint64
) (RawPeekUInt64( m_tagData )) & (wxUint64) 0x00000000ff000000ull
) << 8) | (((wxUint64) (RawPeekUInt64( m_tagData )) &
(wxUint64) 0x000000ff00000000ull) >> 8) | (((wxUint64)
(RawPeekUInt64( m_tagData )) & (wxUint64) 0x0000ff0000000000ull
) >> 24) | (((wxUint64) (RawPeekUInt64( m_tagData )) &
(wxUint64) 0x00ff000000000000ull) >> 40) | (((wxUint64
) (RawPeekUInt64( m_tagData )) & (wxUint64) 0xff00000000000000ull
) >> 56))) )
;
581 case EC_TAGTYPE_UNKNOWN:
582 // Empty tag - This is NOT an error.
583 return 0;
584 default:
585 EC_ASSERT(0)do { if ( 0 ) { } else if ( wxTheAssertHandler && (wxOnAssert
("ECTag.cpp", 585, __FUNCTION__, "0", (const char*)__null), wxTrapInAssert
) ) { wxTrapInAssert = false; asm volatile ("int $3"); } } while
( (void)0, 0 )
;
586 return 0;
587 }
588}
589
590
591std::string CECTag::GetStringDataSTL() const
592{
593 if (m_dataType != EC_TAGTYPE_STRING) {
594 EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( m_dataType == EC_TAGTYPE_UNKNOWN ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 594, __FUNCTION__, "m_dataType == EC_TAGTYPE_UNKNOWN"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
595 return std::string();
596 } else if (m_tagData == NULL__null) {
597 EC_ASSERT(false)do { if ( false ) { } else if ( wxTheAssertHandler &&
(wxOnAssert("ECTag.cpp", 597, __FUNCTION__, "false", (const char
*)__null), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile
("int $3"); } } while ( (void)0, 0 )
;
598 return std::string();
599 }
600
601 return std::string(m_tagData);
602}
603
604
605#ifdef USE_WX_EXTENSIONS1
606wxString CECTag::GetStringData() const
607{
608 return UTF82unicode(GetStringDataSTL().c_str());
609}
610#endif
611
612
613CMD4Hash CECTag::GetMD4Data() const
614{
615 if (m_dataType != EC_TAGTYPE_HASH16) {
616 EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( m_dataType == EC_TAGTYPE_UNKNOWN ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 616, __FUNCTION__, "m_dataType == EC_TAGTYPE_UNKNOWN"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
617 return CMD4Hash();
618 }
619
620 EC_ASSERT(m_tagData != NULL)do { if ( m_tagData != __null ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 620, __FUNCTION__, "m_tagData != __null"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
621
622 // Doesn't matter if m_tagData is NULL in CMD4Hash(),
623 // that'll just result in an empty hash.
624 return CMD4Hash((const unsigned char *)m_tagData);
625}
626
627
628/**
629 * Returns an EC_IPv4_t class.
630 *
631 * This function takes care of the endianness of the port number.
632 *
633 * @return EC_IPv4_t class.
634 *
635 * @see CECTag(ec_tagname_t, const EC_IPv4_t&)
636 */
637EC_IPv4_t CECTag::GetIPv4Data() const
638{
639 EC_IPv4_t p(0, 0);
640
641 if (m_dataType != EC_TAGTYPE_IPV4) {
642 EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( m_dataType == EC_TAGTYPE_UNKNOWN ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 642, __FUNCTION__, "m_dataType == EC_TAGTYPE_UNKNOWN"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
643 } else if (m_tagData == NULL__null) {
644 EC_ASSERT(false)do { if ( false ) { } else if ( wxTheAssertHandler &&
(wxOnAssert("ECTag.cpp", 644, __FUNCTION__, "false", (const char
*)__null), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile
("int $3"); } } while ( (void)0, 0 )
;
645 } else {
646 RawPokeUInt32( p.m_ip, RawPeekUInt32( reinterpret_cast<EC_IPv4_t *>(m_tagData)->m_ip ) );
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
647 p.m_port = ENDIAN_NTOHS(reinterpret_cast<EC_IPv4_t *>(m_tagData)->m_port)( ((wxUint16) ( (((wxUint16) (reinterpret_cast<EC_IPv4_t *
>(m_tagData)->m_port) & (wxUint16) 0x00ffU) <<
8) | (((wxUint16) (reinterpret_cast<EC_IPv4_t *>(m_tagData
)->m_port) & (wxUint16) 0xff00U) >> 8))) )
;
648 }
649
650 return p;
651}
652
653/**
654 * Returns a double value.
655 *
656 * @note The returned value is what we get by converting the string form
657 * of the number to a double.
658 *
659 * @return The double value of the tag.
660 *
661 * @see CECTag(ec_tagname_t, double)
662 */
663double CECTag::GetDoubleData(void) const
664{
665 if (m_dataType != EC_TAGTYPE_DOUBLE) {
666 EC_ASSERT(m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( m_dataType == EC_TAGTYPE_UNKNOWN ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 666, __FUNCTION__, "m_dataType == EC_TAGTYPE_UNKNOWN"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
667 return 0;
668 } else if (m_tagData == NULL__null) {
669 EC_ASSERT(false)do { if ( false ) { } else if ( wxTheAssertHandler &&
(wxOnAssert("ECTag.cpp", 669, __FUNCTION__, "false", (const char
*)__null), wxTrapInAssert) ) { wxTrapInAssert = false; asm volatile
("int $3"); } } while ( (void)0, 0 )
;
670 return 0;
671 }
672
673 std::istringstream double_str(m_tagData);
674
675 double data;
676 double_str >> data;
677 return data;
678}
679
680
681void CECTag::ConstructStringTag(ec_tagname_t name, const std::string& data)
682{
683 m_tagName = name;
684 m_dataLen = (ec_taglen_t)strlen(data.c_str()) + 1;
685 NewData();
686 memcpy(m_tagData, data.c_str(), m_dataLen);
687 m_dataType = EC_TAGTYPE_STRING;
688}
689
690void CECTag::SetStringData(const wxString& s)
691{
692 if (IsString()) {
693 delete [] m_tagData;
694 ConstructStringTag(m_tagName, (const char*)unicode2UTF8(s));
695 }
696}
697
698
699bool CECTag::AssignIfExist(ec_tagname_t tagname, bool *target) const
700{
701 bool ret = false;
702 const CECTag *tag = GetTagByName(tagname);
703 if (tag) {
704 ret = tag->GetInt() > 0;
705 if (target) {
706 *target = ret;
707 }
708 }
709 return ret;
710}
711
712bool CECTag::AssignIfExist(ec_tagname_t tagname, bool &target) const
713{
714 const CECTag *tag = GetTagByName(tagname);
715 if (tag) {
716 target = tag->GetInt() > 0;
717 return true;
718 }
719 return false;
720}
721
722uint8_t CECTag::AssignIfExist(ec_tagname_t tagname, uint8_t *target) const
723{
724 uint8_t ret = 0;
725 const CECTag *tag = GetTagByName(tagname);
726 if (tag) {
727 EC_ASSERT((tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN))do { if ( (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType
== EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler &&
(wxOnAssert("ECTag.cpp", 727, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
728 ret = tag->GetInt();
729 if (target) {
730 *target = ret;
731 }
732 }
733 return ret;
734}
735
736bool CECTag::AssignIfExist(ec_tagname_t tagname, uint8_t &target) const
737{
738 const CECTag *tag = GetTagByName(tagname);
739 if (tag) {
740 EC_ASSERT((tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN))do { if ( (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType
== EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler &&
(wxOnAssert("ECTag.cpp", 740, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
741 target = tag->GetInt();
742 return true;
743 }
744 return false;
745}
746
747uint16_t CECTag::AssignIfExist(ec_tagname_t tagname, uint16_t *target) const
748{
749 uint16_t ret = 0;
750 const CECTag *tag = GetTagByName(tagname);
751 if (tag) {
752 EC_ASSERT(do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 756, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
753 (tag->GetType() == EC_TAGTYPE_UINT16)do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 756, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
754 || (tag->GetType() == EC_TAGTYPE_UINT8)do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 756, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
755 || (m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 756, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
756 )do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 756, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
757 ret = tag->GetInt();
758 if (target) {
759 *target = ret;
760 }
761 }
762 return ret;
763}
764
765bool CECTag::AssignIfExist(ec_tagname_t tagname, uint16_t &target) const
766{
767 const CECTag *tag = GetTagByName(tagname);
768 if (tag) {
769 EC_ASSERT(do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 773, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
770 (tag->GetType() == EC_TAGTYPE_UINT16)do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 773, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
771 || (tag->GetType() == EC_TAGTYPE_UINT8)do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 773, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
772 || (m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 773, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
773 )do { if ( (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->
GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN
) ) { } else if ( wxTheAssertHandler && (wxOnAssert("ECTag.cpp"
, 773, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
774 target = tag->GetInt();
775 return true;
776 }
777 return false;
778}
779
780uint32_t CECTag::AssignIfExist(ec_tagname_t tagname, uint32_t *target) const
781{
782 uint32_t ret = 0;
783 const CECTag *tag = GetTagByName(tagname);
784 if (tag) {
785 EC_ASSERT(do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 790, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
786 (tag->GetType() == EC_TAGTYPE_UINT32)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 790, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
787 || (tag->GetType() == EC_TAGTYPE_UINT16)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 790, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
788 || (tag->GetType() == EC_TAGTYPE_UINT8)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 790, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
789 || (m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 790, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
790 )do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 790, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
791 ret = tag->GetInt();
792 if (target) {
793 *target = ret;
794 }
795 }
796 return ret;
797}
798
799bool CECTag::AssignIfExist(ec_tagname_t tagname, uint32_t &target) const
800{
801 const CECTag *tag = GetTagByName(tagname);
802 if (tag) {
803 EC_ASSERT(do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 808, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
804 (tag->GetType() == EC_TAGTYPE_UINT32)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 808, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
805 || (tag->GetType() == EC_TAGTYPE_UINT16)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 808, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
806 || (tag->GetType() == EC_TAGTYPE_UINT8)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 808, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
807 || (m_dataType == EC_TAGTYPE_UNKNOWN)do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 808, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
808 )do { if ( (tag->GetType() == EC_TAGTYPE_UINT32) || (tag->
GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8
) || (m_dataType == EC_TAGTYPE_UNKNOWN) ) { } else if ( wxTheAssertHandler
&& (wxOnAssert("ECTag.cpp", 808, __FUNCTION__, "(tag->GetType() == EC_TAGTYPE_UINT32) || (tag->GetType() == EC_TAGTYPE_UINT16) || (tag->GetType() == EC_TAGTYPE_UINT8) || (m_dataType == EC_TAGTYPE_UNKNOWN)"
, (const char*)__null), wxTrapInAssert) ) { wxTrapInAssert = false
; asm volatile ("int $3"); } } while ( (void)0, 0 )
;
809 target = tag->GetInt();
810 return true;
811 }
812 return false;
813}
814
815uint64_t CECTag::AssignIfExist(ec_tagname_t tagname, uint64_t *target) const
816{
817 uint64_t ret = 0;
818 const CECTag *tag = GetTagByName(tagname);
819 if (tag) {
820 ret = tag->GetInt();
821 if (target) {
822 *target = ret;
823 }
824 }
825 return ret;
826}
827
828bool CECTag::AssignIfExist(ec_tagname_t tagname, uint64_t &target) const
829{
830 const CECTag *tag = GetTagByName(tagname);
831 if (tag) {
832 target = tag->GetInt();
833 return true;
834 }
835 return false;
836}
837
838time_t CECTag::AssignIfExist(ec_tagname_t tagname, time_t *target) const
839{
840 time_t ret = 0;
841 const CECTag *tag = GetTagByName(tagname);
842 if (tag) {
843 ret = tag->GetInt();
844 if (target) {
845 *target = ret;
846 }
847 }
848 return ret;
849}
850
851bool CECTag::AssignIfExist(ec_tagname_t tagname, time_t &target) const
852{
853 const CECTag *tag = GetTagByName(tagname);
854 if (tag) {
855 target = tag->GetInt();
856 return true;
857 }
858 return false;
859}
860
861double CECTag::AssignIfExist(ec_tagname_t tagname, double *target) const
862{
863 double ret = 0.0;
864 const CECTag *tag = GetTagByName(tagname);
865 if (tag) {
866 ret = tag->GetDoubleData();
867 if (target) {
868 *target = ret;
869 }
870 }
871 return ret;
872}
873
874bool CECTag::AssignIfExist(ec_tagname_t tagname, double &target) const
875{
876 const CECTag *tag = GetTagByName(tagname);
877 if (tag) {
878 target = tag->GetDoubleData();
879 return true;
880 }
881 return false;
882}
883
884float CECTag::AssignIfExist(ec_tagname_t tagname, float *target) const
885{
886 float ret = 0.0;
887 const CECTag *tag = GetTagByName(tagname);
888 if (tag) {
889 ret = tag->GetDoubleData();
890 if (target) {
891 *target = ret;
892 }
893 }
894 return ret;
895}
896
897bool CECTag::AssignIfExist(ec_tagname_t tagname, float &target) const
898{
899 const CECTag *tag = GetTagByName(tagname);
900 if (tag) {
901 target = tag->GetDoubleData();
902 return true;
903 }
904 return false;
905}
906
907CMD4Hash CECTag::AssignIfExist(ec_tagname_t tagname, CMD4Hash *target) const
908{
909 CMD4Hash ret;
910 const CECTag *tag = GetTagByName(tagname);
911 if (tag) {
912 ret = tag->GetMD4Data();
913 if (target) {
914 *target = ret;
915 }
916 }
917 return ret;
918}
919
920bool CECTag::AssignIfExist(ec_tagname_t tagname, CMD4Hash &target) const
921{
922 const CECTag *tag = GetTagByName(tagname);
923 if (tag) {
924 target = tag->GetMD4Data();
925 return true;
926 }
927 return false;
928}
929
930std::string CECTag::AssignIfExist(ec_tagname_t tagname, std::string *target) const
931{
932 std::string ret;
933 const CECTag *tag = GetTagByName(tagname);
934 if (tag) {
935 ret = tag->GetStringDataSTL();
936 if (target) {
937 *target = ret;
938 }
939 }
940 return ret;
941}
942
943bool CECTag::AssignIfExist(ec_tagname_t tagname, std::string &target) const
944{
945 const CECTag *tag = GetTagByName(tagname);
946 if (tag) {
947 target = tag->GetStringDataSTL();
948 return true;
949 }
950 return false;
951}
952
953#ifdef USE_WX_EXTENSIONS1
954wxString CECTag::AssignIfExist(ec_tagname_t tagname, wxString *target) const
955{
956 wxString ret;
957 const CECTag *tag = GetTagByName(tagname);
958 if (tag) {
959 ret = tag->GetStringData();
960 if (target) {
961 *target = ret;
962 }
963 }
964 return ret;
965}
966
967bool CECTag::AssignIfExist(ec_tagname_t tagname, wxString &target) const
968{
969 const CECTag *tag = GetTagByName(tagname);
970 if (tag) {
971 target = tag->GetStringData();
972 return true;
973 }
974 return false;
975}
976#endif
977
978
979#ifdef __DEBUG__
980#include "ECLog.h"
981
982void CECTag::DebugPrint(int level, bool print_empty) const
983{
984 if (m_dataLen || print_empty) {
985 wxString space;
986 for (int i = level; i--;) space += wxT(" ")L" ";
987 wxString s1 = CFormat(wxT("%s%s %d = ")L"%s%s %d = ") % space % GetDebugNameECTagNames(m_tagName) % m_dataLen;
988 wxString s2;
989 switch (m_tagName) {
990 case EC_TAG_DETAIL_LEVEL:
991 s2 = GetDebugNameEC_DETAIL_LEVEL(GetInt()); break;
992 case EC_TAG_SEARCH_TYPE:
993 s2 = GetDebugNameEC_SEARCH_TYPE(GetInt()); break;
994 case EC_TAG_STAT_VALUE_TYPE:
995 s2 = GetDebugNameEC_STATTREE_NODE_VALUE_TYPE(GetInt()); break;
996 default:
997 switch (m_dataType) {
998 case EC_TAGTYPE_UINT8:
999 case EC_TAGTYPE_UINT16:
1000 case EC_TAGTYPE_UINT32:
1001 case EC_TAGTYPE_UINT64:
1002 s2 = CFormat(wxT("%d")L"%d") % GetInt(); break;
1003 case EC_TAGTYPE_STRING:
1004 s2 = GetStringData(); break;
1005 case EC_TAGTYPE_DOUBLE:
1006 s2 = CFormat(wxT("%.1f")L"%.1f") % GetDoubleData(); break;
1007 case EC_TAGTYPE_HASH16:
1008 s2 = GetMD4Data().Encode(); break;
1009 case EC_TAGTYPE_UINT128:
1010 // Using any non-inline function from UInt128.h would break linkage
1011 // of remote apps otherwise not using CUInt128. So just fall through
1012 // and display the value as a byte-stream. Since the value is sent
1013 // big-endian on the network, the visual result is correct, except
1014 // for the intervening spaces...
1015 //s2 = GetInt128Data().ToHexString(); break;
1016 case EC_TAGTYPE_CUSTOM:
1017 if (m_dataLen == 0) {
1018 s2 = wxT("empty")L"empty";
1019 } else {
1020 // Make a hex dump (limited to maxOutput)
1021 const uint32 maxOutput = 50;
1022 for (uint32 i = 0; i < m_dataLen; i++) {
1023 if (i == maxOutput) {
1024 s2 += wxT("...")L"...";
1025 break;
1026 }
1027 s2 += CFormat(wxT("%02X ")L"%02X ") % (unsigned char) m_tagData[i];
1028 }
1029 }
1030 break;
1031 default:
1032 s2 = GetDebugNameECTagTypes(m_dataType);
1033 }
1034 }
1035 DoECLogLine(s1 + s2);
1036 }
1037 for (TagList::const_iterator it = m_tagList.begin(); it != m_tagList.end(); ++it) {
1038 it->DebugPrint(level + 1, true);
1039 }
1040}
1041#endif
1042
1043/*!
1044 * \fn CMD4Hash CECTag::GetMD4Data(void) const
1045 *
1046 * \brief Returns a CMD4Hash class.
1047 *
1048 * This function takes care of converting from MSB to LSB as necessary.
1049 *
1050 * \return CMD4Hash class.
1051 *
1052 * \sa CECTag(ec_tagname_t, const CMD4Hash&)
1053 */
1054
1055/*!
1056 * \fn CECTag *CECTag::GetTagByIndex(size_t index) const
1057 *
1058 * \brief Finds the indexth child tag.
1059 *
1060 * \param index 0-based index, 0 <= \e index < GetTagCount()
1061 *
1062 * \return The child tag, or NULL if index out of range.
1063 */
1064
1065/*!
1066 * \fn CECTag *CECTag::GetTagByIndexSafe(size_t index) const
1067 *
1068 * \brief Finds the indexth child tag.
1069 *
1070 * \param index 0-based index, 0 <= \e index < GetTagCount()
1071 *
1072 * \return The child tag, or a special null-valued tag if index out of range.
1073 */
1074
1075/*!
1076 * \fn size_t CECTag::GetTagCount(void) const
1077 *
1078 * \brief Returns the number of child tags.
1079 *
1080 * \return The number of child tags.
1081 */
1082
1083/*!
1084 * \fn const void *CECTag::GetTagData(void) const
1085 *
1086 * \brief Returns a pointer to the TAG DATA.
1087 *
1088 * \return A pointer to the TAG DATA. (As specified with the data field of the constructor.)
1089*/
1090
1091/*!
1092 * \fn uint16 CECTag::GetTagDataLen(void) const
1093 *
1094 * \brief Returns the length of the data buffer.
1095 *
1096 * \return The length of the data buffer.
1097 */
1098
1099/*!
1100 * \fn ec_tagname_t CECTag::GetTagName(void) const
1101 *
1102 * \brief Returns TAGNAME.
1103 *
1104 * \return The name of the tag.
1105 */
1106
1107/*!
1108 * \fn wxString CECTag::GetStringData(void) const
1109 *
1110 * \brief Returns the string data of the tag.
1111 *
1112 * Returns a wxString created from TAGDATA. It is automatically
1113 * converted from UTF-8 to the internal application encoding.
1114 * Should be used with care (only on tags created with the
1115 * CECTag(ec_tagname_t, const wxString&) constructor),
1116 * because it does not perform any check to see if the tag really contains a
1117 * string object.
1118 *
1119 * \return The string data of the tag.
1120 *
1121 * \sa CECTag(ec_tagname_t, const wxString&)
1122 */
1123
1124/*!
1125 * \fn uint8 CECTag::GetInt(void) const
1126 *
1127 * \brief Returns the uint8 data of the tag.
1128 *
1129 * This function takes care of the endianness problems with numbers.
1130 *
1131 * \return The uint8 data of the tag.
1132 *
1133 * \sa CECTag(ec_tagname_t, uint8)
1134 */
1135
1136/*!
1137 * \fn uint16 CECTag::GetInt(void) const
1138 *
1139 * \brief Returns the uint16 data of the tag.
1140 *
1141 * This function takes care of the endianness problems with numbers.
1142 *
1143 * \return The uint16 data of the tag.
1144 *
1145 * \sa CECTag(ec_tagname_t, uint16)
1146 */
1147
1148/*!
1149 * \fn uint32 CECTag::GetInt(void) const
1150 *
1151 * \brief Returns the uint32 data of the tag.
1152 *
1153 * This function takes care of the endianness problems with numbers.
1154 *
1155 * \return The uint32 data of the tag.
1156 *
1157 * \sa CECTag(ec_tagname_t, uint32)
1158 */
1159
1160/*!
1161 * \fn uint64 CECTag::GetInt(void) const
1162 *
1163 * \brief Returns the uint64 data of the tag.
1164 *
1165 * This function takes care of the endianness problems with numbers.
1166 *
1167 * \return The uint64 data of the tag.
1168 *
1169 * \sa CECTag(ec_tagname_t, uint64)
1170 */
1171
1172uint32 CECID::s_IDCounter = 0;
1173
1174// File_checked_for_headers