test_iterators.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
  2. // test_iterators.cpp
  3. // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
  4. // Use, modification and distribution is subject to the Boost Software
  5. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //#include <algorithm> // std::copy, std::equal
  8. #include <vector>
  9. #include <cstdlib> // for rand
  10. #include <functional>
  11. #include <sstream> // used to test stream iterators
  12. #include <clocale>
  13. #include <iterator> // begin
  14. #include <locale> // setlocale
  15. #include <boost/config.hpp>
  16. #ifdef BOOST_NO_STDC_NAMESPACE
  17. namespace std{
  18. using ::rand;
  19. }
  20. #endif
  21. #include <boost/detail/workaround.hpp>
  22. #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
  23. #include <boost/archive/dinkumware.hpp>
  24. #endif
  25. #ifndef BOOST_NO_CWCHAR
  26. #include <boost/archive/iterators/mb_from_wchar.hpp>
  27. #include <boost/archive/iterators/wchar_from_mb.hpp>
  28. #endif
  29. #include <boost/archive/iterators/xml_escape.hpp>
  30. #include <boost/archive/iterators/xml_unescape.hpp>
  31. #include <boost/archive/iterators/transform_width.hpp>
  32. #include <boost/archive/iterators/istream_iterator.hpp>
  33. #include <boost/archive/iterators/ostream_iterator.hpp>
  34. #include "test_tools.hpp"
  35. #ifndef BOOST_NO_CWCHAR
  36. void test_wchar_from_mb(const wchar_t *la, const char * a, const unsigned int size){
  37. typedef boost::archive::iterators::wchar_from_mb<const char *> translator;
  38. BOOST_CHECK((
  39. std::equal(
  40. translator(a),
  41. translator(a + size),
  42. la
  43. )
  44. ));
  45. }
  46. void test_mb_from_wchar(const char * a, const wchar_t *la, const unsigned int size){
  47. typedef boost::archive::iterators::mb_from_wchar<const wchar_t *> translator;
  48. BOOST_CHECK(
  49. std::equal(
  50. translator(la),
  51. translator(la + size),
  52. a
  53. )
  54. );
  55. }
  56. void test_roundtrip(const wchar_t * la){
  57. std::size_t s = std::wcslen(la);
  58. std::vector<char> a;
  59. {
  60. typedef boost::archive::iterators::mb_from_wchar<const wchar_t *> translator;
  61. std::copy(
  62. translator(la),
  63. translator(la + s),
  64. std::back_inserter(a)
  65. );
  66. // note: wchar_from_mb NEEDS a termination null in order to function!
  67. a.push_back(static_cast<char>(0));
  68. }
  69. BOOST_CHECK(a.size() > 0);
  70. std::vector<wchar_t> la2;
  71. {
  72. typedef boost::archive::iterators::wchar_from_mb<std::vector<char>::const_iterator> translator;
  73. std::copy(
  74. translator(a.begin()),
  75. translator(),
  76. std::back_inserter(la2)
  77. );
  78. }
  79. BOOST_CHECK(la2.size() == s);
  80. BOOST_CHECK(std::equal(la, la + s, la2.begin()));
  81. }
  82. #endif
  83. template<class CharType>
  84. void test_xml_escape(
  85. const CharType * xml_escaped,
  86. const CharType * xml,
  87. unsigned int size
  88. ){
  89. typedef boost::archive::iterators::xml_escape<const CharType *> translator;
  90. BOOST_CHECK(
  91. std::equal(
  92. translator(xml),
  93. translator(xml + size),
  94. xml_escaped
  95. )
  96. );
  97. }
  98. template<class CharType>
  99. void test_xml_unescape(
  100. const CharType * xml,
  101. const CharType * xml_escaped,
  102. unsigned int size
  103. ){
  104. // test xml_unescape
  105. typedef boost::archive::iterators::xml_unescape<const CharType *> translator;
  106. BOOST_CHECK(
  107. std::equal(
  108. translator(xml_escaped),
  109. translator(xml_escaped + size),
  110. xml
  111. )
  112. );
  113. }
  114. template<int BitsOut, int BitsIn>
  115. void test_transform_width(unsigned int size){
  116. // test transform_width
  117. char rawdata[8];
  118. char * rptr;
  119. for(rptr = rawdata + size; rptr-- > rawdata;)
  120. *rptr = static_cast<char>(0xff & std::rand());
  121. // convert 8 to 6 bit characters
  122. typedef boost::archive::iterators::transform_width<
  123. char *, BitsOut, BitsIn
  124. > translator1;
  125. std::vector<char> vout;
  126. std::copy(
  127. translator1(static_cast<char *>(rawdata)),
  128. translator1(rawdata + size),
  129. std::back_inserter(vout)
  130. );
  131. // check to see we got the expected # of characters out
  132. if(0 == size)
  133. BOOST_CHECK(vout.size() == 0);
  134. else
  135. BOOST_CHECK(vout.size() == (size * BitsIn - 1 ) / BitsOut + 1);
  136. typedef boost::archive::iterators::transform_width<
  137. std::vector<char>::iterator, BitsIn, BitsOut
  138. > translator2;
  139. std::vector<char> vin;
  140. std::copy(
  141. translator2(vout.begin()),
  142. translator2(vout.end()),
  143. std::back_inserter(vin)
  144. );
  145. // check to see we got the expected # of characters out
  146. BOOST_CHECK(vin.size() == size);
  147. BOOST_CHECK(
  148. std::equal(
  149. rawdata,
  150. rawdata + size,
  151. vin.begin()
  152. )
  153. );
  154. }
  155. template<class CharType>
  156. void test_stream_iterators(
  157. const CharType * test_data,
  158. unsigned int size
  159. ){
  160. std::basic_stringstream<CharType> ss;
  161. boost::archive::iterators::ostream_iterator<CharType> osi =
  162. boost::archive::iterators::ostream_iterator<CharType>(ss);
  163. std::copy(test_data, test_data + size, osi);
  164. BOOST_CHECK(size == ss.str().size());
  165. boost::archive::iterators::istream_iterator<CharType> isi =
  166. boost::archive::iterators::istream_iterator<CharType>(ss);
  167. BOOST_CHECK(std::equal(test_data, test_data + size,isi));
  168. }
  169. int
  170. test_main(int /* argc */, char* /* argv */ [] )
  171. {
  172. const char xml[] = "<+>+&+\"+'";
  173. const char xml_escaped[] = "&lt;+&gt;+&amp;+&quot;+&apos;";
  174. test_xml_escape<const char>(
  175. xml_escaped,
  176. xml,
  177. sizeof(xml) / sizeof(char) - 1
  178. );
  179. test_xml_unescape<const char>(
  180. xml,
  181. xml_escaped,
  182. sizeof(xml_escaped) / sizeof(char) - 1
  183. );
  184. #ifndef BOOST_NO_CWCHAR
  185. const wchar_t wxml[] = L"<+>+&+\"+'";
  186. const wchar_t wxml_escaped[] = L"&lt;+&gt;+&amp;+&quot;+&apos;";
  187. test_xml_escape<const wchar_t>(
  188. wxml_escaped,
  189. wxml,
  190. sizeof(wxml) / sizeof(wchar_t) - 1
  191. );
  192. test_xml_unescape<const wchar_t>(
  193. wxml,
  194. wxml_escaped,
  195. sizeof(wxml_escaped) / sizeof(wchar_t) - 1
  196. );
  197. const char b[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
  198. const wchar_t lb[] = L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
  199. test_mb_from_wchar(b, lb, sizeof(lb) / sizeof(wchar_t) - 1);
  200. test_wchar_from_mb(lb, b, sizeof(b) / sizeof(char) - 1);
  201. const char a[] = "abcdefghijklmnopqrstuvwxyz";
  202. const wchar_t la[] = L"abcdefghijklmnopqrstuvwxyz";
  203. test_mb_from_wchar(a, la, sizeof(la) / sizeof(wchar_t) - 1);
  204. test_wchar_from_mb(la, a, sizeof(a) / sizeof(char) - 1);
  205. test_roundtrip(L"z\u00df\u6c34\U0001f34c");
  206. test_stream_iterators<wchar_t>(la, sizeof(la)/sizeof(wchar_t) - 1);
  207. #endif
  208. test_stream_iterators<char>(a, sizeof(a) - 1);
  209. test_transform_width<6, 8>(0);
  210. test_transform_width<6, 8>(1);
  211. test_transform_width<6, 8>(2);
  212. test_transform_width<6, 8>(3);
  213. test_transform_width<6, 8>(4);
  214. test_transform_width<6, 8>(5);
  215. test_transform_width<6, 8>(6);
  216. test_transform_width<6, 8>(7);
  217. test_transform_width<6, 8>(8);
  218. return EXIT_SUCCESS;
  219. }