ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

305 lines
8.8 KiB

  1. //
  2. // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #include "test_locale.h"
  9. #include "test_locale_tools.h"
  10. #include <booster/locale/util.h>
  11. #ifdef BOOSTER_LOCALE_WITH_ICU
  12. #include "../src/icu/codecvt.h"
  13. #endif
  14. #if defined(BOOSTER_LOCALE_WITH_ICONV) && !defined(BOOSTER_LOCALE_NO_POSIX_BACKEND)
  15. #include "../src/posix/codecvt.h"
  16. #endif
  17. #include <string.h>
  18. char *make2(unsigned v)
  19. {
  20. static unsigned char buf[3] = {0};
  21. buf[0] = 0xC0 | (v >> 6);
  22. buf[1] = 0x80 | (v & 0x3F );
  23. return reinterpret_cast<char*>(buf);
  24. }
  25. char *make3(unsigned v)
  26. {
  27. static unsigned char buf[4] = {0};
  28. buf[0] = 0xE0 | ((v >> 12) ) ;
  29. buf[1] = 0x80 | ((v >> 6) & 0x3F );
  30. buf[2] = 0x80 | ((v >> 0) & 0x3F );
  31. return reinterpret_cast<char*>(buf);
  32. }
  33. char *make4(unsigned v)
  34. {
  35. static unsigned char buf[5] = {0};
  36. buf[0] = 0xF0 | ((v >> 18) ) ;
  37. buf[1] = 0x80 | ((v >> 12) & 0x3F );
  38. buf[2] = 0x80 | ((v >> 6) & 0x3F );
  39. buf[3] = 0x80 | ((v >> 0) & 0x3F );
  40. return reinterpret_cast<char*>(buf);
  41. }
  42. static const unsigned illegal=0xFFFFFFFF;
  43. static const unsigned incomplete=0xFFFFFFFE;
  44. bool test_to(booster::locale::util::base_converter &cvt,char const *s,unsigned codepoint)
  45. {
  46. size_t len = strlen(s);
  47. char const *end = s + len;
  48. return cvt.to_unicode(s,end) == codepoint;
  49. }
  50. bool test_from(booster::locale::util::base_converter &cvt,unsigned codepoint,char const *str)
  51. {
  52. char buf[32];
  53. unsigned res = cvt.from_unicode(codepoint,buf,buf+sizeof(buf));
  54. if(res == booster::locale::util::base_converter::illegal) {
  55. return str == 0;
  56. }
  57. else {
  58. return str!=0 && strlen(str) == res && memcmp(str,buf,res) == 0;
  59. }
  60. }
  61. bool test_incomplete(booster::locale::util::base_converter &cvt,unsigned codepoint,int len)
  62. {
  63. char buf[32];
  64. unsigned res = cvt.from_unicode(codepoint,buf,buf+len);
  65. return res == incomplete;
  66. }
  67. #define TEST_TO(str,codepoint) TEST(test_to(*cvt,str,codepoint))
  68. #define TEST_FROM(str,codepoint) TEST(test_from(*cvt,codepoint,str))
  69. #define TEST_INC(codepoint,len) TEST(test_incomplete(*cvt,codepoint,len))
  70. void test_shiftjis(std::auto_ptr<booster::locale::util::base_converter> cvt)
  71. {
  72. std::cout << "- Correct" << std::endl;
  73. TEST_TO("a",'a');
  74. TEST_TO("X",'X');
  75. TEST_TO("\xCB",0xFF8b); // half width katakana Hi ヒ
  76. TEST_TO("\x83\x71",0x30d2); // Full width katakana Hi ヒ
  77. TEST_TO("\x82\xd0",0x3072); // Full width hiragana Hi ひ
  78. TEST_FROM("a",'a');
  79. TEST_FROM("X",'X');
  80. TEST_FROM("\xCB",0xFF8b); // half width katakana Hi ヒ
  81. TEST_FROM("\x83\x71",0x30d2); // Full width katakana Hi ヒ
  82. TEST_FROM("\x82\xd0",0x3072); // Full width hiragana Hi ひ
  83. std::cout << "- Illegal/incomplete" << std::endl;
  84. TEST_TO("\xa0",illegal);
  85. TEST_TO("\x82",incomplete);
  86. TEST_TO("\x83\xf0",illegal);
  87. TEST_INC(0x30d2,1); // Full width katakana Hi ヒ
  88. TEST_INC(0x3072,1); // Full width hiragana Hi ひ
  89. TEST_FROM(0,0x5e9); // Hebrew ש not in ShiftJIS
  90. }
  91. int main()
  92. {
  93. try {
  94. using namespace booster::locale::util;
  95. std::auto_ptr<base_converter> cvt;
  96. std::cout << "Test UTF-8" << std::endl;
  97. std::cout << "- From UTF-8" << std::endl;
  98. cvt = create_utf8_converter();
  99. TEST(cvt.get());
  100. TEST(cvt->is_thread_safe());
  101. TEST(cvt->max_len() == 4);
  102. std::cout << "-- Correct" << std::endl;
  103. TEST_TO("\x7f",0x7f);
  104. TEST_TO("\xC2\x80",0x80);
  105. TEST_TO("\xdf\xBF",0x7FF);
  106. TEST_TO("\xe0\xa0\x80",0x800);
  107. TEST_TO("\xef\xbf\xbf",0xFFFF);
  108. TEST_TO("\xf0\x90\x80\x80",0x10000);
  109. TEST_TO("\xf4\x8f\xbf\xbf",0x10FFFF);
  110. std::cout << "-- Too big" << std::endl;
  111. TEST_TO("\xf4\x9f\x80\x80",illegal); // 11 0000
  112. TEST_TO("\xfb\xbf\xbf\xbf",illegal); // 3FF FFFF
  113. TEST_TO("\xf8\x90\x80\x80\x80",illegal); // 400 0000
  114. TEST_TO("\xfd\xbf\xbf\xbf\xbf\xbf",illegal); // 7fff ffff
  115. std::cout << "-- Invalid trail" << std::endl;
  116. TEST_TO("\xC2\x7F",illegal);
  117. TEST_TO("\xdf\x7F",illegal);
  118. TEST_TO("\xe0\x7F\x80",illegal);
  119. TEST_TO("\xef\xbf\x7F",illegal);
  120. TEST_TO("\xe0\x7F\x80",illegal);
  121. TEST_TO("\xef\xbf\x7F",illegal);
  122. TEST_TO("\xf0\x7F\x80\x80",illegal);
  123. TEST_TO("\xf4\x7f\xbf\xbf",illegal);
  124. TEST_TO("\xf0\x90\x7F\x80",illegal);
  125. TEST_TO("\xf4\x8f\x7F\xbf",illegal);
  126. TEST_TO("\xf0\x90\x80\x7F",illegal);
  127. TEST_TO("\xf4\x8f\xbf\x7F",illegal);
  128. std::cout << "-- Invalid length" << std::endl;
  129. /// Test that this actually works
  130. TEST_TO(make2(0x80),0x80);
  131. TEST_TO(make2(0x7ff),0x7ff);
  132. TEST_TO(make3(0x800),0x800);
  133. TEST_TO(make3(0xffff),0xffff);
  134. TEST_TO(make4(0x10000),0x10000);
  135. TEST_TO(make4(0x10ffff),0x10ffff);
  136. TEST_TO(make4(0x110000),illegal);
  137. TEST_TO(make4(0x1fffff),illegal);
  138. TEST_TO(make2(0),illegal);
  139. TEST_TO(make3(0),illegal);
  140. TEST_TO(make4(0),illegal);
  141. TEST_TO(make2(0x7f),illegal);
  142. TEST_TO(make3(0x7f),illegal);
  143. TEST_TO(make4(0x7f),illegal);
  144. TEST_TO(make3(0x80),illegal);
  145. TEST_TO(make4(0x80),illegal);
  146. TEST_TO(make3(0x7ff),illegal);
  147. TEST_TO(make4(0x7ff),illegal);
  148. TEST_TO(make4(0x8000),illegal);
  149. TEST_TO(make4(0xffff),illegal);
  150. std::cout << "-- Invalid surrogate" << std::endl;
  151. TEST_TO(make3(0xD800),illegal);
  152. TEST_TO(make3(0xDBFF),illegal);
  153. TEST_TO(make3(0xDC00),illegal);
  154. TEST_TO(make3(0xDFFF),illegal);
  155. TEST_TO(make4(0xD800),illegal);
  156. TEST_TO(make4(0xDBFF),illegal);
  157. TEST_TO(make4(0xDC00),illegal);
  158. TEST_TO(make4(0xDFFF),illegal);
  159. std::cout <<"-- Incomplete" << std::endl;
  160. TEST_TO("\x80",illegal);
  161. TEST_TO("\xC2",incomplete);
  162. TEST_TO("\xdf",incomplete);
  163. TEST_TO("\xe0",incomplete);
  164. TEST_TO("\xe0\xa0",incomplete);
  165. TEST_TO("\xef\xbf",incomplete);
  166. TEST_TO("\xef",incomplete);
  167. TEST_TO("\xf0\x90\x80",incomplete);
  168. TEST_TO("\xf0\x90",incomplete);
  169. TEST_TO("\xf0",incomplete);
  170. TEST_TO("\xf4\x8f\xbf",incomplete);
  171. TEST_TO("\xf4\x8f",incomplete);
  172. TEST_TO("\xf4",incomplete);
  173. std::cout << "- To UTF-8" << std::endl;
  174. std::cout << "-- Test correct" << std::endl;
  175. TEST_FROM("\x7f",0x7f);
  176. TEST_FROM("\xC2\x80",0x80);
  177. TEST_FROM("\xdf\xBF",0x7FF);
  178. TEST_INC(0x7FF,1);
  179. TEST_FROM("\xe0\xa0\x80",0x800);
  180. TEST_INC(0x800,2);
  181. TEST_INC(0x800,1);
  182. TEST_FROM("\xef\xbf\xbf",0xFFFF);
  183. TEST_INC(0x10000,3);
  184. TEST_INC(0x10000,2);
  185. TEST_INC(0x10000,1);
  186. TEST_FROM("\xf0\x90\x80\x80",0x10000);
  187. TEST_FROM("\xf4\x8f\xbf\xbf",0x10FFFF);
  188. std::cout << "-- Test no surrogate " << std::endl;
  189. TEST_FROM(0,0xD800);
  190. TEST_FROM(0,0xDBFF);
  191. TEST_FROM(0,0xDC00);
  192. TEST_FROM(0,0xDFFF);
  193. std::cout << "-- Test invalid " << std::endl;
  194. TEST_FROM(0,0x110000);
  195. TEST_FROM(0,0x1FFFFF);
  196. std::cout << "Test windows-1255" << std::endl;
  197. cvt = create_simple_converter("windows-1255");
  198. TEST(cvt.get());
  199. TEST(cvt->is_thread_safe());
  200. TEST(cvt->max_len() == 1);
  201. std::cout << "- From 1255" << std::endl;
  202. TEST_TO("\xa4",0x20aa);
  203. TEST_TO("\xe0",0x05d0);
  204. TEST_TO("\xc4",0x5b4);
  205. TEST_TO("\xfb",illegal);
  206. TEST_TO("\xdd",illegal);
  207. TEST_TO("\xff",illegal);
  208. TEST_TO("\xfe",0x200f);
  209. std::cout << "- To 1255" << std::endl;
  210. TEST_FROM("\xa4",0x20aa);
  211. TEST_FROM("\xe0",0x05d0);
  212. TEST_FROM("\xc4",0x5b4);
  213. TEST_FROM("\xfe",0x200f);
  214. TEST_FROM(0,0xe4);
  215. TEST_FROM(0,0xd0);
  216. #ifdef BOOSTER_LOCALE_WITH_ICU
  217. std::cout << "Testing Shift-JIS using ICU/uconv" << std::endl;
  218. cvt = booster::locale::impl_icu::create_uconv_converter("Shift-JIS");
  219. TEST(cvt.get());
  220. test_shiftjis(cvt);
  221. #endif
  222. #if defined(BOOSTER_LOCALE_WITH_ICONV) && !defined(BOOSTER_LOCALE_NO_POSIX_BACKEND)
  223. std::cout << "Testing Shift-JIS using POSIX/iconv" << std::endl;
  224. cvt = booster::locale::impl_posix::create_iconv_converter("Shift-JIS");
  225. TEST(cvt.get());
  226. test_shiftjis(cvt);
  227. #endif
  228. }
  229. catch(std::exception const &e) {
  230. std::cerr << "Failed " << e.what() << std::endl;
  231. return EXIT_FAILURE;
  232. }
  233. FINALIZE();
  234. }
  235. // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
  236. // boostinspect:noascii