Leaked source code of windows server 2003
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.

1889 lines
61 KiB

  1. #include <bcl_common.h>
  2. #include <bcl_w32unicodeinlinestringbuffer.h>
  3. #include <bcl_w32unicodestringbuffer.h>
  4. #include <bcl_w32unicodefixedstringbuffer.h>
  5. #include <stdio.h>
  6. #include <limits.h>
  7. extern "C" void bar(BCL::CWin32BaseUnicodeInlineStringBuffer<50> *p);
  8. template class BCL::CWin32BaseUnicodeInlineStringBuffer<50>;
  9. #define SHOULDFAIL(_e, _le) do { BOOL fSuccess = (_e); BCL_ASSERT((!fSuccess) && (::GetLastError() == (_le))); } while (0)
  10. #define SHOULDWORK(_e) do { BOOL fSuccess = (_e); BCL_ASSERT(fSuccess); } while (0)
  11. #define CHECK(_sv, x) do { bool fEquals; SHOULDWORK(_sv.Equals(x, static_cast<SIZE_T>(BCL_NUMBER_OF(x) - 1), fEquals)); BCL_ASSERT(fEquals); } while (0)
  12. template <typename TStringClass>
  13. void
  14. DoCheckCaseSensitiveComparisons(
  15. TStringClass &rString
  16. )
  17. {
  18. bool fEquals;
  19. int iComparisonResult;
  20. SHOULDWORK(rString.Assign(L"foobarbazeieiomumble"));
  21. CHECK(rString, L"foobarbazeieiomumble");
  22. SHOULDWORK(rString.Equals(L"hello there", fEquals));
  23. BCL_ASSERT(!fEquals);
  24. SHOULDWORK(rString.Equals(L"foobarbazeieiomumble", fEquals));
  25. BCL_ASSERT(fEquals);
  26. SHOULDWORK(rString.Equals(L"FooBarBazEieioMumble", fEquals));
  27. BCL_ASSERT(!fEquals);
  28. SHOULDWORK(rString.Compare(L"foo", iComparisonResult));
  29. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  30. SHOULDWORK(rString.Compare(L"foozle", iComparisonResult));
  31. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  32. SHOULDWORK(rString.Assign(L'f'));
  33. CHECK(rString, L"f");
  34. SHOULDWORK(rString.Equals(L'e', fEquals));
  35. BCL_ASSERT(!fEquals);
  36. SHOULDWORK(rString.Equals(L'f', fEquals));
  37. BCL_ASSERT(fEquals);
  38. SHOULDWORK(rString.Equals(L'g', fEquals));
  39. BCL_ASSERT(!fEquals);
  40. SHOULDWORK(rString.Equals(L'E', fEquals));
  41. BCL_ASSERT(!fEquals);
  42. SHOULDWORK(rString.Equals(L'F', fEquals));
  43. BCL_ASSERT(!fEquals);
  44. SHOULDWORK(rString.Equals(L'G', fEquals));
  45. BCL_ASSERT(!fEquals);
  46. SHOULDWORK(rString.Compare(L'e', iComparisonResult));
  47. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  48. SHOULDWORK(rString.Compare(L'f', iComparisonResult));
  49. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  50. SHOULDWORK(rString.Compare(L'g', iComparisonResult));
  51. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  52. SHOULDWORK(rString.Compare(L'E', iComparisonResult));
  53. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  54. SHOULDWORK(rString.Compare(L'F', iComparisonResult));
  55. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  56. SHOULDWORK(rString.Compare(L'G', iComparisonResult));
  57. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  58. }
  59. template <typename TStringClass>
  60. void
  61. DoCheckCaseInsensitiveComparisons(
  62. TStringClass &rString
  63. )
  64. {
  65. bool fEquals;
  66. int iComparisonResult;
  67. SHOULDWORK(rString.Assign(L"foobarbazeieiomumble"));
  68. CHECK(rString, L"foobarbazeieiomumble");
  69. SHOULDWORK(rString.EqualsI(L"hello there", BCL::CWin32CaseInsensitivityData(), fEquals));
  70. BCL_ASSERT(!fEquals);
  71. SHOULDWORK(rString.EqualsILI(L"foobarbazeieiomumble", fEquals));
  72. BCL_ASSERT(fEquals);
  73. SHOULDWORK(rString.EqualsILI(L"foobarbazeieio", fEquals));
  74. BCL_ASSERT(!fEquals);
  75. SHOULDWORK(rString.EqualsILI(L"foobarbazeieiomumblexyz", fEquals));
  76. BCL_ASSERT(!fEquals);
  77. SHOULDWORK(rString.EqualsILI(L"FooBarBazEieioMumble", fEquals));
  78. BCL_ASSERT(fEquals);
  79. SHOULDWORK(rString.CompareI(L"FOO", BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  80. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  81. SHOULDWORK(rString.CompareI(L"FOOZLE", BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  82. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  83. SHOULDWORK(rString.CompareILI(L"foobarbazeieiomumble", iComparisonResult));
  84. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  85. SHOULDWORK(rString.CompareILI(L"foobarbazeieio", iComparisonResult));
  86. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  87. SHOULDWORK(rString.CompareILI(L"foobarbazeieiomumblexyz", iComparisonResult));
  88. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  89. SHOULDWORK(rString.CompareILI(L"FooBarBazEieioMumble", iComparisonResult));
  90. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  91. SHOULDWORK(rString.Assign(L'f'));
  92. CHECK(rString, L"f");
  93. SHOULDWORK(rString.EqualsI(L'h', BCL::CWin32CaseInsensitivityData(), fEquals));
  94. BCL_ASSERT(!fEquals);
  95. SHOULDWORK(rString.EqualsILI(L'f', fEquals));
  96. BCL_ASSERT(fEquals);
  97. SHOULDWORK(rString.EqualsILI(L'F', fEquals));
  98. BCL_ASSERT(fEquals);
  99. SHOULDWORK(rString.EqualsILI(L'e', fEquals));
  100. BCL_ASSERT(!fEquals);
  101. SHOULDWORK(rString.EqualsILI(L'E', fEquals));
  102. BCL_ASSERT(!fEquals);
  103. SHOULDWORK(rString.EqualsILI(L'g', fEquals));
  104. BCL_ASSERT(!fEquals);
  105. SHOULDWORK(rString.EqualsILI(L'G', fEquals));
  106. BCL_ASSERT(!fEquals);
  107. SHOULDWORK(rString.CompareI(L'E', BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  108. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  109. SHOULDWORK(rString.CompareI(L'F', BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  110. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  111. SHOULDWORK(rString.CompareI(L'G', BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  112. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  113. SHOULDWORK(rString.CompareI(L'e', BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  114. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  115. SHOULDWORK(rString.CompareI(L'f', BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  116. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  117. SHOULDWORK(rString.CompareI(L'g', BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  118. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  119. }
  120. template <typename TStringClass>
  121. void
  122. DoCheckCharacterFinding(
  123. TStringClass &rString
  124. )
  125. {
  126. SIZE_T ich;
  127. bool fContains;
  128. SHOULDWORK(rString.Assign(L"bbbcccdddeeefffggg"));
  129. CHECK(rString, L"bbbcccdddeeefffggg");
  130. SHOULDWORK(rString.Contains(L'a', fContains));
  131. BCL_ASSERT(!fContains);
  132. SHOULDWORK(rString.Contains(L'b', fContains));
  133. BCL_ASSERT(fContains);
  134. SHOULDWORK(rString.Contains(L'g', fContains));
  135. BCL_ASSERT(fContains);
  136. SHOULDWORK(rString.Contains(L'h', fContains));
  137. BCL_ASSERT(!fContains);
  138. SHOULDWORK(rString.Contains(L'A', fContains));
  139. BCL_ASSERT(!fContains);
  140. SHOULDWORK(rString.Contains(L'B', fContains));
  141. BCL_ASSERT(!fContains);
  142. SHOULDWORK(rString.Contains(L'G', fContains));
  143. BCL_ASSERT(!fContains);
  144. SHOULDWORK(rString.Contains(L'H', fContains));
  145. BCL_ASSERT(!fContains);
  146. SHOULDWORK(rString.ContainsI(L'a', BCL::CWin32CaseInsensitivityData(), fContains));
  147. BCL_ASSERT(!fContains);
  148. SHOULDWORK(rString.ContainsI(L'b', BCL::CWin32CaseInsensitivityData(), fContains));
  149. BCL_ASSERT(fContains);
  150. SHOULDWORK(rString.ContainsI(L'g', BCL::CWin32CaseInsensitivityData(), fContains));
  151. BCL_ASSERT(fContains);
  152. SHOULDWORK(rString.ContainsI(L'h', BCL::CWin32CaseInsensitivityData(), fContains));
  153. BCL_ASSERT(!fContains);
  154. SHOULDWORK(rString.ContainsI(L'A', BCL::CWin32CaseInsensitivityData(), fContains));
  155. BCL_ASSERT(!fContains);
  156. SHOULDWORK(rString.ContainsI(L'B', BCL::CWin32CaseInsensitivityData(), fContains));
  157. BCL_ASSERT(fContains);
  158. SHOULDWORK(rString.ContainsI(L'G', BCL::CWin32CaseInsensitivityData(), fContains));
  159. BCL_ASSERT(fContains);
  160. SHOULDWORK(rString.ContainsI(L'H', BCL::CWin32CaseInsensitivityData(), fContains));
  161. BCL_ASSERT(!fContains);
  162. SHOULDWORK(rString.ContainsILI(L'a', fContains));
  163. BCL_ASSERT(!fContains);
  164. SHOULDWORK(rString.ContainsILI(L'b', fContains));
  165. BCL_ASSERT(fContains);
  166. SHOULDWORK(rString.ContainsILI(L'g', fContains));
  167. BCL_ASSERT(fContains);
  168. SHOULDWORK(rString.ContainsILI(L'h', fContains));
  169. BCL_ASSERT(!fContains);
  170. SHOULDWORK(rString.ContainsILI(L'A', fContains));
  171. BCL_ASSERT(!fContains);
  172. SHOULDWORK(rString.ContainsILI(L'B', fContains));
  173. BCL_ASSERT(fContains);
  174. SHOULDWORK(rString.ContainsILI(L'G', fContains));
  175. BCL_ASSERT(fContains);
  176. SHOULDWORK(rString.ContainsILI(L'H', fContains));
  177. BCL_ASSERT(!fContains);
  178. SHOULDWORK(rString.FindFirst(L'a', ich));
  179. BCL_ASSERT(ich == 18);
  180. SHOULDWORK(rString.FindFirst(L'b', ich));
  181. BCL_ASSERT(ich == 0);
  182. SHOULDWORK(rString.FindFirst(L'c', ich));
  183. BCL_ASSERT(ich == 3);
  184. SHOULDWORK(rString.FindFirst(L'g', ich));
  185. BCL_ASSERT(ich == 15);
  186. SHOULDWORK(rString.FindFirst(L'h', ich));
  187. BCL_ASSERT(ich == 18);
  188. SHOULDWORK(rString.FindFirst(L'A', ich));
  189. BCL_ASSERT(ich == 18);
  190. SHOULDWORK(rString.FindFirst(L'B', ich));
  191. BCL_ASSERT(ich == 18);
  192. SHOULDWORK(rString.FindFirst(L'G', ich));
  193. BCL_ASSERT(ich == 18);
  194. SHOULDWORK(rString.FindFirst(L'H', ich));
  195. BCL_ASSERT(ich == 18);
  196. SHOULDWORK(rString.FindLast(L'a', ich));
  197. BCL_ASSERT(ich == 18);
  198. SHOULDWORK(rString.FindLast(L'b', ich));
  199. BCL_ASSERT(ich == 2);
  200. SHOULDWORK(rString.FindLast(L'c', ich));
  201. BCL_ASSERT(ich == 5);
  202. SHOULDWORK(rString.FindLast(L'g', ich));
  203. BCL_ASSERT(ich == 17);
  204. SHOULDWORK(rString.FindLast(L'h', ich));
  205. BCL_ASSERT(ich == 18);
  206. SHOULDWORK(rString.FindLast(L'A', ich));
  207. BCL_ASSERT(ich == 18);
  208. SHOULDWORK(rString.FindLast(L'B', ich));
  209. BCL_ASSERT(ich == 18);
  210. SHOULDWORK(rString.FindLast(L'G', ich));
  211. BCL_ASSERT(ich == 18);
  212. SHOULDWORK(rString.FindLast(L'H', ich));
  213. BCL_ASSERT(ich == 18);
  214. SHOULDWORK(rString.FindFirstI(L'a', BCL::CWin32CaseInsensitivityData(), ich));
  215. BCL_ASSERT(ich == 18);
  216. SHOULDWORK(rString.FindFirstI(L'b', BCL::CWin32CaseInsensitivityData(), ich));
  217. BCL_ASSERT(ich == 0);
  218. SHOULDWORK(rString.FindFirstI(L'c', BCL::CWin32CaseInsensitivityData(), ich));
  219. BCL_ASSERT(ich == 3);
  220. SHOULDWORK(rString.FindFirstI(L'g', BCL::CWin32CaseInsensitivityData(), ich));
  221. BCL_ASSERT(ich == 15);
  222. SHOULDWORK(rString.FindFirstI(L'h', BCL::CWin32CaseInsensitivityData(), ich));
  223. BCL_ASSERT(ich == 18);
  224. SHOULDWORK(rString.FindFirstI(L'A', BCL::CWin32CaseInsensitivityData(), ich));
  225. BCL_ASSERT(ich == 18);
  226. SHOULDWORK(rString.FindFirstI(L'B', BCL::CWin32CaseInsensitivityData(), ich));
  227. BCL_ASSERT(ich == 0);
  228. SHOULDWORK(rString.FindFirstI(L'G', BCL::CWin32CaseInsensitivityData(), ich));
  229. BCL_ASSERT(ich == 15);
  230. SHOULDWORK(rString.FindFirstI(L'H', BCL::CWin32CaseInsensitivityData(), ich));
  231. BCL_ASSERT(ich == 18);
  232. SHOULDWORK(rString.FindLastI(L'a', BCL::CWin32CaseInsensitivityData(), ich));
  233. BCL_ASSERT(ich == 18);
  234. SHOULDWORK(rString.FindLastI(L'b', BCL::CWin32CaseInsensitivityData(), ich));
  235. BCL_ASSERT(ich == 2);
  236. SHOULDWORK(rString.FindLastI(L'c', BCL::CWin32CaseInsensitivityData(), ich));
  237. BCL_ASSERT(ich == 5);
  238. SHOULDWORK(rString.FindLastI(L'g', BCL::CWin32CaseInsensitivityData(), ich));
  239. BCL_ASSERT(ich == 17);
  240. SHOULDWORK(rString.FindLastI(L'h', BCL::CWin32CaseInsensitivityData(), ich));
  241. BCL_ASSERT(ich == 18);
  242. SHOULDWORK(rString.FindLastI(L'A', BCL::CWin32CaseInsensitivityData(), ich));
  243. BCL_ASSERT(ich == 18);
  244. SHOULDWORK(rString.FindLastI(L'B', BCL::CWin32CaseInsensitivityData(), ich));
  245. BCL_ASSERT(ich == 2);
  246. SHOULDWORK(rString.FindLastI(L'G', BCL::CWin32CaseInsensitivityData(), ich));
  247. BCL_ASSERT(ich == 17);
  248. SHOULDWORK(rString.FindLastI(L'H', BCL::CWin32CaseInsensitivityData(), ich));
  249. BCL_ASSERT(ich == 18);
  250. SHOULDWORK(rString.FindFirstILI(L'a', ich));
  251. BCL_ASSERT(ich == 18);
  252. SHOULDWORK(rString.FindFirstILI(L'b', ich));
  253. BCL_ASSERT(ich == 0);
  254. SHOULDWORK(rString.FindFirstILI(L'c', ich));
  255. BCL_ASSERT(ich == 3);
  256. SHOULDWORK(rString.FindFirstILI(L'g', ich));
  257. BCL_ASSERT(ich == 15);
  258. SHOULDWORK(rString.FindFirstILI(L'h', ich));
  259. BCL_ASSERT(ich == 18);
  260. SHOULDWORK(rString.FindFirstILI(L'A', ich));
  261. BCL_ASSERT(ich == 18);
  262. SHOULDWORK(rString.FindFirstILI(L'B', ich));
  263. BCL_ASSERT(ich == 0);
  264. SHOULDWORK(rString.FindFirstILI(L'G', ich));
  265. BCL_ASSERT(ich == 15);
  266. SHOULDWORK(rString.FindFirstILI(L'H', ich));
  267. BCL_ASSERT(ich == 18);
  268. SHOULDWORK(rString.FindLastILI(L'a', ich));
  269. BCL_ASSERT(ich == 18);
  270. SHOULDWORK(rString.FindLastILI(L'b', ich));
  271. BCL_ASSERT(ich == 2);
  272. SHOULDWORK(rString.FindLastILI(L'c', ich));
  273. BCL_ASSERT(ich == 5);
  274. SHOULDWORK(rString.FindLastILI(L'g', ich));
  275. BCL_ASSERT(ich == 17);
  276. SHOULDWORK(rString.FindLastILI(L'h', ich));
  277. BCL_ASSERT(ich == 18);
  278. SHOULDWORK(rString.FindLastILI(L'A', ich));
  279. BCL_ASSERT(ich == 18);
  280. SHOULDWORK(rString.FindLastILI(L'B', ich));
  281. BCL_ASSERT(ich == 2);
  282. SHOULDWORK(rString.FindLastILI(L'G', ich));
  283. BCL_ASSERT(ich == 17);
  284. SHOULDWORK(rString.FindLastILI(L'H', ich));
  285. BCL_ASSERT(ich == 18);
  286. }
  287. template <typename TStringClass>
  288. void
  289. DoCheckStringFinding(
  290. TStringClass &rString
  291. )
  292. {
  293. SIZE_T ich;
  294. bool fContains;
  295. SHOULDWORK(rString.Assign(L"bbbcccdddeeefffggg"));
  296. CHECK(rString, L"bbbcccdddeeefffggg");
  297. SHOULDWORK(rString.Contains(L"a", fContains));
  298. BCL_ASSERT(!fContains);
  299. SHOULDWORK(rString.Contains(L"b", fContains));
  300. BCL_ASSERT(fContains);
  301. SHOULDWORK(rString.Contains(L"g", fContains));
  302. BCL_ASSERT(fContains);
  303. SHOULDWORK(rString.Contains(L"h", fContains));
  304. BCL_ASSERT(!fContains);
  305. SHOULDWORK(rString.Contains(L"A", fContains));
  306. BCL_ASSERT(!fContains);
  307. SHOULDWORK(rString.Contains(L"B", fContains));
  308. BCL_ASSERT(!fContains);
  309. SHOULDWORK(rString.Contains(L"G", fContains));
  310. BCL_ASSERT(!fContains);
  311. SHOULDWORK(rString.Contains(L"H", fContains));
  312. BCL_ASSERT(!fContains);
  313. SHOULDWORK(rString.Contains(L"bb", fContains));
  314. BCL_ASSERT(fContains);
  315. SHOULDWORK(rString.Contains(L"bbb", fContains));
  316. BCL_ASSERT(fContains);
  317. SHOULDWORK(rString.Contains(L"bbc", fContains));
  318. BCL_ASSERT(fContains);
  319. SHOULDWORK(rString.Contains(L"bbbc", fContains));
  320. BCL_ASSERT(fContains);
  321. SHOULDWORK(rString.Contains(L"bbbb", fContains));
  322. BCL_ASSERT(!fContains);
  323. SHOULDWORK(rString.Contains(L"ggg", fContains));
  324. BCL_ASSERT(fContains);
  325. SHOULDWORK(rString.FindFirst(L"a", ich));
  326. BCL_ASSERT(ich == 18);
  327. SHOULDWORK(rString.FindFirst(L"b", ich));
  328. BCL_ASSERT(ich == 0);
  329. SHOULDWORK(rString.FindFirst(L"c", ich));
  330. BCL_ASSERT(ich == 3);
  331. SHOULDWORK(rString.FindFirst(L"g", ich));
  332. BCL_ASSERT(ich == 15);
  333. SHOULDWORK(rString.FindFirst(L"h", ich));
  334. BCL_ASSERT(ich == 18);
  335. SHOULDWORK(rString.FindFirst(L"A", ich));
  336. BCL_ASSERT(ich == 18);
  337. SHOULDWORK(rString.FindFirst(L"B", ich));
  338. BCL_ASSERT(ich == 18);
  339. SHOULDWORK(rString.FindFirst(L"G", ich));
  340. BCL_ASSERT(ich == 18);
  341. SHOULDWORK(rString.FindFirst(L"H", ich));
  342. BCL_ASSERT(ich == 18);
  343. SHOULDWORK(rString.FindLast(L"a", ich));
  344. BCL_ASSERT(ich == 18);
  345. SHOULDWORK(rString.FindLast(L"b", ich));
  346. BCL_ASSERT(ich == 2);
  347. SHOULDWORK(rString.FindLast(L"c", ich));
  348. BCL_ASSERT(ich == 5);
  349. SHOULDWORK(rString.FindLast(L"g", ich));
  350. BCL_ASSERT(ich == 17);
  351. SHOULDWORK(rString.FindLast(L"h", ich));
  352. BCL_ASSERT(ich == 18);
  353. SHOULDWORK(rString.FindLast(L"A", ich));
  354. BCL_ASSERT(ich == 18);
  355. SHOULDWORK(rString.FindLast(L"B", ich));
  356. BCL_ASSERT(ich == 18);
  357. SHOULDWORK(rString.FindLast(L"G", ich));
  358. BCL_ASSERT(ich == 18);
  359. SHOULDWORK(rString.FindLast(L"H", ich));
  360. BCL_ASSERT(ich == 18);
  361. SHOULDWORK(rString.FindFirstI(L"a", BCL::CWin32CaseInsensitivityData(), ich));
  362. BCL_ASSERT(ich == 18);
  363. SHOULDWORK(rString.FindFirstI(L"b", BCL::CWin32CaseInsensitivityData(), ich));
  364. BCL_ASSERT(ich == 0);
  365. SHOULDWORK(rString.FindFirstI(L"c", BCL::CWin32CaseInsensitivityData(), ich));
  366. BCL_ASSERT(ich == 3);
  367. SHOULDWORK(rString.FindFirstI(L"g", BCL::CWin32CaseInsensitivityData(), ich));
  368. BCL_ASSERT(ich == 15);
  369. SHOULDWORK(rString.FindFirstI(L"h", BCL::CWin32CaseInsensitivityData(), ich));
  370. BCL_ASSERT(ich == 18);
  371. SHOULDWORK(rString.FindFirstI(L"A", BCL::CWin32CaseInsensitivityData(), ich));
  372. BCL_ASSERT(ich == 18);
  373. SHOULDWORK(rString.FindFirstI(L"B", BCL::CWin32CaseInsensitivityData(), ich));
  374. BCL_ASSERT(ich == 0);
  375. SHOULDWORK(rString.FindFirstI(L"G", BCL::CWin32CaseInsensitivityData(), ich));
  376. BCL_ASSERT(ich == 15);
  377. SHOULDWORK(rString.FindFirstI(L"H", BCL::CWin32CaseInsensitivityData(), ich));
  378. BCL_ASSERT(ich == 18);
  379. SHOULDWORK(rString.FindLastI(L"a", BCL::CWin32CaseInsensitivityData(), ich));
  380. BCL_ASSERT(ich == 18);
  381. SHOULDWORK(rString.FindLastI(L"b", BCL::CWin32CaseInsensitivityData(), ich));
  382. BCL_ASSERT(ich == 2);
  383. SHOULDWORK(rString.FindLastI(L"c", BCL::CWin32CaseInsensitivityData(), ich));
  384. BCL_ASSERT(ich == 5);
  385. SHOULDWORK(rString.FindLastI(L"g", BCL::CWin32CaseInsensitivityData(), ich));
  386. BCL_ASSERT(ich == 17);
  387. SHOULDWORK(rString.FindLastI(L"h", BCL::CWin32CaseInsensitivityData(), ich));
  388. BCL_ASSERT(ich == 18);
  389. SHOULDWORK(rString.FindLastI(L"A", BCL::CWin32CaseInsensitivityData(), ich));
  390. BCL_ASSERT(ich == 18);
  391. SHOULDWORK(rString.FindLastI(L"B", BCL::CWin32CaseInsensitivityData(), ich));
  392. BCL_ASSERT(ich == 2);
  393. SHOULDWORK(rString.FindLastI(L"G", BCL::CWin32CaseInsensitivityData(), ich));
  394. BCL_ASSERT(ich == 17);
  395. SHOULDWORK(rString.FindLastI(L"H", BCL::CWin32CaseInsensitivityData(), ich));
  396. BCL_ASSERT(ich == 18);
  397. SHOULDWORK(rString.FindFirstILI(L"a", ich));
  398. BCL_ASSERT(ich == 18);
  399. SHOULDWORK(rString.FindFirstILI(L"b", ich));
  400. BCL_ASSERT(ich == 0);
  401. SHOULDWORK(rString.FindFirstILI(L"c", ich));
  402. BCL_ASSERT(ich == 3);
  403. SHOULDWORK(rString.FindFirstILI(L"g", ich));
  404. BCL_ASSERT(ich == 15);
  405. SHOULDWORK(rString.FindFirstILI(L"h", ich));
  406. BCL_ASSERT(ich == 18);
  407. SHOULDWORK(rString.FindFirstILI(L"A", ich));
  408. BCL_ASSERT(ich == 18);
  409. SHOULDWORK(rString.FindFirstILI(L"B", ich));
  410. BCL_ASSERT(ich == 0);
  411. SHOULDWORK(rString.FindFirstILI(L"G", ich));
  412. BCL_ASSERT(ich == 15);
  413. SHOULDWORK(rString.FindFirstILI(L"H", ich));
  414. BCL_ASSERT(ich == 18);
  415. SHOULDWORK(rString.FindLastILI(L"a", ich));
  416. BCL_ASSERT(ich == 18);
  417. SHOULDWORK(rString.FindLastILI(L"b", ich));
  418. BCL_ASSERT(ich == 2);
  419. SHOULDWORK(rString.FindLastILI(L"c", ich));
  420. BCL_ASSERT(ich == 5);
  421. SHOULDWORK(rString.FindLastILI(L"g", ich));
  422. BCL_ASSERT(ich == 17);
  423. SHOULDWORK(rString.FindLastILI(L"h", ich));
  424. BCL_ASSERT(ich == 18);
  425. SHOULDWORK(rString.FindLastILI(L"A", ich));
  426. BCL_ASSERT(ich == 18);
  427. SHOULDWORK(rString.FindLastILI(L"B", ich));
  428. BCL_ASSERT(ich == 2);
  429. SHOULDWORK(rString.FindLastILI(L"G", ich));
  430. BCL_ASSERT(ich == 17);
  431. SHOULDWORK(rString.FindLastILI(L"H", ich));
  432. BCL_ASSERT(ich == 18);
  433. //
  434. //
  435. //
  436. SHOULDWORK(rString.FindFirst(L"aa", ich));
  437. BCL_ASSERT(ich == 18);
  438. SHOULDWORK(rString.FindFirst(L"bb", ich));
  439. BCL_ASSERT(ich == 0);
  440. SHOULDWORK(rString.FindFirst(L"cc", ich));
  441. BCL_ASSERT(ich == 3);
  442. SHOULDWORK(rString.FindFirst(L"gg", ich));
  443. BCL_ASSERT(ich == 15);
  444. SHOULDWORK(rString.FindFirst(L"hh", ich));
  445. BCL_ASSERT(ich == 18);
  446. SHOULDWORK(rString.FindFirst(L"AA", ich));
  447. BCL_ASSERT(ich == 18);
  448. SHOULDWORK(rString.FindFirst(L"BB", ich));
  449. BCL_ASSERT(ich == 18);
  450. SHOULDWORK(rString.FindFirst(L"GG", ich));
  451. BCL_ASSERT(ich == 18);
  452. SHOULDWORK(rString.FindFirst(L"HH", ich));
  453. BCL_ASSERT(ich == 18);
  454. SHOULDWORK(rString.FindLast(L"aa", ich));
  455. BCL_ASSERT(ich == 18);
  456. SHOULDWORK(rString.FindLast(L"bb", ich));
  457. BCL_ASSERT(ich == 1);
  458. SHOULDWORK(rString.FindLast(L"cc", ich));
  459. BCL_ASSERT(ich == 4);
  460. SHOULDWORK(rString.FindLast(L"gg", ich));
  461. BCL_ASSERT(ich == 16);
  462. SHOULDWORK(rString.FindLast(L"hh", ich));
  463. BCL_ASSERT(ich == 18);
  464. SHOULDWORK(rString.FindLast(L"AA", ich));
  465. BCL_ASSERT(ich == 18);
  466. SHOULDWORK(rString.FindLast(L"BB", ich));
  467. BCL_ASSERT(ich == 18);
  468. SHOULDWORK(rString.FindLast(L"GG", ich));
  469. BCL_ASSERT(ich == 18);
  470. SHOULDWORK(rString.FindLast(L"HH", ich));
  471. BCL_ASSERT(ich == 18);
  472. SHOULDWORK(rString.FindFirstI(L"aa", BCL::CWin32CaseInsensitivityData(), ich));
  473. BCL_ASSERT(ich == 18);
  474. SHOULDWORK(rString.FindFirstI(L"bb", BCL::CWin32CaseInsensitivityData(), ich));
  475. BCL_ASSERT(ich == 0);
  476. SHOULDWORK(rString.FindFirstI(L"cc", BCL::CWin32CaseInsensitivityData(), ich));
  477. BCL_ASSERT(ich == 3);
  478. SHOULDWORK(rString.FindFirstI(L"gg", BCL::CWin32CaseInsensitivityData(), ich));
  479. BCL_ASSERT(ich == 15);
  480. SHOULDWORK(rString.FindFirstI(L"hh", BCL::CWin32CaseInsensitivityData(), ich));
  481. BCL_ASSERT(ich == 18);
  482. SHOULDWORK(rString.FindFirstI(L"AA", BCL::CWin32CaseInsensitivityData(), ich));
  483. BCL_ASSERT(ich == 18);
  484. SHOULDWORK(rString.FindFirstI(L"BB", BCL::CWin32CaseInsensitivityData(), ich));
  485. BCL_ASSERT(ich == 0);
  486. SHOULDWORK(rString.FindFirstI(L"GG", BCL::CWin32CaseInsensitivityData(), ich));
  487. BCL_ASSERT(ich == 15);
  488. SHOULDWORK(rString.FindFirstI(L"HH", BCL::CWin32CaseInsensitivityData(), ich));
  489. BCL_ASSERT(ich == 18);
  490. SHOULDWORK(rString.FindLastI(L"aa", BCL::CWin32CaseInsensitivityData(), ich));
  491. BCL_ASSERT(ich == 18);
  492. SHOULDWORK(rString.FindLastI(L"bb", BCL::CWin32CaseInsensitivityData(), ich));
  493. BCL_ASSERT(ich == 1);
  494. SHOULDWORK(rString.FindLastI(L"cc", BCL::CWin32CaseInsensitivityData(), ich));
  495. BCL_ASSERT(ich == 4);
  496. SHOULDWORK(rString.FindLastI(L"gg", BCL::CWin32CaseInsensitivityData(), ich));
  497. BCL_ASSERT(ich == 16);
  498. SHOULDWORK(rString.FindLastI(L"hh", BCL::CWin32CaseInsensitivityData(), ich));
  499. BCL_ASSERT(ich == 18);
  500. SHOULDWORK(rString.FindLastI(L"AA", BCL::CWin32CaseInsensitivityData(), ich));
  501. BCL_ASSERT(ich == 18);
  502. SHOULDWORK(rString.FindLastI(L"BB", BCL::CWin32CaseInsensitivityData(), ich));
  503. BCL_ASSERT(ich == 1);
  504. SHOULDWORK(rString.FindLastI(L"GG", BCL::CWin32CaseInsensitivityData(), ich));
  505. BCL_ASSERT(ich == 16);
  506. SHOULDWORK(rString.FindLastI(L"HH", BCL::CWin32CaseInsensitivityData(), ich));
  507. BCL_ASSERT(ich == 18);
  508. SHOULDWORK(rString.FindFirstILI(L"aa", ich));
  509. BCL_ASSERT(ich == 18);
  510. SHOULDWORK(rString.FindFirstILI(L"bb", ich));
  511. BCL_ASSERT(ich == 0);
  512. SHOULDWORK(rString.FindFirstILI(L"cc", ich));
  513. BCL_ASSERT(ich == 3);
  514. SHOULDWORK(rString.FindFirstILI(L"gg", ich));
  515. BCL_ASSERT(ich == 15);
  516. SHOULDWORK(rString.FindFirstILI(L"hh", ich));
  517. BCL_ASSERT(ich == 18);
  518. SHOULDWORK(rString.FindFirstILI(L"AA", ich));
  519. BCL_ASSERT(ich == 18);
  520. SHOULDWORK(rString.FindFirstILI(L"BB", ich));
  521. BCL_ASSERT(ich == 0);
  522. SHOULDWORK(rString.FindFirstILI(L"GG", ich));
  523. BCL_ASSERT(ich == 15);
  524. SHOULDWORK(rString.FindFirstILI(L"HH", ich));
  525. BCL_ASSERT(ich == 18);
  526. SHOULDWORK(rString.FindLastILI(L"aa", ich));
  527. BCL_ASSERT(ich == 18);
  528. SHOULDWORK(rString.FindLastILI(L"bb", ich));
  529. BCL_ASSERT(ich == 1);
  530. SHOULDWORK(rString.FindLastILI(L"cc", ich));
  531. BCL_ASSERT(ich == 4);
  532. SHOULDWORK(rString.FindLastILI(L"gg", ich));
  533. BCL_ASSERT(ich == 16);
  534. SHOULDWORK(rString.FindLastILI(L"hh", ich));
  535. BCL_ASSERT(ich == 18);
  536. SHOULDWORK(rString.FindLastILI(L"AA", ich));
  537. BCL_ASSERT(ich == 18);
  538. SHOULDWORK(rString.FindLastILI(L"BB", ich));
  539. BCL_ASSERT(ich == 1);
  540. SHOULDWORK(rString.FindLastILI(L"GG", ich));
  541. BCL_ASSERT(ich == 16);
  542. SHOULDWORK(rString.FindLastILI(L"HH", ich));
  543. BCL_ASSERT(ich == 18);
  544. }
  545. template <typename TStringClass>
  546. void
  547. DoSpanChecks(
  548. TStringClass &rString
  549. )
  550. {
  551. SIZE_T ich;
  552. bool fContains;
  553. SHOULDWORK(rString.Assign(L"bbbcccdddeeefffggg"));
  554. CHECK(rString, L"bbbcccdddeeefffggg");
  555. SHOULDWORK(rString.Span(L"a", ich));
  556. BCL_ASSERT(ich == 0);
  557. SHOULDWORK(rString.Span(L"abc", ich));
  558. BCL_ASSERT(ich == 6);
  559. SHOULDWORK(rString.Span(L"abcdefg", ich));
  560. BCL_ASSERT(ich == 18);
  561. SHOULDWORK(rString.Span(L"", ich));
  562. BCL_ASSERT(ich == 0);
  563. SHOULDWORK(rString.Span(L"A", ich));
  564. BCL_ASSERT(ich == 0);
  565. SHOULDWORK(rString.Span(L"ABC", ich));
  566. BCL_ASSERT(ich == 0);
  567. SHOULDWORK(rString.Span(L"ABCDEFG", ich));
  568. BCL_ASSERT(ich == 0);
  569. SHOULDWORK(rString.Span(L"", ich));
  570. BCL_ASSERT(ich == 0);
  571. SHOULDWORK(rString.ComplementSpan(L"a", ich));
  572. BCL_ASSERT(ich == 18);
  573. SHOULDWORK(rString.ComplementSpan(L"abc", ich));
  574. BCL_ASSERT(ich == 0);
  575. SHOULDWORK(rString.ComplementSpan(L"efg", ich));
  576. BCL_ASSERT(ich == 9);
  577. SHOULDWORK(rString.ComplementSpan(L"abcdefg", ich));
  578. BCL_ASSERT(ich == 0);
  579. SHOULDWORK(rString.ComplementSpan(L"", ich));
  580. BCL_ASSERT(ich == 18);
  581. SHOULDWORK(rString.ComplementSpan(L"A", ich));
  582. BCL_ASSERT(ich == 18);
  583. SHOULDWORK(rString.ComplementSpan(L"ABC", ich));
  584. BCL_ASSERT(ich == 18);
  585. SHOULDWORK(rString.ComplementSpan(L"ABCDEFG", ich));
  586. BCL_ASSERT(ich == 18);
  587. SHOULDWORK(rString.ComplementSpan(L"", ich));
  588. BCL_ASSERT(ich == 18);
  589. SHOULDWORK(rString.SpanILI(L"a", ich));
  590. BCL_ASSERT(ich == 0);
  591. SHOULDWORK(rString.SpanILI(L"abc", ich));
  592. BCL_ASSERT(ich == 6);
  593. SHOULDWORK(rString.SpanILI(L"abcdefg", ich));
  594. BCL_ASSERT(ich == 18);
  595. SHOULDWORK(rString.SpanILI(L"", ich));
  596. BCL_ASSERT(ich == 0);
  597. SHOULDWORK(rString.SpanILI(L"A", ich));
  598. BCL_ASSERT(ich == 0);
  599. SHOULDWORK(rString.SpanILI(L"ABC", ich));
  600. BCL_ASSERT(ich == 6);
  601. SHOULDWORK(rString.SpanILI(L"ABCDEFG", ich));
  602. BCL_ASSERT(ich == 18);
  603. SHOULDWORK(rString.SpanILI(L"", ich));
  604. BCL_ASSERT(ich == 0);
  605. SHOULDWORK(rString.ComplementSpanILI(L"a", ich));
  606. BCL_ASSERT(ich == 18);
  607. SHOULDWORK(rString.ComplementSpanILI(L"abc", ich));
  608. BCL_ASSERT(ich == 0);
  609. SHOULDWORK(rString.ComplementSpanILI(L"efg", ich));
  610. BCL_ASSERT(ich == 9);
  611. SHOULDWORK(rString.ComplementSpanILI(L"abcdefg", ich));
  612. BCL_ASSERT(ich == 0);
  613. SHOULDWORK(rString.ComplementSpanILI(L"", ich));
  614. BCL_ASSERT(ich == 18);
  615. SHOULDWORK(rString.ComplementSpanILI(L"A", ich));
  616. BCL_ASSERT(ich == 18);
  617. SHOULDWORK(rString.ComplementSpanILI(L"ABC", ich));
  618. BCL_ASSERT(ich == 0);
  619. SHOULDWORK(rString.ComplementSpanILI(L"ABCDEFG", ich));
  620. BCL_ASSERT(ich == 0);
  621. SHOULDWORK(rString.ComplementSpanILI(L"", ich));
  622. BCL_ASSERT(ich == 18);
  623. SHOULDWORK(rString.ReverseSpan(L"a", ich));
  624. BCL_ASSERT(ich == 18);
  625. SHOULDWORK(rString.ReverseSpan(L"abc", ich));
  626. BCL_ASSERT(ich == 18);
  627. SHOULDWORK(rString.ReverseSpan(L"fgh", ich));
  628. BCL_ASSERT(ich == 12);
  629. SHOULDWORK(rString.ReverseSpan(L"abcdefg", ich));
  630. BCL_ASSERT(ich == 0);
  631. SHOULDWORK(rString.ReverseSpan(L"", ich));
  632. BCL_ASSERT(ich == 18);
  633. SHOULDWORK(rString.ReverseSpan(L"A", ich));
  634. BCL_ASSERT(ich == 18);
  635. SHOULDWORK(rString.ReverseSpan(L"ABC", ich));
  636. BCL_ASSERT(ich == 18);
  637. SHOULDWORK(rString.ReverseSpan(L"FGH", ich));
  638. BCL_ASSERT(ich == 18);
  639. SHOULDWORK(rString.ReverseSpan(L"ABCDEFG", ich));
  640. BCL_ASSERT(ich == 18);
  641. SHOULDWORK(rString.ReverseSpan(L"", ich));
  642. BCL_ASSERT(ich == 18);
  643. SHOULDWORK(rString.ReverseComplementSpan(L"a", ich));
  644. BCL_ASSERT(ich == 0);
  645. SHOULDWORK(rString.ReverseComplementSpan(L"abc", ich));
  646. BCL_ASSERT(ich == 5);
  647. SHOULDWORK(rString.ReverseComplementSpan(L"efg", ich));
  648. BCL_ASSERT(ich == 17);
  649. SHOULDWORK(rString.ReverseComplementSpan(L"abcdefg", ich));
  650. BCL_ASSERT(ich == 17);
  651. SHOULDWORK(rString.ReverseComplementSpan(L"", ich));
  652. BCL_ASSERT(ich == 0);
  653. SHOULDWORK(rString.ReverseComplementSpan(L"A", ich));
  654. BCL_ASSERT(ich == 0);
  655. SHOULDWORK(rString.ReverseComplementSpan(L"ABC", ich));
  656. BCL_ASSERT(ich == 0);
  657. SHOULDWORK(rString.ReverseComplementSpan(L"ABCDEFG", ich));
  658. BCL_ASSERT(ich == 0);
  659. SHOULDWORK(rString.ReverseComplementSpan(L"", ich));
  660. BCL_ASSERT(ich == 0);
  661. SHOULDWORK(rString.ReverseSpanILI(L"a", ich));
  662. BCL_ASSERT(ich == 18);
  663. SHOULDWORK(rString.ReverseSpanILI(L"abc", ich));
  664. BCL_ASSERT(ich == 18);
  665. SHOULDWORK(rString.ReverseSpanILI(L"abcdefg", ich));
  666. BCL_ASSERT(ich == 0);
  667. SHOULDWORK(rString.ReverseSpanILI(L"", ich));
  668. BCL_ASSERT(ich == 18);
  669. SHOULDWORK(rString.ReverseSpanILI(L"A", ich));
  670. BCL_ASSERT(ich == 18);
  671. SHOULDWORK(rString.ReverseSpanILI(L"ABC", ich));
  672. BCL_ASSERT(ich == 18);
  673. SHOULDWORK(rString.ReverseSpanILI(L"ABCDEFG", ich));
  674. BCL_ASSERT(ich == 0);
  675. SHOULDWORK(rString.ReverseSpanILI(L"", ich));
  676. BCL_ASSERT(ich == 18);
  677. SHOULDWORK(rString.ReverseComplementSpanILI(L"a", ich));
  678. BCL_ASSERT(ich == 0);
  679. SHOULDWORK(rString.ReverseComplementSpanILI(L"abc", ich));
  680. BCL_ASSERT(ich == 5);
  681. SHOULDWORK(rString.ReverseComplementSpanILI(L"efg", ich));
  682. BCL_ASSERT(ich == 17);
  683. SHOULDWORK(rString.ReverseComplementSpanILI(L"abcdefg", ich));
  684. BCL_ASSERT(ich == 17);
  685. SHOULDWORK(rString.ReverseComplementSpanILI(L"", ich));
  686. BCL_ASSERT(ich == 0);
  687. SHOULDWORK(rString.ReverseComplementSpanILI(L"A", ich));
  688. BCL_ASSERT(ich == 0);
  689. SHOULDWORK(rString.ReverseComplementSpanILI(L"ABC", ich));
  690. BCL_ASSERT(ich == 5);
  691. SHOULDWORK(rString.ReverseComplementSpanILI(L"ABCDEFG", ich));
  692. BCL_ASSERT(ich == 17);
  693. SHOULDWORK(rString.ReverseComplementSpanILI(L"", ich));
  694. BCL_ASSERT(ich == 0);
  695. }
  696. template <typename TStringClass>
  697. void
  698. DoNonNativeInChecks(
  699. TStringClass &rString
  700. )
  701. {
  702. WCHAR rgwch[80];
  703. BCL::CWin32MBCSToUnicodeDataIn datain;
  704. BCL::CWin32MBCSToUnicodeDataOut dataout;
  705. SIZE_T cchWritten;
  706. datain.m_CodePage = CP_ACP;
  707. datain.m_dwFlags = MB_PRECOMPOSED;
  708. SHOULDWORK(rString.Assign(datain, "Foo", dataout));
  709. CHECK(rString, L"Foo");
  710. SHOULDWORK(rString.AssignACP("Foo!"));
  711. CHECK(rString, L"Foo!");
  712. // EBCDIC? Yes, EBCDIC...
  713. const unsigned char rgABCInEBCDIC[] = { 0x81, 0x82, 0x83, 0 };
  714. datain.m_CodePage = 37;
  715. SHOULDWORK(rString.Assign(datain, (PSTR) rgABCInEBCDIC, dataout));
  716. CHECK(rString, L"abc");
  717. SHOULDWORK(rString.Assign(datain, (PSTR) rgABCInEBCDIC, 3, dataout));
  718. CHECK(rString, L"abc");
  719. // Let's try Hangul
  720. datain.m_CodePage = 1361;
  721. // const unsigned char rgHangul[] = { 0x88, 0xd0, 0x88, 0xd1, 0x88, 0xd2, 0x88, 0xd3, 0 };
  722. const unsigned char rgHangul[] = { 0x84, 0x42, 0x85, 0xa1, 0 };
  723. SHOULDWORK(rString.Assign(datain, (PSTR) rgHangul, dataout));
  724. SHOULDWORK(rString.CopyOut(rgwch, BCL_NUMBER_OF(rgwch), cchWritten));
  725. BCL_ASSERT(cchWritten == 2);
  726. BCL_ASSERT(rgwch[0] == 0x11a8);
  727. BCL_ASSERT(rgwch[1] == 0x1169);
  728. BCL_ASSERT(rgwch[2] == 0);
  729. }
  730. template <typename TStringClass>
  731. void
  732. DoNonNativeOutChecks(
  733. TStringClass &rString
  734. )
  735. {
  736. CHAR rgch[80];
  737. BCL::CWin32UnicodeToMBCSDataIn datain;
  738. BCL::CWin32UnicodeToMBCSDataOut dataout;
  739. SIZE_T cchWritten;
  740. PSTR psz = NULL;
  741. SHOULDWORK(rString.Assign(L"Foo"));
  742. CHECK(rString, L"Foo");
  743. datain.m_CodePage = CP_ACP;
  744. datain.m_dwFlags = 0;
  745. dataout.m_lpDefaultChar = NULL;
  746. dataout.m_lpUsedDefaultChar = NULL;
  747. SHOULDWORK(rString.CopyOut(datain, rgch, BCL_NUMBER_OF(rgch), dataout, cchWritten));
  748. BCL_ASSERT(cchWritten == 3);
  749. BCL_ASSERT(rgch[0] == 'F');
  750. BCL_ASSERT(rgch[1] == 'o');
  751. BCL_ASSERT(rgch[2] == 'o');
  752. BCL_ASSERT(rgch[3] == 0);
  753. SHOULDWORK(rString.CopyOutACP(rgch, BCL_NUMBER_OF(rgch), cchWritten));
  754. BCL_ASSERT(cchWritten == 3);
  755. BCL_ASSERT(rgch[0] == 'F');
  756. BCL_ASSERT(rgch[1] == 'o');
  757. BCL_ASSERT(rgch[2] == 'o');
  758. BCL_ASSERT(rgch[3] == 0);
  759. SHOULDFAIL(rString.CopyOut(datain, rgch, 0, dataout, cchWritten), ERROR_BUFFER_OVERFLOW);
  760. SHOULDFAIL(rString.CopyOut(datain, rgch, 1, dataout, cchWritten), ERROR_BUFFER_OVERFLOW);
  761. SHOULDFAIL(rString.CopyOut(datain, rgch, 2, dataout, cchWritten), ERROR_BUFFER_OVERFLOW);
  762. SHOULDFAIL(rString.CopyOut(datain, rgch, 3, dataout, cchWritten), ERROR_BUFFER_OVERFLOW);
  763. SHOULDWORK(rString.CopyOut(datain, psz, dataout, cchWritten));
  764. BCL_ASSERT(cchWritten == 3);
  765. BCL_ASSERT(
  766. (psz != NULL) &&
  767. (psz[0] == 'F') &&
  768. (psz[1] == 'o') &&
  769. (psz[2] == 'o') &&
  770. (psz[3] == 0));
  771. ::HeapFree(::GetProcessHeap(), 0, psz);
  772. psz = NULL;
  773. SHOULDWORK(rString.CopyOutACP(psz, cchWritten));
  774. BCL_ASSERT(cchWritten == 3);
  775. BCL_ASSERT(
  776. (psz != NULL) &&
  777. (psz[0] == 'F') &&
  778. (psz[1] == 'o') &&
  779. (psz[2] == 'o') &&
  780. (psz[3] == 0));
  781. ::HeapFree(::GetProcessHeap(), 0, psz);
  782. psz = NULL;
  783. }
  784. template <typename TStringClass>
  785. void
  786. DoChecks(
  787. TStringClass &rString,
  788. DWORD dwMassiveStringErrorCode
  789. )
  790. {
  791. bool fEquals;
  792. int iComparisonResult;
  793. SIZE_T cchExtra;
  794. BCL::CWin32CaseInsensitivityData cidTurkish(MAKELCID(MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT), SORT_DEFAULT), LCMAP_LINGUISTIC_CASING);
  795. BCL::CWin32CaseInsensitivityData cidGerman(MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT));
  796. BCL::CWin32CaseInsensitivityData cidFrench(MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_SWISS), SORT_DEFAULT));
  797. BCL::CWin32CaseInsensitivityData cidUKEnglish(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), SORT_DEFAULT));
  798. BCL::CWin32CaseInsensitivityData cidUSEnglish(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
  799. SHOULDWORK(rString.Assign(L"hello", 5));
  800. CHECK(rString, L"hello");
  801. SHOULDWORK(rString.Append(L" there", 6));
  802. CHECK(rString, L"hello there");
  803. SHOULDWORK(rString.Prepend(L"Why ", 4));
  804. CHECK(rString, L"Why hello there");
  805. SHOULDWORK(rString.Prepend(L'_'));
  806. CHECK(rString, L"_Why hello there");
  807. rString.Clear();
  808. CHECK(rString, L"");
  809. SHOULDWORK(rString.AppendFill(L'x', 10, cchExtra));
  810. CHECK(rString, L"xxxxxxxxxx");
  811. BCL_ASSERT(cchExtra == 0);
  812. SHOULDWORK(rString.AssignFill(L'x', 10, cchExtra));
  813. CHECK(rString, L"xxxxxxxxxx");
  814. BCL_ASSERT(cchExtra == 0);
  815. SHOULDWORK(rString.AppendFill(L'y', 10, cchExtra));
  816. CHECK(rString, L"xxxxxxxxxx");
  817. BCL_ASSERT(cchExtra == 0);
  818. SHOULDWORK(rString.AppendFill(L'y', 20, cchExtra));
  819. CHECK(rString, L"xxxxxxxxxxyyyyyyyyyy");
  820. BCL_ASSERT(cchExtra == 0);
  821. rString.Clear();
  822. CHECK(rString, L"");
  823. SHOULDWORK(rString.AppendFill(L"xx", 10, cchExtra));
  824. CHECK(rString, L"xxxxxxxxxx");
  825. BCL_ASSERT(cchExtra == 0);
  826. SHOULDWORK(rString.AssignFill(L"xx", 10, cchExtra));
  827. CHECK(rString, L"xxxxxxxxxx");
  828. BCL_ASSERT(cchExtra == 0);
  829. SHOULDWORK(rString.AppendFill(L"yy", 10, cchExtra));
  830. CHECK(rString, L"xxxxxxxxxx");
  831. BCL_ASSERT(cchExtra == 0);
  832. SHOULDWORK(rString.AppendFill(L"yy", 20, cchExtra));
  833. CHECK(rString, L"xxxxxxxxxxyyyyyyyyyy");
  834. BCL_ASSERT(cchExtra == 0);
  835. rString.Clear();
  836. CHECK(rString, L"");
  837. SHOULDWORK(rString.AppendFill(L"x1", 10, cchExtra));
  838. CHECK(rString, L"x1x1x1x1x1");
  839. BCL_ASSERT(cchExtra == 0);
  840. SHOULDWORK(rString.AssignFill(L"x2", 10, cchExtra));
  841. CHECK(rString, L"x2x2x2x2x2");
  842. BCL_ASSERT(cchExtra == 0);
  843. SHOULDWORK(rString.AppendFill(L"y3", 10, cchExtra));
  844. CHECK(rString, L"x2x2x2x2x2");
  845. BCL_ASSERT(cchExtra == 0);
  846. SHOULDWORK(rString.AppendFill(L"y4", 20, cchExtra));
  847. CHECK(rString, L"x2x2x2x2x2y4y4y4y4y4");
  848. BCL_ASSERT(cchExtra == 0);
  849. SHOULDWORK(rString.Assign(L"12345"));
  850. CHECK(rString, L"12345");
  851. SHOULDWORK(rString.AppendFill(L"67890", 7, cchExtra));
  852. CHECK(rString, L"12345");
  853. BCL_ASSERT(cchExtra == 2);
  854. SHOULDWORK(rString.AppendFill(L"67890", 12, cchExtra));
  855. CHECK(rString, L"1234567890");
  856. BCL_ASSERT(cchExtra == 2);
  857. SHOULDWORK(rString.AssignFill(L"12345", 3, cchExtra));
  858. CHECK(rString, L"");
  859. BCL_ASSERT(cchExtra == 3);
  860. SHOULDWORK(rString.AssignFill(L"12345", 8, cchExtra));
  861. CHECK(rString, L"12345");
  862. BCL_ASSERT(cchExtra == 3);
  863. SHOULDWORK(rString.AssignFill(L"12345", 13, cchExtra));
  864. CHECK(rString, L"1234512345");
  865. BCL_ASSERT(cchExtra == 3);
  866. rString.Clear();
  867. CHECK(rString, L"");
  868. SHOULDWORK(rString.AppendFill(L"xx", 2, 10, cchExtra));
  869. CHECK(rString, L"xxxxxxxxxx");
  870. BCL_ASSERT(cchExtra == 0);
  871. SHOULDWORK(rString.AssignFill(L"xx", 2, 10, cchExtra));
  872. CHECK(rString, L"xxxxxxxxxx");
  873. BCL_ASSERT(cchExtra == 0);
  874. SHOULDWORK(rString.AppendFill(L"yy", 2, 10, cchExtra));
  875. CHECK(rString, L"xxxxxxxxxx");
  876. BCL_ASSERT(cchExtra == 0);
  877. SHOULDWORK(rString.AppendFill(L"yy", 2, 20, cchExtra));
  878. CHECK(rString, L"xxxxxxxxxxyyyyyyyyyy");
  879. BCL_ASSERT(cchExtra == 0);
  880. rString.Clear();
  881. CHECK(rString, L"");
  882. SHOULDWORK(rString.AppendFill(L"x1", 2, 10, cchExtra));
  883. CHECK(rString, L"x1x1x1x1x1");
  884. BCL_ASSERT(cchExtra == 0);
  885. SHOULDWORK(rString.AssignFill(L"x2", 2, 10, cchExtra));
  886. CHECK(rString, L"x2x2x2x2x2");
  887. BCL_ASSERT(cchExtra == 0);
  888. SHOULDWORK(rString.AppendFill(L"y3", 2, 10, cchExtra));
  889. CHECK(rString, L"x2x2x2x2x2");
  890. BCL_ASSERT(cchExtra == 0);
  891. SHOULDWORK(rString.AppendFill(L"y4", 2, 20, cchExtra));
  892. CHECK(rString, L"x2x2x2x2x2y4y4y4y4y4");
  893. BCL_ASSERT(cchExtra == 0);
  894. SHOULDWORK(rString.Assign(L"12345", 5));
  895. CHECK(rString, L"12345");
  896. SHOULDWORK(rString.AppendFill(L"67890", 5, 7, cchExtra));
  897. CHECK(rString, L"12345");
  898. BCL_ASSERT(cchExtra == 2);
  899. SHOULDWORK(rString.AppendFill(L"67890", 5, 12, cchExtra));
  900. CHECK(rString, L"1234567890");
  901. BCL_ASSERT(cchExtra == 2);
  902. SHOULDWORK(rString.AssignFill(L"12345", 5, 3, cchExtra));
  903. CHECK(rString, L"");
  904. BCL_ASSERT(cchExtra == 3);
  905. SHOULDWORK(rString.AssignFill(L"12345", 5, 8, cchExtra));
  906. CHECK(rString, L"12345");
  907. BCL_ASSERT(cchExtra == 3);
  908. SHOULDWORK(rString.AssignFill(L"12345", 5, 13, cchExtra));
  909. CHECK(rString, L"1234512345");
  910. BCL_ASSERT(cchExtra == 3);
  911. rString.Clear();
  912. CHECK(rString, L"");
  913. SHOULDWORK(rString.AppendFill(L"xxy", 2, 10, cchExtra));
  914. CHECK(rString, L"xxxxxxxxxx");
  915. BCL_ASSERT(cchExtra == 0);
  916. SHOULDWORK(rString.AssignFill(L"xxz", 2, 10, cchExtra));
  917. CHECK(rString, L"xxxxxxxxxx");
  918. BCL_ASSERT(cchExtra == 0);
  919. SHOULDWORK(rString.AppendFill(L"yya", 2, 10, cchExtra));
  920. CHECK(rString, L"xxxxxxxxxx");
  921. BCL_ASSERT(cchExtra == 0);
  922. SHOULDWORK(rString.AppendFill(L"yya", 2, 20, cchExtra));
  923. CHECK(rString, L"xxxxxxxxxxyyyyyyyyyy");
  924. BCL_ASSERT(cchExtra == 0);
  925. rString.Clear();
  926. CHECK(rString, L"");
  927. SHOULDWORK(rString.AppendFill(L"x1d", 2, 10, cchExtra));
  928. CHECK(rString, L"x1x1x1x1x1");
  929. BCL_ASSERT(cchExtra == 0);
  930. SHOULDWORK(rString.AssignFill(L"x2d", 2, 10, cchExtra));
  931. CHECK(rString, L"x2x2x2x2x2");
  932. BCL_ASSERT(cchExtra == 0);
  933. SHOULDWORK(rString.AppendFill(L"y3d", 2, 10, cchExtra));
  934. CHECK(rString, L"x2x2x2x2x2");
  935. BCL_ASSERT(cchExtra == 0);
  936. SHOULDWORK(rString.AppendFill(L"y4d", 2, 20, cchExtra));
  937. CHECK(rString, L"x2x2x2x2x2y4y4y4y4y4");
  938. BCL_ASSERT(cchExtra == 0);
  939. SHOULDWORK(rString.Assign(L"12345", 5));
  940. CHECK(rString, L"12345");
  941. SHOULDWORK(rString.AppendFill(L"67890xxx", 5, 7, cchExtra));
  942. CHECK(rString, L"12345");
  943. BCL_ASSERT(cchExtra == 2);
  944. SHOULDWORK(rString.AppendFill(L"67890xxx", 5, 12, cchExtra));
  945. CHECK(rString, L"1234567890");
  946. BCL_ASSERT(cchExtra == 2);
  947. SHOULDWORK(rString.AssignFill(L"12345xxx", 5, 3, cchExtra));
  948. CHECK(rString, L"");
  949. BCL_ASSERT(cchExtra == 3);
  950. SHOULDWORK(rString.AssignFill(L"12345xxx", 5, 8, cchExtra));
  951. CHECK(rString, L"12345");
  952. BCL_ASSERT(cchExtra == 3);
  953. SHOULDWORK(rString.AssignFill(L"12345xxx", 5, 13, cchExtra));
  954. CHECK(rString, L"1234512345");
  955. BCL_ASSERT(cchExtra == 3);
  956. SHOULDWORK(rString.AssignRepeat(L"abc", 5));
  957. CHECK(rString, L"abcabcabcabcabc");
  958. SHOULDWORK(rString.AppendRepeat(L"def", 5));
  959. CHECK(rString, L"abcabcabcabcabcdefdefdefdefdef");
  960. SHOULDWORK(rString.AssignRepeat(L"abc", 0));
  961. CHECK(rString, L"");
  962. SHOULDWORK(rString.AppendRepeat(L"def", 0));
  963. CHECK(rString, L"");
  964. SHOULDWORK(rString.AssignRepeat(L"abc", 3, 5));
  965. CHECK(rString, L"abcabcabcabcabc");
  966. SHOULDWORK(rString.AppendRepeat(L"def", 3, 5));
  967. CHECK(rString, L"abcabcabcabcabcdefdefdefdefdef");
  968. SHOULDWORK(rString.AssignRepeat(L"abc", 3, 0));
  969. CHECK(rString, L"");
  970. SHOULDWORK(rString.AppendRepeat(L"def", 3, 0));
  971. CHECK(rString, L"");
  972. SHOULDWORK(rString.AssignRepeat(L"abc", 0, 5));
  973. CHECK(rString, L"");
  974. SHOULDWORK(rString.AppendRepeat(L"def", 0, 5));
  975. CHECK(rString, L"");
  976. SHOULDWORK(rString.AssignRepeat(L"abc", 0, 0));
  977. CHECK(rString, L"");
  978. SHOULDWORK(rString.AppendRepeat(L"def", 0, 0));
  979. CHECK(rString, L"");
  980. SHOULDWORK(rString.AssignRepeat(L'a', 5));
  981. CHECK(rString, L"aaaaa");
  982. SHOULDWORK(rString.AppendRepeat(L'd', 5));
  983. CHECK(rString, L"aaaaaddddd");
  984. SHOULDWORK(rString.AssignRepeat(L'a', 0));
  985. CHECK(rString, L"");
  986. SHOULDWORK(rString.AppendRepeat(L'd', 0));
  987. CHECK(rString, L"");
  988. SHOULDWORK(rString.Assign(L"1234512345"));
  989. CHECK(rString, L"1234512345");
  990. SHOULDFAIL(rString.Assign(3, L"hello there", INT_MAX, L"hi again", INT_MAX, L"Still me", INT_MAX), ERROR_ARITHMETIC_OVERFLOW);
  991. CHECK(rString, L"1234512345");
  992. SHOULDWORK(rString.Assign(3, L"hello there", -1, L"hi again", -1, L"Still me", -1));
  993. CHECK(rString, L"hello therehi againStill me");
  994. SHOULDWORK(rString.Assign(5, L"foo", 3, L"bar", 3, L"baz", 3, L"eieio", 5, L"mumble", 6));
  995. CHECK(rString, L"foobarbazeieiomumble");
  996. SHOULDWORK(rString.Equals(L"hello there", 11, fEquals));
  997. BCL_ASSERT(!fEquals);
  998. SHOULDWORK(rString.Equals(L"foobarbazeieiomumble", 20, fEquals));
  999. BCL_ASSERT(fEquals);
  1000. SHOULDWORK(rString.Equals(L"FooBarBazEieioMumble", 20, fEquals));
  1001. BCL_ASSERT(!fEquals);
  1002. SHOULDWORK(rString.EqualsI(L"hello there", 11, BCL::CWin32CaseInsensitivityData(), fEquals));
  1003. BCL_ASSERT(!fEquals);
  1004. SHOULDWORK(rString.EqualsILI(L"foobarbazeieiomumble", 20, fEquals));
  1005. BCL_ASSERT(fEquals);
  1006. SHOULDWORK(rString.EqualsILI(L"foobarbazeieio", 14, fEquals));
  1007. BCL_ASSERT(!fEquals);
  1008. SHOULDWORK(rString.EqualsILI(L"foobarbazeieiomumblexyz", 23, fEquals));
  1009. BCL_ASSERT(!fEquals);
  1010. SHOULDWORK(rString.EqualsILI(L"FooBarBazEieioMumble", 20, fEquals));
  1011. BCL_ASSERT(fEquals);
  1012. SHOULDWORK(rString.Compare(L"foo", 3, iComparisonResult));
  1013. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  1014. SHOULDWORK(rString.Compare(L"foozle", 6, iComparisonResult));
  1015. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  1016. SHOULDWORK(rString.CompareI(L"FOO", 3, cidUSEnglish, iComparisonResult));
  1017. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  1018. SHOULDWORK(rString.CompareI(L"FOOZLE", 6, BCL::CWin32CaseInsensitivityData(), iComparisonResult));
  1019. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  1020. SHOULDWORK(rString.CompareILI(L"foobarbazeieiomumble", 20, iComparisonResult));
  1021. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  1022. SHOULDWORK(rString.CompareILI(L"foobarbazeieio", 14, iComparisonResult));
  1023. BCL_ASSERT(iComparisonResult == CSTR_GREATER_THAN);
  1024. SHOULDWORK(rString.CompareILI(L"foobarbazeieiomumblexyz", 23, iComparisonResult));
  1025. BCL_ASSERT(iComparisonResult == CSTR_LESS_THAN);
  1026. SHOULDWORK(rString.CompareILI(L"FooBarBazEieioMumble", 20, iComparisonResult));
  1027. BCL_ASSERT(iComparisonResult == CSTR_EQUAL);
  1028. rString.Clear();
  1029. for (ULONG i=0; i<1000; i++)
  1030. {
  1031. if (!rString.Append(L"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"))
  1032. {
  1033. const DWORD dwLastError = ::GetLastError();
  1034. BCL_ASSERT(dwLastError == dwMassiveStringErrorCode);
  1035. break;
  1036. }
  1037. }
  1038. SHOULDFAIL(rString.Assign(L"hello", 1 << 30), dwMassiveStringErrorCode);
  1039. SHOULDFAIL(rString.Assign(L"hello", 0xffffffff), ERROR_ARITHMETIC_OVERFLOW);
  1040. // Do it again without lengths...
  1041. SHOULDWORK(rString.Assign(L"hello"));
  1042. CHECK(rString, L"hello");
  1043. SHOULDWORK(rString.Append(L" there"));
  1044. CHECK(rString, L"hello there");
  1045. SHOULDWORK(rString.Prepend(L"Why "));
  1046. CHECK(rString, L"Why hello there");
  1047. rString.Clear();
  1048. CHECK(rString, L"");
  1049. SHOULDWORK(rString.Assign(5, L"foo", 3, L"bar", 3, L"baz", 3, L"eieio", 5, L"mumble", 6));
  1050. CHECK(rString, L"foobarbazeieiomumble");
  1051. DoCheckCaseInsensitiveComparisons(rString);
  1052. DoCheckCaseSensitiveComparisons(rString);
  1053. SHOULDWORK(rString.Assign(L"MixedCase"));
  1054. CHECK(rString, L"MixedCase");
  1055. SHOULDWORK(rString.Assign(L"MixedCase"));
  1056. CHECK(rString, L"MixedCase");
  1057. SHOULDWORK(rString.UpperCase(cidUSEnglish));
  1058. CHECK(rString, L"MIXEDCASE");
  1059. SHOULDWORK(rString.Assign(L"MixedCase"));
  1060. CHECK(rString, L"MixedCase");
  1061. SHOULDWORK(rString.LowerCase(BCL::CWin32CaseInsensitivityData()));
  1062. CHECK(rString, L"mixedcase");
  1063. // Let's make that Turkish I thing happen...
  1064. SHOULDWORK(rString.Assign(L"IxedCase"));
  1065. CHECK(rString, L"IxedCase");
  1066. SHOULDWORK(rString.LowerCase(cidTurkish));
  1067. CHECK(rString, L"\x0131xedcase");
  1068. SHOULDWORK(rString.Assign(L"MixedCase"));
  1069. CHECK(rString, L"MixedCase");
  1070. SHOULDWORK(rString.UpperCaseILI());
  1071. CHECK(rString, L"MIXEDCASE");
  1072. SHOULDWORK(rString.Assign(L"MixedCase"));
  1073. CHECK(rString, L"MixedCase");
  1074. SHOULDWORK(rString.LoweCaseILI());
  1075. CHECK(rString, L"mixedcase");
  1076. SHOULDWORK(rString.Assign(L"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"));
  1077. CHECK(rString, L"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789");
  1078. // verify behavior for shrinking buffer
  1079. SHOULDWORK(rString.Assign(L"0123456789"));
  1080. CHECK(rString, L"0123456789");
  1081. DoCheckCharacterFinding(rString);
  1082. DoCheckStringFinding(rString);
  1083. DoSpanChecks(rString);
  1084. DoNonNativeInChecks(rString);
  1085. DoNonNativeOutChecks(rString);
  1086. }
  1087. __declspec(noinline)
  1088. void DoCaseStuff()
  1089. {
  1090. ULONG i, j;
  1091. FILE *f = fopen("results.txt", "w");
  1092. if (f == NULL)
  1093. {
  1094. perror("Failed to open results.txt");
  1095. return;
  1096. }
  1097. WCHAR *rgwchSource = new WCHAR[65536];
  1098. WCHAR *rgwchUpper = new WCHAR[65536];
  1099. WCHAR *rgwchLower = new WCHAR[65536];
  1100. for (i=0; i<65536; i++)
  1101. rgwchSource[i] = (WCHAR) i;
  1102. for (i=0; i<65536; i++)
  1103. {
  1104. if (::LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, &rgwchSource[i], 1, &rgwchUpper[i], 1) == 0)
  1105. {
  1106. fprintf(f, "Uppercase mapping of U+%04x failed; GetLastError() = %d\n", rgwchSource[i], ::GetLastError());
  1107. rgwchUpper[i] = 0xffff;
  1108. }
  1109. if (::LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, &rgwchSource[i], 1, &rgwchLower[i], 1) == 0)
  1110. {
  1111. fprintf(f, "Uppercase mapping of U+%04x failed; GetLastError() = %d\n", rgwchSource[i], ::GetLastError());
  1112. rgwchLower[i] = 0xffff;
  1113. }
  1114. }
  1115. fprintf(f, "\nUpper case mappings follow:\n");
  1116. for (i=0; i<65536; i++)
  1117. {
  1118. if (rgwchUpper[i] != i)
  1119. fprintf(f, "U+%04x -> U+%04x\n", i, rgwchUpper[i]);
  1120. }
  1121. fprintf(f, "\nLower case mappings follow:\n");
  1122. for (i=0; i<65536; i++)
  1123. {
  1124. if (rgwchLower[i] != i)
  1125. fprintf(f, "U+%04x -> U+%04x\n", i, rgwchLower[i]);
  1126. }
  1127. fprintf(f, "\nUpper case mappings where LCMapString disagrees with CharUpper:\nOrig, LCMapString, CharUpper\n");
  1128. for (i=0; i<65536; i++)
  1129. {
  1130. if (((WCHAR) CharUpperW((LPWSTR) i)) != rgwchUpper[i])
  1131. fprintf(f, "U+%04x,U+%04x,U+%04x\n", i, rgwchUpper[i], (WCHAR) CharUpperW((LPWSTR) i));
  1132. }
  1133. fprintf(f, "\nLower case mappings where LCMapString disagrees with CharLower:\nOrig, LCMapString, CharLower\n");
  1134. for (i=0; i<65536; i++)
  1135. {
  1136. if (((WCHAR) CharLowerW((LPWSTR) i)) != rgwchLower[i])
  1137. fprintf(f, "U+%04x,U+%04x,U+%04x\n", i, rgwchLower[i], (WCHAR) CharLowerW((LPWSTR) i));
  1138. }
  1139. fprintf(f, "\n Upper case mappings where the lower case mapping is not identity:\n Orig -> Upper -> Lower\n");
  1140. for (i=0; i<65536; i++)
  1141. {
  1142. // temporaries used for clarity
  1143. const WCHAR wchUpper = rgwchUpper[i];
  1144. if (wchUpper != i)
  1145. {
  1146. const WCHAR wchLower = rgwchLower[wchUpper];
  1147. if (wchLower != i)
  1148. fprintf(f, "U+%04x -> U+%04x -> U+%04x\n", i, wchUpper, wchLower);
  1149. }
  1150. }
  1151. fprintf(f, "\n Lower case mappings where the upper case mapping is not identity:\n Orig -> Lower -> Upper\n");
  1152. for (i=0; i<65536; i++)
  1153. {
  1154. // temporaries used for clarity
  1155. const WCHAR wchLower = rgwchLower[i];
  1156. if (wchLower != i)
  1157. {
  1158. const WCHAR wchUpper = rgwchUpper[wchLower];
  1159. if (wchUpper != i)
  1160. fprintf(f, "U+%04x -> U+%04x -> U+%04x\n", i, wchLower, wchUpper);
  1161. }
  1162. }
  1163. fprintf(f, "\n Lower-case mappings where CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, ...) says they're not equal \n");
  1164. for (i=0; i<65536; i++)
  1165. {
  1166. const WCHAR wchSource = (WCHAR) i;
  1167. const WCHAR wchLower = rgwchLower[i];
  1168. if (wchLower != i)
  1169. {
  1170. int iResult = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &wchSource, 1, &wchLower, 1);
  1171. if (iResult == 0)
  1172. fprintf(f, "*** Error comparing U+%04x and U+%04x - Win32 Error = %d\n", i, wchLower, GetLastError());
  1173. else if (iResult != CSTR_EQUAL)
  1174. fprintf(f, "U+%04x -> U+%04x but CompareString says %s (%d)\n",
  1175. i,
  1176. wchLower,
  1177. (iResult == CSTR_GREATER_THAN) ? "CSTR_GREATER_THAN" : ((iResult == CSTR_LESS_THAN) ? "CSTR_LESS_THAN" : "Invalid return value"),
  1178. iResult);
  1179. }
  1180. }
  1181. fprintf(f, "\nUpper-case mappings where CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, ...) says they're not equal \n");
  1182. for (i=0; i<65536; i++)
  1183. {
  1184. const WCHAR wchSource = (WCHAR) i;
  1185. const WCHAR wchUpper = rgwchUpper[i];
  1186. if (wchUpper != i)
  1187. {
  1188. int iResult = CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &wchSource, 1, &wchUpper, 1);
  1189. if (iResult == 0)
  1190. fprintf(f, "*** Error comparing U+%04x and U+%04x - Win32 Error = %d\n", i, wchUpper, GetLastError());
  1191. else if (iResult != CSTR_EQUAL)
  1192. fprintf(f, "U+%04x -> U+%04x but CompareString says %s (%d)\n",
  1193. i,
  1194. wchUpper,
  1195. (iResult == CSTR_GREATER_THAN) ? "CSTR_GREATER_THAN" : ((iResult == CSTR_LESS_THAN) ? "CSTR_LESS_THAN" : "Invalid return value"),
  1196. iResult);
  1197. }
  1198. }
  1199. #if 0
  1200. fprintf(f, "\nPairs where CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, ...) says equal but not same in upper\n");
  1201. for (i=1; i<65536; i++)
  1202. {
  1203. for (j=i+1; j<65536; j++)
  1204. {
  1205. WCHAR wch1 = (WCHAR) i;
  1206. WCHAR wch2 = (WCHAR) j;
  1207. int iResult = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &wch1, 1, &wch2, 1);
  1208. if (iResult == 0)
  1209. fprintf(f, "*** Error comparing U+%04x and U+%04x - Win32 Error = %d\n", wch1, wch2, GetLastError());
  1210. else
  1211. {
  1212. if (iResult == CSTR_EQUAL)
  1213. {
  1214. if (rgwchUpper[i] != rgwchUpper[j])
  1215. {
  1216. // fprintf(f, "U+%04x -> U+%04x and U+%04x -> U+%04x but CompareString says CSTR_EQUAL\n", i, rgwchUpper[i], j, rgwchUpper[j]);
  1217. fprintf(f, "[%04x -> %04x] and [%04x -> %04x] =\n", i, rgwchUpper[i], j, rgwchUpper[j]);
  1218. }
  1219. }
  1220. else
  1221. {
  1222. if (rgwchUpper[i] == rgwchUpper[j])
  1223. fprintf(
  1224. f,
  1225. "[%04x -> %04x] and [%04x -> %04x] %s\n", i, rgwchUpper[i], j, rgwchUpper[j],
  1226. (iResult == CSTR_GREATER_THAN) ? ">" : ((iResult == CSTR_LESS_THAN) ? "<" : "?"));
  1227. }
  1228. }
  1229. }
  1230. }
  1231. fprintf(f, "\nPairs where CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, ...) says equal but not same in Lower\n");
  1232. for (i=1; i<65536; i++)
  1233. {
  1234. for (j=i+1; j<65536; j++)
  1235. {
  1236. WCHAR wch1 = (WCHAR) i;
  1237. WCHAR wch2 = (WCHAR) j;
  1238. int iResult = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &wch1, 1, &wch2, 1);
  1239. if (iResult == 0)
  1240. fprintf(f, "*** Error comparing U+%04x and U+%04x - Win32 Error = %d\n", wch1, wch2, GetLastError());
  1241. else
  1242. {
  1243. if (iResult == CSTR_EQUAL)
  1244. {
  1245. if (rgwchLower[i] != rgwchLower[j])
  1246. fprintf(f, "U+%04x -> U+%04x and U+%04x -> U+%04x but CompareString says CSTR_EQUAL\n", i, rgwchLower[i], j, rgwchLower[j]);
  1247. }
  1248. else
  1249. {
  1250. if (rgwchLower[i] == rgwchLower[j])
  1251. fprintf(
  1252. f,
  1253. "U+%04x -> U+%04x and U+%04x -> U+%04x but CompareString says %s (%d)\n", i, rgwchLower[i], j, rgwchLower[j],
  1254. (iResult == CSTR_GREATER_THAN) ? "CSTR_GREATER_THAN" : ((iResult == CSTR_LESS_THAN) ? "CSTR_LESS_THAN" : "Invalid return value"),
  1255. iResult);
  1256. }
  1257. }
  1258. }
  1259. }
  1260. #endif // 0
  1261. delete []rgwchSource;
  1262. delete []rgwchUpper;
  1263. delete []rgwchLower;
  1264. fclose(f);
  1265. }
  1266. void TestCodePage(UINT cp)
  1267. {
  1268. SIZE_T i;
  1269. UCHAR ch1, ch2;
  1270. WCHAR wch1, wch2;
  1271. FILE *f;
  1272. CHAR buff[80];
  1273. WCHAR wchBuff[132];
  1274. sprintf(buff, "results_%d.txt", cp);
  1275. f = fopen(buff, "w");
  1276. if (!f)
  1277. {
  1278. perror("Error opening output file");
  1279. // exit(EXIT_FAILURE);
  1280. return;
  1281. }
  1282. for (i=0; i<256; i++)
  1283. {
  1284. buff[0] = (CHAR) i;
  1285. if (::IsDBCSLeadByteEx(cp, buff[0]))
  1286. {
  1287. SIZE_T j;
  1288. fprintf(f, "Lead byte: 0x%x\n", i);
  1289. for (j=0; j<256; j++)
  1290. {
  1291. buff[1] = (CHAR) j;
  1292. int iResult = ::MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buff, 2, wchBuff, 132);
  1293. if (iResult == 0)
  1294. {
  1295. const DWORD dwLastError = ::GetLastError();
  1296. if (dwLastError != ERROR_NO_UNICODE_TRANSLATION)
  1297. fprintf(f, "(0x%x, 0x%x) Failed; GetLastError() = %d\n", i, j, dwLastError);
  1298. }
  1299. else
  1300. {
  1301. if (iResult != 1)
  1302. {
  1303. if (iResult == 2)
  1304. fprintf(f, "(0x%x, 0x%x) -> (0x%x, 0x%x)\n", i, j, wchBuff[0], wchBuff[1]);
  1305. else
  1306. fprintf(f, "(0x%x, 0x%x) -> (0x%x, 0x%x, ...) (%d total)\n", i, j, wchBuff[0], wchBuff[1], iResult);
  1307. }
  1308. // Let's apply the upper casing rules in both places and see what happens.
  1309. int iResult2 = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, wchBuff, iResult, wchBuff, iResult);
  1310. if (iResult2 == 0)
  1311. {
  1312. const DWORD dwLastError = ::GetLastError();
  1313. fprintf(f, "Upper casing unicode char 0x%04x [%d total] failed; last error = %u\n", wchBuff[0], iResult, dwLastError);
  1314. }
  1315. else
  1316. {
  1317. BOOL fUsedDefaultChar = FALSE;
  1318. // back to oem!
  1319. int iResult3 = ::WideCharToMultiByte(
  1320. cp,
  1321. WC_NO_BEST_FIT_CHARS,
  1322. wchBuff,
  1323. iResult2,
  1324. buff,
  1325. sizeof(buff),
  1326. NULL,
  1327. &fUsedDefaultChar);
  1328. if (iResult3 == 0)
  1329. {
  1330. const DWORD dwLastError = ::GetLastError();
  1331. fprintf(f, "Converting Unicode 0x%04x back to mbcs failed; last error = %u\n", wchBuff[0], iResult2, dwLastError);
  1332. }
  1333. else
  1334. {
  1335. fprintf(f, "(0x%x, 0x%x) -> (0x%x, 0x%x)\n", i, j, buff[0], buff[1]);
  1336. }
  1337. }
  1338. }
  1339. }
  1340. }
  1341. else
  1342. {
  1343. // single byte. Hopefully easier.
  1344. buff[0] = (CHAR) i;
  1345. int iResult = ::MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, buff, 1, wchBuff, 132);
  1346. if (iResult == 0)
  1347. {
  1348. const DWORD dwLastError = ::GetLastError();
  1349. if (dwLastError != ERROR_NO_UNICODE_TRANSLATION)
  1350. fprintf(f, "(0x%x) Failed; GetLastError() = %d\n", i, dwLastError);
  1351. }
  1352. else
  1353. {
  1354. if (iResult != 1)
  1355. {
  1356. if (iResult == 2)
  1357. fprintf(f, "MBCS (0x%x) -> Unicode (0x%x, 0x%x)\n", i, wchBuff[0], wchBuff[1]);
  1358. else
  1359. fprintf(f, "MBCS (0x%x) -> Unicode (0x%x, 0x%x, ...) (%d total)\n", i, wchBuff[0], wchBuff[1], iResult);
  1360. }
  1361. // Let's apply the upper casing rules in both places and see what happens.
  1362. int iResult2 = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, wchBuff, iResult, wchBuff, iResult);
  1363. if (iResult2 == 0)
  1364. {
  1365. const DWORD dwLastError = ::GetLastError();
  1366. fprintf(f, "Upper casing unicode char 0x%04x [%d total] failed; last error = %u\n", wchBuff[0], iResult, dwLastError);
  1367. }
  1368. else
  1369. {
  1370. BOOL fUsedDefaultChar = FALSE;
  1371. // back to oem!
  1372. int iResult3 = ::WideCharToMultiByte(
  1373. cp,
  1374. WC_NO_BEST_FIT_CHARS,
  1375. wchBuff,
  1376. iResult2,
  1377. buff,
  1378. sizeof(buff),
  1379. NULL,
  1380. &fUsedDefaultChar);
  1381. if (iResult3 == 0)
  1382. {
  1383. const DWORD dwLastError = ::GetLastError();
  1384. fprintf(f, "Converting Unicode 0x%04x back to mbcs failed; last error = %u\n", wchBuff[0], iResult2, dwLastError);
  1385. }
  1386. else
  1387. {
  1388. if (fUsedDefaultChar)
  1389. {
  1390. fprintf(f, "MBCS (0x%x) -> unicode defualt char\n", i);
  1391. }
  1392. else
  1393. {
  1394. if (iResult3 == 1)
  1395. {
  1396. if (((UCHAR) buff[0]) != i)
  1397. fprintf(f, "MBCS (0x%x) -> MBCS (0x%x)\n", i, (UCHAR) buff[0]);
  1398. }
  1399. else
  1400. fprintf(f, "MBCS (0x%x) -> MBCS (0x%x) (%d total)\n", i, (UCHAR) buff[0], iResult3);
  1401. }
  1402. }
  1403. }
  1404. }
  1405. }
  1406. }
  1407. fclose(f);
  1408. }
  1409. int __cdecl main(int argc, char *argv[])
  1410. {
  1411. TestCodePage(437);
  1412. TestCodePage(850);
  1413. #if 0
  1414. DoCaseStuff();
  1415. #endif // 0
  1416. BCL::CWin32BaseUnicodeInlineStringBuffer<50> foo;
  1417. BCL::CWin32UnicodeStringBuffer bar;
  1418. BCL::CWin32BaseUnicodeFixedStringBuffer<260> baz;
  1419. DoChecks(foo, ERROR_OUTOFMEMORY);
  1420. DoChecks(bar, ERROR_OUTOFMEMORY);
  1421. DoChecks(baz, ERROR_BUFFER_OVERFLOW);
  1422. printf("%s\n", foo);
  1423. }