1 /*
2
3 Copyright (c) 2002-2008, Yauheni Akhotnikau
4 Copyright (c) 2008-2013, The SObjectizer Project
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 - Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright notice, this
14 list of conditions and the following disclaimer in the documentation and/or
15 other materials provided with the distribution.
16
17 - The name of the author may not be used to endorse or promote products derived
18 from this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29 OF SUCH DAMAGE.
30
31 */
32
33 #include <iostream>
34
35 #include <string>
36 #include <stdexcept>
37
38 #include <vector>
39 #include <list>
40 #include <deque>
41 #include <set>
42 #include <map>
43 #include <string>
44
45 #include <algorithm>
46
47 #include <cpp_util_2/h/lexcast.hpp>
48 #include <cpp_util_2/hex_dumps/h/string_dumper.hpp>
49
50 #include <oess_2/io/h/bstring_buf.hpp>
51 #include <oess_2/io/h/fixed_mem_buf.hpp>
52
53 #include <oess_2/stdsn/h/inout_templ.hpp>
54 #include <oess_2/stdsn/h/ent_no_markers.hpp>
55
56 #include <utest_helper_1/h/helper.hpp>
57
58 #include <test/h/binary_str_proxy.hpp>
59
60 class dumpable_t
61 {
62 public :
63 virtual std::ostream &
64 dump( std::ostream & to ) const = 0;
65 };
66
67 inline std::ostream &
operator <<(std::ostream & to,const dumpable_t & what)68 operator<<( std::ostream & to, const dumpable_t & what )
69 {
70 return what.dump(to);
71 }
72
73 template< class A >
74 void
print_value(std::ostream & to,const A & a)75 print_value( std::ostream & to, const A & a )
76 {
77 to << a << " ";
78 }
79
80 template<>
81 void
print_value(std::ostream & to,const std::string & a)82 print_value( std::ostream & to, const std::string & a )
83 {
84 to << "'" << a << "' ";
85 }
86
87 template< class K, class V >
88 void
print_value(std::ostream & to,const std::pair<K,V> & a)89 print_value( std::ostream & to, const std::pair<K, V> & a )
90 {
91 to << "(" << a.first << ":" << a.second << ") ";
92 }
93
94 template< class C >
95 std::ostream &
show_content(const C & what,std::ostream & to)96 show_content( const C & what, std::ostream & to )
97 {
98 to << "{ ";
99
100 std::for_each( what.begin(), what.end(),
101 [&to]( decltype(*what.begin()) & a ) {
102 print_value( to, a );
103 } );
104
105 to << "}";
106
107 return to;
108 }
109
110 //
111 // vector_type_t
112 //
113 class vector_type_t :
114 public oess_2::stdsn::serializable_t,
115 public dumpable_t
116 {
117 OESS_SERIALIZER( vector_type_t )
118 public:
vector_type_t()119 vector_type_t() {}
120
121 virtual std::ostream &
dump(std::ostream & to) const122 dump( std::ostream & to ) const
123 {
124 return show_content(m_vector, to);
125 }
126
127 void
fill_in()128 fill_in()
129 {
130 for(int i = 0 ; i < 5 ; ++i)
131 m_vector.push_back(i);
132 }
133
134 private:
135 std::vector< oess_2::long_t > m_vector;
136 };
137
138 //
139 // small_vector_type_t
140 //
141 class small_vector_type_t:
142 public oess_2::stdsn::serializable_t,
143 public dumpable_t
144 {
145 OESS_SERIALIZER( small_vector_type_t )
146 public:
small_vector_type_t()147 small_vector_type_t() {}
148
149 virtual std::ostream &
dump(std::ostream & to) const150 dump( std::ostream & to ) const
151 {
152 return show_content(m_vector, to);
153 }
154
155 void
fill_in()156 fill_in()
157 {
158 for(int i = 0 ; i < 5 ; ++i)
159 m_vector.push_back(5-i);
160 }
161
162 private:
163 std::vector< oess_2::ulong_t > m_vector;
164 };
165
166 //
167 // list_type_t
168 //
169 class list_type_t:
170 public oess_2::stdsn::serializable_t,
171 public dumpable_t
172 {
173 OESS_SERIALIZER( list_type_t )
174 public:
list_type_t()175 list_type_t() {}
176
177 virtual std::ostream &
dump(std::ostream & to) const178 dump( std::ostream & to ) const
179 {
180 return show_content( m_list, to );
181 }
182
183 void
fill_in()184 fill_in()
185 {
186 m_list.push_back("one");
187 m_list.push_back("two");
188 m_list.push_back("three");
189 m_list.push_back("four");
190 m_list.push_back("five");
191 }
192
193 private:
194 std::list< std::string > m_list;
195 };
196
197 //
198 // small_list_type_t
199 //
200 class small_list_type_t:
201 public oess_2::stdsn::serializable_t,
202 public dumpable_t
203 {
204 OESS_SERIALIZER( small_list_type_t )
205 public:
small_list_type_t()206 small_list_type_t() {}
207
208 virtual std::ostream &
dump(std::ostream & to) const209 dump( std::ostream & to ) const
210 {
211 return show_content( m_list, to );
212 }
213
214 void
fill_in()215 fill_in()
216 {
217 m_list.push_back("I");
218 m_list.push_back("II");
219 m_list.push_back("III");
220 m_list.push_back("IV");
221 m_list.push_back("V");
222 }
223
224 private:
225 std::list< std::string > m_list;
226 };
227
228 //
229 // deque_type_t
230 //
231 class deque_type_t:
232 public oess_2::stdsn::serializable_t,
233 public dumpable_t
234 {
235 OESS_SERIALIZER( deque_type_t )
236 public:
deque_type_t()237 deque_type_t() {}
238
239 virtual std::ostream &
dump(std::ostream & to) const240 dump( std::ostream & to ) const
241 {
242 return show_content( m_deque, to );
243 }
244
245 void
fill_in()246 fill_in()
247 {
248 m_deque.push_back(3);
249 m_deque.push_back(1);
250 m_deque.push_back(4);
251 m_deque.push_back(1);
252 m_deque.push_back(5);
253 m_deque.push_back(9);
254 m_deque.push_back(2);
255 m_deque.push_back(6);
256 m_deque.push_back(5);
257 }
258
259 private:
260 std::deque< oess_2::ushort_t > m_deque;
261 };
262
263 //
264 // small_deque_type_t
265 //
266 class small_deque_type_t:
267 public oess_2::stdsn::serializable_t,
268 public dumpable_t
269 {
270 OESS_SERIALIZER( small_deque_type_t )
271 public:
small_deque_type_t()272 small_deque_type_t() {}
273
274 virtual std::ostream &
dump(std::ostream & to) const275 dump( std::ostream & to ) const
276 {
277 return show_content( m_deque, to );
278 }
279
280 void
fill_in()281 fill_in()
282 {
283 m_deque.push_back(2);
284 m_deque.push_back(7);
285 m_deque.push_back(1);
286 m_deque.push_back(8);
287 m_deque.push_back(2);
288 m_deque.push_back(8);
289 m_deque.push_back(1);
290 m_deque.push_back(8);
291 m_deque.push_back(3);
292 }
293
294 private:
295 std::deque< oess_2::ushort_t > m_deque;
296 };
297
298 //
299 // set_type_t
300 //
301
302 class set_type_t:
303 public oess_2::stdsn::serializable_t,
304 public dumpable_t
305 {
306 OESS_SERIALIZER( set_type_t )
307 public:
set_type_t()308 set_type_t() {}
309
310 virtual std::ostream &
dump(std::ostream & to) const311 dump( std::ostream & to ) const
312 {
313 return show_content( m_set, to );
314 }
315
316 void
fill_in()317 fill_in()
318 {
319 m_set.insert("int_t");
320 m_set.insert("uint_t");
321 m_set.insert("short_t");
322 m_set.insert("ushort_t");
323 m_set.insert("single_t");
324 m_set.insert("double_t");
325 m_set.insert("char_t");
326 m_set.insert("schar_t");
327 }
328
329 private:
330 std::set< std::string > m_set;
331 };
332
333 //
334 // small_set_type_t
335 //
336
337 class small_set_type_t:
338 public oess_2::stdsn::serializable_t,
339 public dumpable_t
340 {
341 OESS_SERIALIZER( small_set_type_t )
342 public:
small_set_type_t()343 small_set_type_t() {}
344
345 virtual std::ostream &
dump(std::ostream & to) const346 dump( std::ostream & to ) const
347 {
348 return show_content( m_set, to );
349 }
350
351 void
fill_in()352 fill_in()
353 {
354 m_set.insert("a");
355 m_set.insert("g");
356 m_set.insert("e");
357 m_set.insert("d");
358 m_set.insert("c");
359 m_set.insert("f");
360 m_set.insert("h");
361 m_set.insert("b");
362 }
363
364 private:
365 std::set< std::string > m_set;
366 };
367
368 //
369 // multiset_type_t
370 //
371
372 class multiset_type_t:
373 public oess_2::stdsn::serializable_t,
374 public dumpable_t
375 {
376 OESS_SERIALIZER( multiset_type_t )
377 public:
multiset_type_t()378 multiset_type_t() {}
379
380 virtual std::ostream &
dump(std::ostream & to) const381 dump( std::ostream & to ) const
382 {
383 return show_content( m_set, to );
384 }
385
386 void
fill_in()387 fill_in()
388 {
389 m_set.insert("one");
390 m_set.insert("two");
391 m_set.insert("two");
392 m_set.insert("three");
393 m_set.insert("three");
394 m_set.insert("three");
395 }
396
397 private:
398 std::multiset< std::string > m_set;
399 };
400
401 //
402 // small_multiset_type_t
403 //
404
405 class small_multiset_type_t:
406 public oess_2::stdsn::serializable_t,
407 public dumpable_t
408 {
409 OESS_SERIALIZER( small_multiset_type_t )
410 public:
small_multiset_type_t()411 small_multiset_type_t() {}
412
413 virtual std::ostream &
dump(std::ostream & to) const414 dump( std::ostream & to ) const
415 {
416 return show_content( m_set, to );
417 }
418
419 void
fill_in()420 fill_in()
421 {
422 m_set.insert("1");
423 m_set.insert("2");
424 m_set.insert("2");
425 m_set.insert("3");
426 m_set.insert("3");
427 m_set.insert("3");
428 }
429
430 private:
431 std::multiset< std::string > m_set;
432 };
433
434 //
435 // map_type_t
436 //
437
438 class map_type_t:
439 public oess_2::stdsn::serializable_t,
440 public dumpable_t
441 {
442 OESS_SERIALIZER( map_type_t )
443 public:
map_type_t()444 map_type_t() {}
445
446 virtual std::ostream &
dump(std::ostream & to) const447 dump( std::ostream & to ) const
448 {
449 return show_content( m_map, to );
450 }
451
452 void
fill_in()453 fill_in()
454 {
455 m_map[1] = "one";
456 m_map[2] = "two";
457 m_map[3] = "three";
458 m_map[4] = "four";
459 }
460
461 private:
462 typedef std::map< oess_2::int_t, std::string > map_t;
463
464 map_t m_map;
465 };
466
467 //
468 // small_map_type_t
469 //
470
471 class small_map_type_t:
472 public oess_2::stdsn::serializable_t,
473 public dumpable_t
474 {
475 OESS_SERIALIZER( small_map_type_t )
476 public:
small_map_type_t()477 small_map_type_t() {}
478
479 virtual std::ostream &
dump(std::ostream & to) const480 dump( std::ostream & to ) const
481 {
482 return show_content( m_map, to );
483 }
484
485 void
fill_in()486 fill_in()
487 {
488 m_map[1] = "I";
489 m_map[2] = "II";
490 m_map[3] = "III";
491 m_map[4] = "IV";
492 }
493
494 private:
495 typedef std::map< oess_2::int_t , std::string > map_t;
496
497 map_t m_map;
498 };
499
500 //
501 // multimap_type_t
502 //
503
504 class multimap_type_t:
505 public oess_2::stdsn::serializable_t,
506 public dumpable_t
507 {
508 OESS_SERIALIZER( multimap_type_t )
509 public:
multimap_type_t()510 multimap_type_t() {}
511
512 virtual std::ostream &
dump(std::ostream & to) const513 dump( std::ostream & to ) const
514 {
515 return show_content( m_map, to );
516 }
517
518 void
fill_in()519 fill_in()
520 {
521 m_map.insert( multimap_t::value_type( "forth", 4 ) );
522 m_map.insert( multimap_t::value_type( "third", 3 ) );
523 m_map.insert( multimap_t::value_type( "first", 1 ) );
524 m_map.insert( multimap_t::value_type( "forth", 5 ) );
525 m_map.insert( multimap_t::value_type( "seventh", 7 ) );
526 m_map.insert( multimap_t::value_type( "third", 2 ) );
527 }
528
529 private:
530 typedef std::multimap< std::string , oess_2::int_t > multimap_t;
531
532 multimap_t m_map;
533 };
534
535 //
536 // small_multimap_type_t
537 //
538
539 class small_multimap_type_t:
540 public oess_2::stdsn::serializable_t,
541 public dumpable_t
542 {
543 OESS_SERIALIZER( small_multimap_type_t )
544 public:
small_multimap_type_t()545 small_multimap_type_t() {}
546
547 virtual std::ostream &
dump(std::ostream & to) const548 dump( std::ostream & to ) const
549 {
550 return show_content( m_map, to );
551 }
552
553 void
fill_in()554 fill_in()
555 {
556 m_map.insert( multimap_t::value_type( "IV", 4 ) );
557 m_map.insert( multimap_t::value_type( "III", 3 ) );
558 m_map.insert( multimap_t::value_type( "I", 1 ) );
559 m_map.insert( multimap_t::value_type( "V", 5 ) );
560 m_map.insert( multimap_t::value_type( "VII", 7 ) );
561 m_map.insert( multimap_t::value_type( "III", 2 ) );
562 }
563
564 private:
565 typedef std::multimap< std::string, oess_2::int_t > multimap_t;
566
567 multimap_t m_map;
568 };
569
570 //
571 // small_string_type_t
572 //
573
574 class small_string_type_t:
575 public oess_2::stdsn::serializable_t,
576 public dumpable_t
577 {
578 OESS_SERIALIZER( small_string_type_t )
579 public:
small_string_type_t()580 small_string_type_t() {}
581
582 virtual std::ostream &
dump(std::ostream & to) const583 dump( std::ostream & to ) const
584 {
585 to << "'" << m_string << "'";
586 return to;
587 }
588
589 void
fill_in()590 fill_in()
591 {
592 m_string = "It's small string for testing";
593 }
594
595 private:
596 std::string m_string;
597 };
598
599 //
600 // small_vector_of_small_string_type_t
601 //
602
603 class vector_of_small_string_type_t:
604 public oess_2::stdsn::serializable_t,
605 public dumpable_t
606 {
607 OESS_SERIALIZER( vector_of_small_string_type_t )
608 public:
vector_of_small_string_type_t()609 vector_of_small_string_type_t() {}
610
611 virtual std::ostream &
dump(std::ostream & to) const612 dump( std::ostream & to ) const
613 {
614 return show_content( m_vector, to );
615 }
616
617 void
fill_in()618 fill_in()
619 {
620 m_vector.push_back("five");
621 m_vector.push_back("four");
622 m_vector.push_back("three");
623 m_vector.push_back("two");
624 m_vector.push_back("one");
625 }
626
627 private:
628 std::vector< std::string > m_vector;
629 };
630
631 //
632 // small_vector_of_small_string_type_t
633 //
634 class small_vector_of_small_string_type_t:
635 public oess_2::stdsn::serializable_t,
636 public dumpable_t
637 {
638 OESS_SERIALIZER( small_vector_of_small_string_type_t )
639 public:
small_vector_of_small_string_type_t()640 small_vector_of_small_string_type_t() {}
641
642 virtual std::ostream &
dump(std::ostream & to) const643 dump( std::ostream & to ) const
644 {
645 return show_content( m_vector, to );
646 }
647
648 void
fill_in()649 fill_in()
650 {
651 m_vector.push_back("one");
652 m_vector.push_back("two");
653 m_vector.push_back("three");
654 m_vector.push_back("four");
655 m_vector.push_back("five");
656 }
657
658 private:
659 std::vector< std::string > m_vector;
660 };
661
662 //
663 // small_map_with_small_string_as_key_type_t
664 //
665
666 class small_map_with_small_string_as_key_type_t :
667 public oess_2::stdsn::serializable_t,
668 public dumpable_t
669 {
670 OESS_SERIALIZER( small_map_with_small_string_as_key_type_t )
671 public:
small_map_with_small_string_as_key_type_t()672 small_map_with_small_string_as_key_type_t() {}
673
674 virtual std::ostream &
dump(std::ostream & to) const675 dump( std::ostream & to ) const
676 {
677 return show_content( m_map, to );
678 }
679
680 void
fill_in()681 fill_in()
682 {
683 m_map["one"] = "I";
684 m_map["two"] = "II";
685 m_map["three"] = "III";
686 m_map["four"] = "IV";
687 }
688
689 private:
690 typedef std::map< std::string, std::string > map_t;
691
692 map_t m_map;
693 };
694
695 #include "main.ddl.cpp"
696
697 template< class C >
698 void
pack_to(const C & what,std::string & to)699 pack_to( const C & what, std::string & to )
700 {
701 oess_2::io::obstring_t s( to );
702 oess_2::stdsn::oent_std_t ent( s );
703 ent << what;
704 }
705
706 template< class C >
707 void
unpack_from(C & what,const std::string & from)708 unpack_from( C & what, const std::string & from )
709 {
710 oess_2::io::ibstring_t s( from );
711 oess_2::stdsn::ient_std_t ent( s );
712 ent >> what;
713 }
714
715 struct proxy
716 {
717 const std::string m_textual;
718
719 template< class T >
proxyproxy720 proxy( const T & w ) : m_textual( make_textual(w) ) {}
721
722 bool
operator ==proxy723 operator==( const proxy & o ) const
724 {
725 return m_textual == o.m_textual;
726 }
727
728 template< class T >
729 static std::string
make_textualproxy730 make_textual( const T & w )
731 {
732 std::ostringstream o;
733 o << w;
734 return o.str();
735 }
736 };
737
738 std::ostream &
operator <<(std::ostream & to,const proxy & p)739 operator<<( std::ostream & to, const proxy & p )
740 {
741 return (to << p.m_textual);
742 }
743
744 template< class C >
745 void
do_tests()746 do_tests()
747 {
748 C first;
749 first.fill_in();
750 std::string first_image;
751 pack_to( first, first_image );
752
753 C second;
754 unpack_from( second, first_image );
755
756 UT_CHECK_EQ( proxy(first), proxy(second) );
757
758 std::string second_image;
759 pack_to( second, second_image );
760
761 UT_CHECK_EQ( binary_str_proxy(first_image), binary_str_proxy(second_image) );
762 }
763
764 #define MAKE_UNIT_TEST_FOR_CONTAINERS(C1, C2, name) \
765 UT_UNIT_TEST(name) \
766 { \
767 UT_PUSH_CONTEXT( #C1 ); \
768 do_tests< C1 >(); \
769 UT_POP_CONTEXT(); \
770 UT_PUSH_CONTEXT( #C2 ); \
771 do_tests< C2 >(); \
772 UT_POP_CONTEXT(); \
773 }
774
MAKE_UNIT_TEST_FOR_CONTAINERS(vector_type_t,small_vector_type_t,vectors)775 MAKE_UNIT_TEST_FOR_CONTAINERS(
776 vector_type_t,
777 small_vector_type_t,
778 vectors )
779
780 MAKE_UNIT_TEST_FOR_CONTAINERS(
781 list_type_t,
782 small_list_type_t,
783 lists )
784
785 MAKE_UNIT_TEST_FOR_CONTAINERS(
786 deque_type_t,
787 small_deque_type_t,
788 deques )
789
790 MAKE_UNIT_TEST_FOR_CONTAINERS(
791 set_type_t,
792 small_set_type_t,
793 sets )
794
795 MAKE_UNIT_TEST_FOR_CONTAINERS(
796 multiset_type_t,
797 small_multiset_type_t,
798 multisets )
799
800 MAKE_UNIT_TEST_FOR_CONTAINERS(
801 map_type_t,
802 small_map_type_t,
803 maps )
804
805 MAKE_UNIT_TEST_FOR_CONTAINERS(
806 multimap_type_t,
807 small_multimap_type_t,
808 multimaps )
809
810 UT_UNIT_TEST(small_string)
811 {
812 do_tests< small_string_type_t >();
813 }
814
MAKE_UNIT_TEST_FOR_CONTAINERS(vector_of_small_string_type_t,small_vector_of_small_string_type_t,vectors_of_small_strings)815 MAKE_UNIT_TEST_FOR_CONTAINERS(
816 vector_of_small_string_type_t,
817 small_vector_of_small_string_type_t,
818 vectors_of_small_strings )
819
820 UT_UNIT_TEST(small_map_with_small_string_as_key)
821 {
822 small_map_with_small_string_as_key_type_t o;
823 o.fill_in();
824
825 std::string image;
826 pack_to( o, image );
827
828 // image length should be:
829 // 1b -- map size (4)
830 // 1b + 3b -- "one" key
831 // 1b + 1b -- "I" value
832 // 1b + 3b -- "two" key
833 // 1b + 2b -- "II" value
834 // 1b + 5b -- "three" key
835 // 1b + 3b -- "III" value
836 // 1b + 4b -- "four" key
837 // 1b + 2b -- "IV" value
838 // 4b -- extension size.
839 UT_CHECK_EQ( 36, image.size() );
840
841 small_map_with_small_string_as_key_type_t r;
842 unpack_from( r, image );
843
844 UT_CHECK_EQ( proxy(o), proxy(r) );
845 }
846
847 int
main()848 main()
849 {
850 UT_RUN_UNIT_TEST(vectors);
851 UT_RUN_UNIT_TEST(lists);
852 UT_RUN_UNIT_TEST(deques);
853 UT_RUN_UNIT_TEST(sets);
854 UT_RUN_UNIT_TEST(multisets);
855 UT_RUN_UNIT_TEST(maps);
856 UT_RUN_UNIT_TEST(multimaps);
857 UT_RUN_UNIT_TEST(small_string);
858 UT_RUN_UNIT_TEST(vectors);
859
860 UT_RUN_UNIT_TEST(small_map_with_small_string_as_key);
861 }
862