1 #include <muleunit/test.h>
2
3 #include <wx/filename.h>
4 #include <MemFile.h>
5 #include <tags/FileTags.h>
6 #include <math.h>
7
8 #include "MD4Hash.h"
9 #include "amule.h"
10 #include "Packet.h"
11 #include <vector>
12
13 using namespace muleunit;
14
15 DECLARE_SIMPLE(CTag)
16
17 void test_taglist_serialization(TagPtrList & taglist, byte* packet, uint64 packet_len);
18
19 template <class T1, class T2>
AssertEquals(const T1 & a,const T2 & b)20 void AssertEquals(const T1& a, const T2& b)
21 {
22 ASSERT_EQUALS(a, b);
23 }
24
25 struct BLOBValue : std::vector<byte>
26 {
BLOBValueBLOBValue27 BLOBValue(uint32 _length, const byte* _ptr)
28 : std::vector<byte > (_ptr, _ptr + _length)
29 {}
30 };
31
32 struct BSOBValue : std::vector<byte>
33 {
BSOBValueBSOBValue34 BSOBValue(uint8 _length, const byte* _ptr)
35 : std::vector<byte > (_ptr, _ptr + _length)
36 {}
37 };
38
valid_tag_value(const BLOBValue & x)39 BLOBValue valid_tag_value(const BLOBValue& x) { return x; }
valid_tag_value(const BSOBValue & x)40 BSOBValue valid_tag_value(const BSOBValue& x) { return x; }
valid_tag_value(const CMD4Hash & x)41 CMD4Hash valid_tag_value(const CMD4Hash& x) { return x; }
valid_tag_value(float x)42 float valid_tag_value(float x) { return x; }
valid_tag_value(const wxString & x)43 wxString valid_tag_value(const wxString& x) { return x; }
valid_tag_value(int x)44 uint64 valid_tag_value(int x) { return x; }
valid_tag_value(long long x)45 uint64 valid_tag_value(long long x) { return x; }
valid_tag_value(uint64 x)46 uint64 valid_tag_value(uint64 x) { return x; }
47
48 template<class T>
toString(const T & value)49 wxString toString(const T& value)
50 {
51 wxString buf;
52
53 return buf << value;
54 }
55
56 template<class T>
toString(T & value)57 wxString toString(T& value)
58 {
59 wxString buf;
60
61 return buf << value;
62 }
63
64 template<>
toString(const CMD4Hash & value)65 wxString toString(const CMD4Hash& value)
66 {
67 return value.Encode();
68 }
69
70 template<>
toString(CMemFile & buf)71 wxString toString(CMemFile& buf)
72 {
73 uint64 curpos = buf.GetPosition();
74 wxString result;
75 buf.Seek(0, wxFromStart);
76 for (uint64 i = 0; i < buf.GetLength(); i++) {
77 result += wxString::Format(wxT("0x%02x,"), buf.ReadUInt8());
78 }
79 buf.Seek(curpos, wxFromStart);
80
81 return result;
82 }
83
84 template<>
toString(const BSOBValue & buf)85 wxString toString(const BSOBValue& buf)
86 {
87 wxString result;
88 for (uint64 i = 0; i < buf.size(); i++) {
89 result += wxString::Format(wxT("0x%02x,"), buf[i]);
90 }
91 return result;
92 }
93
94 template<>
toString(const BLOBValue & buf)95 wxString toString(const BLOBValue& buf)
96 {
97 wxString result;
98 for (uint64 i = 0; i < buf.size(); i++) {
99 result += wxString::Format(wxT("0x%02x,"), buf[i]);
100 }
101 return result;
102 }
103
104 template<>
AssertEquals(const CMD4Hash & a,const CMD4Hash & b)105 void AssertEquals(const CMD4Hash& a, const CMD4Hash& b)
106 {
107 CONTEXT(wxT("Compare CMD4Hashes"));
108 ASSERT_EQUALS(a.Encode(), b.Encode());
109 }
110
111 template<>
AssertEquals(const BSOBValue & a,const BSOBValue & b)112 void AssertEquals(const BSOBValue& a, const BSOBValue& b)
113 {
114 CONTEXT(wxT("Compare BSOBValue"));
115 ASSERT_EQUALS(toString(a), toString(b));
116 }
117
118 template<>
AssertEquals(const BLOBValue & a,const BLOBValue & b)119 void AssertEquals(const BLOBValue& a, const BLOBValue& b)
120 {
121 CONTEXT(wxT("Compare BLOBValue"));
122 ASSERT_EQUALS(toString(a), toString(b));
123 }
124
CheckTagName(const wxString & tagName,CTag * tag)125 void CheckTagName(const wxString& tagName, CTag* tag)
126 {
127 CONTEXT(wxT("Checking string tagname"));
128 ASSERT_EQUALS(tagName, tag->GetName());
129 }
130
CheckTagName(uint8 tagName,CTag * tag)131 void CheckTagName(uint8 tagName, CTag* tag)
132 {
133 CONTEXT(wxT("Checking int tagname"));
134 ASSERT_EQUALS(tagName, tag->GetNameID());
135 }
136
137
138 typedef bool (CTag::*CTagTypeChecker)() const;
139
140 template<class T>
141 struct CTagAccess {};
142
143 template<>
144 struct CTagAccess<wxString>
145 {
IsRightTypeCTagAccess146 static bool IsRightType(CTag* tag)
147 {
148 return tag->IsStr();
149 }
150
GetValueCTagAccess151 static const wxString & GetValue(CTag* tag)
152 {
153 return tag->GetStr();
154 }
155 };
156
157 template<>
158 struct CTagAccess<CMD4Hash>
159 {
IsRightTypeCTagAccess160 static bool IsRightType(CTag* tag)
161 {
162 return tag->IsHash();
163 }
164
GetValueCTagAccess165 static const CMD4Hash & GetValue(CTag* tag)
166 {
167 return tag->GetHash();
168 }
169 };
170
171 template<>
172 struct CTagAccess<float>
173 {
IsRightTypeCTagAccess174 static bool IsRightType(CTag* tag)
175 {
176 return tag->IsFloat();
177 }
178
GetValueCTagAccess179 static float GetValue(CTag* tag)
180 {
181 return tag->GetFloat();
182 }
183 };
184
185 template<>
186 struct CTagAccess<uint64>
187 {
IsRightTypeCTagAccess188 static bool IsRightType(CTag* tag)
189 {
190 return tag->IsInt();
191 }
192
GetValueCTagAccess193 static uint64 GetValue(CTag* tag)
194 {
195 return tag->GetInt();
196 }
197 };
198
199 template<>
200 struct CTagAccess<BLOBValue>
201 {
IsRightTypeCTagAccess202 static bool IsRightType(CTag* tag)
203 {
204 return tag->IsBlob();
205 }
206
GetValueCTagAccess207 static BLOBValue GetValue(CTag* tag)
208 {
209 return BLOBValue(tag->GetBlobSize(), tag->GetBlob());
210 }
211 };
212
213 template<>
214 struct CTagAccess<BSOBValue>
215 {
IsRightTypeCTagAccess216 static bool IsRightType(CTag* tag)
217 {
218 return tag->IsBsob();
219 }
220
GetValueCTagAccess221 static BSOBValue GetValue(CTag* tag) {
222 return BSOBValue(tag->GetBsobSize(), tag->GetBsob());
223 }
224 };
225
226 template<class V>
CheckTagValue(V tagValue,CTag * tag)227 void CheckTagValue(V tagValue, CTag* tag)
228 {
229 CONTEXT(wxT("Check tag value"));
230
231 AssertEquals(tagValue, CTagAccess< V >::GetValue(tag));
232 }
233
234 template<class V>
CheckTagType(V,CTag * tag)235 void CheckTagType(V, CTag* tag)
236 {
237 CONTEXT(wxT("Check tag type"));
238 ASSERT_EQUALS(true, CTagAccess<V>::IsRightType(tag));
239 }
240
241 template<class V, class TName>
CheckTagData(CTag * tag,TName tagName,const V & tagValue)242 void CheckTagData(CTag* tag, TName tagName, const V& tagValue)
243 {
244 CONTEXT(wxT("Expected tag value:") + toString(tagValue));
245 CONTEXT(wxT("Parsed tag info:") + tag->GetFullInfo());
246
247 CheckTagType(tagValue, tag);
248 CheckTagName(tagName, tag);
249 CheckTagValue(valid_tag_value(tagValue), tag);
250 }
251
test_taglist_serialization(TagPtrList & taglist,byte * packet,uint64 packet_len)252 void test_taglist_serialization(TagPtrList& taglist, byte* packet, uint64 packet_len)
253 {
254 CMemFile fout;
255
256 {
257 CONTEXT(wxT("Writing taglist to CMemFile"));
258
259 fout.WriteTagPtrList(taglist);
260 }
261
262 // Rewind file
263 fout.Seek(0, wxFromStart);
264
265 {
266 CONTEXT(wxT("Check taglist serialization length"));
267 ASSERT_EQUALS(packet_len, fout.GetLength());
268 }
269
270 std::vector<byte> buf(packet_len);
271
272 {
273 CONTEXT(wxT("Reading back serialized taglist bytes from CMemFile"));
274 fout.Read(&buf[0], packet_len);
275 }
276
277 for (uint64 i = 0; i < packet_len; i++) {
278 CONTEXT(wxString::Format(wxT("Comparing serialized byte #%") wxLongLongFmtSpec wxT("u"), i));
279
280 ASSERT_EQUALS(packet[i], buf[i]);
281 }
282 }
283
ReadTagPtrList(TagPtrList & taglist,byte * packet,uint64 packet_len)284 void ReadTagPtrList(TagPtrList& taglist, byte* packet, uint64 packet_len)
285 {
286
287 CONTEXT(wxT("Reading taglist from buffer"));
288 CMemFile fin(packet, packet_len);
289 fin.ReadTagPtrList(&taglist, true);
290
291 {
292 CONTEXT(wxT("Verify position is at end of packet"));
293 ASSERT_EQUALS(packet_len, fin.GetPosition());
294 }
295 }
296
297 TEST_M(CTag, ReadTagList1, wxT("Kad: Parse taglist from Kad packet with UTF8 string #1"))
298 {
299 byte packet[] = {
300 0x07,
301 /*Tag1*/ 0x02, 0x01, 0x00, 0x01, 0x22, 0x00, 0x47, 0x65, 0x6d, 0x20, 0x42, 0x6f, 0x79, 0x20, 0x2d,
302 0x20, 0x53, 0x61, 0x72, 0xc3, 0xa0, 0x20, 0x70, 0x65, 0x72, 0x63, 0x68, 0xc3, 0xa8, 0x20, 0x74,
303 0x69, 0x20, 0x61, 0x6d, 0x6f, 0x2e, 0x6d, 0x70, 0x33,
304 /*Tag2*/ 0x03, 0x01, 0x00, 0x02, 0x1d, 0x6f, 0x1f, 0x00,
305 /*Tag3*/ 0x09, 0x01, 0x00, 0x15, 0x01,
306 /*Tag4*/ 0x02, 0x01, 0x00, 0x03, 0x05, 0x00, 0x41, 0x75, 0x64, 0x69, 0x6f,
307 /*Tag5*/ 0x09, 0x01, 0x00, 0xd3, 0x6b,
308 /*Tag6*/ 0x09, 0x01, 0x00, 0xd4, 0x9a,
309 /*Tag7*/ 0x03, 0x01, 0x00, 0x33, 0x2f, 0x00, 0x01, 0x01
310 };
311
312 TagPtrList taglist;
313 ReadTagPtrList(taglist, packet, sizeof (packet));
314 TagPtrList::iterator it = taglist.begin();
315
316 CheckTagData(*it++, TAG_FILENAME, valid_tag_value(wxT("Gem Boy - Sarà perchè ti amo.mp3")));
317 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(2060061));
318 CheckTagData(*it++, TAG_SOURCES, valid_tag_value(1));
319 CheckTagData(*it++, TAG_FILETYPE, valid_tag_value(ED2KFTSTR_AUDIO));
320 CheckTagData(*it++, TAG_MEDIA_LENGTH, valid_tag_value(107));
321 CheckTagData(*it++, TAG_MEDIA_BITRATE, valid_tag_value(154));
322 CheckTagData(*it++, TAG_PUBLISHINFO, valid_tag_value(16842799));
323
324 ASSERT_TRUE(it == taglist.end());
325 test_taglist_serialization(taglist, packet, sizeof (packet));
326 deleteTagPtrListEntries(&taglist);
327 }
328
329 TEST_M(CTag, ReadTagList2, wxT("Kad: Parse taglist from Kad packet with UTF8 string #2"))
330 {
331 byte packet[] = {
332 0x05,
333 /*Tag1*/0x02, 0x01, 0x00, 0x01, 0x33, 0x00, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61,
334 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x31,
335 0x38, 0x39, 0x33, 0x2d, 0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac, 0xc3, 0xa8, 0xc3, 0xa9, 0xc3, 0xa7,
336 0xc3, 0xa0, 0xc3, 0xb9, 0xc2, 0xa7, 0x2e, 0x74, 0x78, 0x74,
337 /*Tag2*/0x09, 0x01, 0x00, 0x02, 0x0d,
338 /*Tag3*/0x09, 0x01, 0x00, 0x15, 0x00,
339 /*Tag4*/0x02, 0x01, 0x00, 0x03, 0x03, 0x00, 0x44, 0x6f, 0x63, 0x03, 0x01, 0x00,
340 0x33, 0xe8, 0x03, 0x01, 0x01
341 };
342
343 TagPtrList taglist;
344 ReadTagPtrList(taglist, packet, sizeof (packet));
345 TagPtrList::iterator it = taglist.begin();
346
347 CheckTagData(*it++, TAG_FILENAME, valid_tag_value(wxT("Serialization Test File 1893-€€èéçàù§.txt")));
348 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(13));
349 CheckTagData(*it++, TAG_SOURCES, valid_tag_value(0));
350 CheckTagData(*it++, TAG_FILETYPE, valid_tag_value(ED2KFTSTR_DOCUMENT));
351 CheckTagData(*it++, TAG_PUBLISHINFO, valid_tag_value(16843752));
352
353 ASSERT_TRUE(it == taglist.end());
354 test_taglist_serialization(taglist, packet, sizeof (packet));
355 deleteTagPtrListEntries(&taglist);
356
357 }
358
359 TEST_M(CTag, Float, wxT("Kad: Read/Write floats"))
360 {
361 byte packet[] = {
362 0x02,
363 /*Tag1*/0x04, 0x01, 0x00, 0xFF, 0x79, 0xe9, 0xf6, 0x42,
364 /*Tag2*/0x04, 0x01, 0x00, 0xFF, 0x79, 0xd9, 0xd6, 0x42,
365 };
366
367 TagPtrList taglist;
368 ReadTagPtrList(taglist, packet, sizeof (packet));
369 TagPtrList::iterator it = taglist.begin();
370
371 CheckTagData(*it++, TAG_SOURCETYPE, valid_tag_value((float) 123.456));
372 CheckTagData(*it++, TAG_SOURCETYPE, valid_tag_value((float) 107.424751));
373
374 ASSERT_TRUE(it == taglist.end());
375 test_taglist_serialization(taglist, packet, sizeof (packet));
376 deleteTagPtrListEntries(&taglist);
377 }
378
379 TEST_M(CTag, CMD4Hash, wxT("Kad: Read/Write CMD4Hash"))
380 {
381 byte packet[] = {
382 0x01,
383 /*Tag1*/0x01,
384 0x01, 0x00, 0xFF,
385 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
386 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
387 };
388
389 TagPtrList taglist;
390 ReadTagPtrList(taglist, packet, sizeof (packet));
391 TagPtrList::iterator it = taglist.begin();
392
393 CMD4Hash hash;
394 ASSERT_TRUE(hash.Decode(std::string("000102030405060708090A0B0C0D0E0F")));
395
396 CheckTagData(*it++, TAG_SOURCETYPE, valid_tag_value(hash));
397
398 ASSERT_TRUE(it == taglist.end());
399 test_taglist_serialization(taglist, packet, sizeof (packet));
400 deleteTagPtrListEntries(&taglist);
401 }
402
403 template<class T, class V>
check_single_kad_tag(byte * packet,size_t packet_len,T tagName,V tagValue)404 void check_single_kad_tag(byte* packet, size_t packet_len, T tagName, V tagValue)
405 {
406 CMemFile buf(packet, packet_len);
407 CONTEXT(wxT("Starting buffer: ") + toString(buf));
408 CTag* tag = buf.ReadTag(true);
409
410 CheckTagData(tag, tagName, valid_tag_value(tagValue));
411 {
412 CONTEXT(wxT("Check end of buffer"));
413 ASSERT_EQUALS(packet_len, buf.GetPosition());
414 }
415
416 {
417 CMemFile newbuf;
418 newbuf.WriteTag(*tag);
419
420 CONTEXT(wxT("Serialized : ") + toString(newbuf));
421
422 newbuf.Seek(0, wxFromStart);
423 for (size_t i = 0; i < packet_len; i++) {
424 CONTEXT(wxString::Format(wxT("Comparing byte #%d"), static_cast<int>(i)));
425
426 ASSERT_EQUALS(packet[i], newbuf.ReadUInt8());
427 }
428
429 ASSERT_EQUALS(packet_len, buf.GetPosition());
430 }
431 delete tag;
432 }
433
434 TEST_M(CTag, KadBsob, wxT("Kad: Read/Write BSOB"))
435 {
436 byte packet[] = {
437 /*Tag1*/ 0x0A, 0x01, 0x00, 0x02, 0x04, 0x01, 0x02, 0x03, 0x04,
438 };
439 byte raw_data[] = {0x01, 0x02, 0x03, 0x04};
440 {
441 CONTEXT(wxT("Create BSOBValue"));
442 BSOBValue bsob(sizeof (raw_data), raw_data);
443
444 CONTEXT(wxT("check_single_kad_tag BSOBValue"));
445 check_single_kad_tag(packet, sizeof (packet), TAG_FILESIZE, bsob);
446 }
447 }
448
449 TEST_M(CTag, KadInt64, wxT("Kad: Read/Write integer 64bit"))
450 {
451 byte packet[] = {
452 /*Tag1*/ 0x0b, 0x01, 0x00, 0x02, 0x10, 0x11, 0x12, 0x13, 0x20, 0x21, 0x22, 0x23, // 64 bit int
453 };
454 check_single_kad_tag(packet, sizeof (packet), TAG_FILESIZE, 0x2322212013121110LL);
455 }
456
457 TEST_M(CTag, KadInt32, wxT("Kad: Read/Write integer 32bit"))
458 {
459 byte packet[] = {
460 /*Tag1*/ 0x03, 0x01, 0x00, 0x02, 0x12, 0x34, 0x56, 0x78, // 32 bit int
461 };
462 check_single_kad_tag(packet, sizeof (packet), TAG_FILESIZE, 0x78563412);
463 }
464
465 TEST_M(CTag, KadInt16, wxT("Kad: Read/Write integer 16bit"))
466 {
467 byte packet[] = {
468 /*Tag1*/ 0x08, 0x01, 0x00, 0x02, 0x12, 0x34, // 16 bit int
469 };
470 check_single_kad_tag(packet, sizeof (packet), TAG_FILESIZE, 0x3412);
471 }
472
473 TEST_M(CTag, KadInt8, wxT("Kad: Read/Write integer 8bit"))
474 {
475 byte packet[] = {
476 /*Tag1*/ 0x09, 0x01, 0x00, 0x02, 0x12, // 8 bit int
477 };
478 check_single_kad_tag(packet, sizeof (packet), TAG_FILESIZE, 0x12);
479 }
480
481 TEST_M(CTag, ReadIntegers, wxT("Kad: Read/Write multiple integers"))
482 {
483 byte packet[] = {
484 0x08,
485 /*Tag1*/ 0x03, 0x01, 0x00, 0x02, 0x12, 0x34, 0x56, 0x78, // 32 bit int
486 /*Tag2*/ 0x08, 0x01, 0x00, 0x02, 0x12, 0x34, // 16 bit int
487 /*Tag3*/ 0x09, 0x01, 0x00, 0x02, 0x12, // 8 bit int
488 /*Tag4*/ 0x0b, 0x01, 0x00, 0x02, 0x10, 0x11, 0x12, 0x13, 0x20, 0x21, 0x22, 0x23, // 64 bit int
489
490 /*Tag5*/ 0x03, 0x01, 0x00, 0x02, 0x12, 0x34, 0x56, 0x78, // 32 bit int
491 /*Tag6*/ 0x08, 0x01, 0x00, 0x02, 0x12, 0x34, // 16 bit int
492 /*Tag7*/ 0x09, 0x01, 0x00, 0x02, 0x12, // 8 bit int
493 /*Tag8*/ 0x0b, 0x01, 0x00, 0x02, 0x10, 0x11, 0x12, 0x13, 0x20, 0x21, 0x22, 0x23, // 64 bit int
494 };
495
496 TagPtrList taglist;
497 ReadTagPtrList(taglist, packet, sizeof (packet));
498 TagPtrList::iterator it = taglist.begin();
499
500 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x78563412));
501 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x3412));
502 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x12));
503 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x2322212013121110LL));
504
505 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x78563412));
506 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x3412));
507 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x12));
508 CheckTagData(*it++, TAG_FILESIZE, valid_tag_value(0x2322212013121110LL));
509
510 ASSERT_TRUE(it == taglist.end());
511 test_taglist_serialization(taglist, packet, sizeof (packet));
512 deleteTagPtrListEntries(&taglist);
513 }
514
515
516 #include <map>
517
518 typedef std::map<wxString, wxString> TagNamesByString;
519
520 TEST_M(CTag, KadTagNames, wxT("Kad: Test Kad tags (name=string) - write/read every valid tag name"))
521 {
522 TagNamesByString tagNames;
523
524 tagNames[TAG_FILENAME] = wxT("TAG_FILENAME");
525 tagNames[TAG_FILESIZE] = wxT("TAG_FILESIZE");
526 tagNames[TAG_FILESIZE_HI] = wxT("TAG_FILESIZE_HI");
527 tagNames[TAG_FILETYPE] = wxT("TAG_FILETYPE");
528 tagNames[TAG_FILEFORMAT] = wxT("TAG_FILEFORMAT");
529 tagNames[TAG_COLLECTION] = wxT("TAG_COLLECTION");
530 tagNames[TAG_PART_PATH] = wxT("TAG_PART_PATH");
531 tagNames[TAG_PART_HASH] = wxT("TAG_PART_HASH");
532 tagNames[TAG_COPIED] = wxT("TAG_COPIED");
533 tagNames[TAG_GAP_START] = wxT("TAG_GAP_START");
534 tagNames[TAG_GAP_END] = wxT("TAG_GAP_END");
535 tagNames[TAG_DESCRIPTION] = wxT("TAG_DESCRIPTION");
536 tagNames[TAG_PING] = wxT("TAG_PING");
537 tagNames[TAG_FAIL] = wxT("TAG_FAIL");
538 tagNames[TAG_PREFERENCE] = wxT("TAG_PREFERENCE");
539 tagNames[TAG_PORT] = wxT("TAG_PORT");
540 tagNames[TAG_IP_ADDRESS] = wxT("TAG_IP_ADDRESS");
541 tagNames[TAG_VERSION] = wxT("TAG_VERSION");
542 tagNames[TAG_TEMPFILE] = wxT("TAG_TEMPFILE");
543 tagNames[TAG_PRIORITY] = wxT("TAG_PRIORITY");
544 tagNames[TAG_STATUS] = wxT("TAG_STATUS");
545 tagNames[TAG_SOURCES] = wxT("TAG_SOURCES");
546 tagNames[TAG_AVAILABILITY] = wxT("TAG_AVAILABILITY");
547 tagNames[TAG_PERMISSIONS] = wxT("TAG_PERMISSIONS");
548 tagNames[TAG_QTIME] = wxT("TAG_QTIME");
549 tagNames[TAG_PARTS] = wxT("TAG_PARTS");
550 tagNames[TAG_PUBLISHINFO] = wxT("TAG_PUBLISHINFO");
551 tagNames[TAG_MEDIA_ARTIST] = wxT("TAG_MEDIA_ARTIST");
552 tagNames[TAG_MEDIA_ALBUM] = wxT("TAG_MEDIA_ALBUM");
553 tagNames[TAG_MEDIA_TITLE] = wxT("TAG_MEDIA_TITLE");
554 tagNames[TAG_MEDIA_LENGTH] = wxT("TAG_MEDIA_LENGTH");
555 tagNames[TAG_MEDIA_BITRATE] = wxT("TAG_MEDIA_BITRATE");
556 tagNames[TAG_MEDIA_CODEC] = wxT("TAG_MEDIA_CODEC");
557 tagNames[TAG_KADMISCOPTIONS] = wxT("TAG_KADMISCOPTIONS");
558 tagNames[TAG_ENCRYPTION] = wxT("TAG_ENCRYPTION");
559 tagNames[TAG_FILERATING] = wxT("TAG_FILERATING");
560 tagNames[TAG_BUDDYHASH] = wxT("TAG_BUDDYHASH");
561 tagNames[TAG_CLIENTLOWID] = wxT("TAG_CLIENTLOWID");
562 tagNames[TAG_SERVERPORT] = wxT("TAG_SERVERPORT");
563 tagNames[TAG_SERVERIP] = wxT("TAG_SERVERIP");
564 tagNames[TAG_SOURCEUPORT] = wxT("TAG_SOURCEUPORT");
565 tagNames[TAG_SOURCEPORT] = wxT("TAG_SOURCEPORT");
566 tagNames[TAG_SOURCEIP] = wxT("TAG_SOURCEIP");
567 tagNames[TAG_SOURCETYPE] = wxT("TAG_SOURCETYPE");
568
569 CMemFile buf;
570 buf.WriteUInt8(tagNames.size());
571 int counter = 0;
572 // For each tagNames entry write an 8bit int tag (type:0x9)
573 for (TagNamesByString::iterator it_name = tagNames.begin(); it_name != tagNames.end(); ++it_name) {
574 buf.WriteUInt8(0x09); // 8 bit int tag type
575
576 buf.WriteUInt8(0x01); // single char string
577 buf.WriteUInt8(0x00); //
578
579 #if wxCHECK_VERSION(3, 1, 0)
580 wxCharBuffer b = wxConvISO8859_1.cWC2MB(it_name->first.c_str());
581 #else
582 wxCharBuffer b = wxConvISO8859_1.cWC2MB(it_name->first);
583 #endif
584
585 buf.WriteUInt8(((const char *)b)[0]); // Write string first char
586 buf.WriteUInt8(counter++); // write tag value
587 }
588
589 TagPtrList taglist;
590 buf.Seek(0, wxFromStart);
591 size_t packet_len = buf.GetLength();
592 std::vector<byte> packet(packet_len);
593 buf.Read(&packet[0], packet_len);
594
595 ReadTagPtrList(taglist, &packet[0], packet_len);
596
597 TagPtrList::iterator it = taglist.begin();
598
599 counter = 0;
600 for (TagNamesByString::iterator it_name = tagNames.begin(); it_name != tagNames.end(); ++it_name) {
601 CONTEXT(wxT("Testing tag name: ") + it_name->second);
602 CheckTagData(*it++, it_name->first, valid_tag_value(counter++));
603 }
604
605 ASSERT_TRUE(it == taglist.end());
606 test_taglist_serialization(taglist, &packet[0], packet_len);
607 deleteTagPtrListEntries(&taglist);
608 }
609
610 typedef std::map<int, wxString> TagNamesByInt;
611
612 TEST_M(CTag, ED2kTagNames, wxT("Ed2k: Test ed2k tags (name=id) - write/read every valid tag name"))
613 {
614 TagNamesByInt tagNames;
615
616 tagNames[FT_FILENAME] = wxT("FT_FILENAME");
617 tagNames[FT_FILESIZE] = wxT("FT_FILESIZE");
618 tagNames[FT_FILESIZE_HI] = wxT("FT_FILESIZE_HI");
619 tagNames[FT_FILETYPE] = wxT("FT_FILETYPE");
620 tagNames[FT_FILEFORMAT] = wxT("FT_FILEFORMAT");
621 tagNames[FT_LASTSEENCOMPLETE] = wxT("FT_LASTSEENCOMPLETE");
622 tagNames[FT_TRANSFERRED] = wxT("FT_TRANSFERRED");
623 tagNames[FT_GAPSTART] = wxT("FT_GAPSTART");
624 tagNames[FT_GAPEND] = wxT("FT_GAPEND");
625 tagNames[FT_PARTFILENAME] = wxT("FT_PARTFILENAME");
626 tagNames[FT_OLDDLPRIORITY] = wxT("FT_OLDDLPRIORITY");
627 tagNames[FT_STATUS] = wxT("FT_STATUS");
628 tagNames[FT_SOURCES] = wxT("FT_SOURCES");
629 tagNames[FT_PERMISSIONS] = wxT("FT_PERMISSIONS");
630 tagNames[FT_OLDULPRIORITY] = wxT("FT_OLDULPRIORITY");
631 tagNames[FT_DLPRIORITY] = wxT("FT_DLPRIORITY");
632 tagNames[FT_ULPRIORITY] = wxT("FT_ULPRIORITY");
633 tagNames[FT_KADLASTPUBLISHKEY] = wxT("FT_KADLASTPUBLISHKEY");
634 tagNames[FT_KADLASTPUBLISHSRC] = wxT("FT_KADLASTPUBLISHSRC");
635 tagNames[FT_FLAGS] = wxT("FT_FLAGS");
636 tagNames[FT_DL_ACTIVE_TIME] = wxT("FT_DL_ACTIVE_TIME");
637 tagNames[FT_CORRUPTEDPARTS] = wxT("FT_CORRUPTEDPARTS");
638 tagNames[FT_DL_PREVIEW] = wxT("FT_DL_PREVIEW");
639 tagNames[FT_KADLASTPUBLISHNOTES] = wxT("FT_KADLASTPUBLISHNOTES");
640 tagNames[FT_AICH_HASH] = wxT("FT_AICH_HASH");
641 tagNames[FT_COMPLETE_SOURCES] = wxT("FT_COMPLETE_SOURCES");
642 tagNames[FT_PUBLISHINFO] = wxT("FT_PUBLISHINFO");
643 tagNames[FT_ATTRANSFERRED] = wxT("FT_ATTRANSFERRED");
644 tagNames[FT_ATREQUESTED] = wxT("FT_ATREQUESTED");
645 tagNames[FT_ATACCEPTED] = wxT("FT_ATACCEPTED");
646 tagNames[FT_CATEGORY] = wxT("FT_CATEGORY");
647 tagNames[FT_ATTRANSFERREDHI] = wxT("FT_ATTRANSFERREDHI");
648 tagNames[FT_MEDIA_ARTIST] = wxT("FT_MEDIA_ARTIST");
649 tagNames[FT_MEDIA_ALBUM] = wxT("FT_MEDIA_ALBUM");
650 tagNames[FT_MEDIA_TITLE] = wxT("FT_MEDIA_TITLE");
651 tagNames[FT_MEDIA_LENGTH] = wxT("FT_MEDIA_LENGTH");
652 tagNames[FT_MEDIA_BITRATE] = wxT("FT_MEDIA_BITRATE");
653 tagNames[FT_MEDIA_CODEC] = wxT("FT_MEDIA_CODEC");
654 tagNames[FT_FILERATING] = wxT("FT_FILERATING");
655
656
657 CMemFile buf;
658
659 uint64 counter = 0;
660 for (TagNamesByInt::iterator it_name = tagNames.begin(); it_name != tagNames.end(); ++it_name) {
661 // m_uType
662 buf.WriteUInt8(0x09 + 0x80);
663 // m_uName
664 buf.WriteUInt8(it_name->first);
665 // 8 bit
666 buf.WriteUInt8(counter++);
667 }
668
669 buf.Seek(0, wxFromStart);
670
671 counter = 0;
672 for (TagNamesByInt::iterator it_name = tagNames.begin(); it_name != tagNames.end(); ++it_name) {
673 CONTEXT(wxString::Format(wxT("Reading tag#%") wxLongLongFmtSpec wxT("u"), counter));
674 CTag* newtag = new CTag(buf, true);
675 CheckTagName(it_name->first, newtag);
676 CheckTagValue( valid_tag_value( counter ), newtag);
677 delete newtag;
678 counter++;
679 }
680 }
681
682 TEST_M(CTag, Ed2kBlob1, wxT("Ed2k: Read/Write BLOB - numeric tagname"))
683 {
684 byte packet[] = {
685 /*Tag1*/ 0x87, 0xFF, 0x04, 0x00, 0x00, 0x00,
686 0x01, 0x02, 0x03, 0x04,
687 };
688
689 CMemFile buf(packet, sizeof (packet));
690 buf.Seek(0, wxFromStart);
691 byte raw_data[] = {0x01, 0x02, 0x03, 0x04};
692 {
693 CONTEXT(wxT("Create BLOBValue"));
694 BLOBValue blob(sizeof (raw_data), raw_data);
695
696 CTag tag(buf, true);
697 CheckTagName(0xFF, &tag);
698 CheckTagValue( valid_tag_value( blob ), &tag);
699 }
700 }
701
702 TEST_M(CTag, Ed2kBlob2, wxT("Ed2k: Read/Write BLOB - string tagname"))
703 {
704 byte packet[] = {
705 /*Tag1*/ 0x07, 0x02, 0x00, 'A', 'A', 0x04, 0x00, 0x00, 0x00,
706 0x01, 0x02, 0x03, 0x04,
707 };
708
709 CMemFile buf(packet, sizeof (packet));
710 buf.Seek(0, wxFromStart);
711 byte raw_data[] = {0x01, 0x02, 0x03, 0x04};
712 {
713 CONTEXT(wxT("Create BLOBValue"));
714 BLOBValue blob(sizeof (raw_data), raw_data);
715
716 CTag tag(buf, true);
717 CheckTagName(wxT("AA"), &tag);
718 CheckTagValue( valid_tag_value( blob ), &tag);
719 }
720 }
721