2#include <cppunit/extensions/HelperMacros.h>
3#include <cppunit/TestFixture.h>
5#include "../src/unicode.h"
13 CPPUNIT_TEST(testUTF8ToUTF32);
14 CPPUNIT_TEST(testUTF32ToUTF8);
15 CPPUNIT_TEST(testUTF16ToUTF32);
16 CPPUNIT_TEST(testUTF32ToUTF16);
17 CPPUNIT_TEST_SUITE_END();
20 void testUTF8ToUTF32();
21 void testUTF32ToUTF8();
22 void testUTF16ToUTF32();
23 void testUTF32ToUTF16();
26static const char initial_bytes[8] = { 0, 0,
'\xC0',
'\xE0',
'\xF0',
'\xF8',
'\xFC',
'\xFE' };
28void TestUnicode::testUTF8ToUTF32()
30 UnicodeConversion::Result result;
31 char const * input_pointer;
32 char32_t * output_pointer;
36 for(uint16_t i = 0; i < 0x100; i++)
39 char32_t output_buffer[1];
44 input_pointer = input_buffer;
45 output_pointer = output_buffer;
47 result = UTF8ToUTF32(input_pointer, output_pointer, 1,
false);
50 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
52 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
54 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidValue, result);
56 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InputTruncated, result);
58 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidValue, result);
60 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(UnicodeConversion::InputAdvanced(result) ? 1 : 0), const_cast<char *>(input_pointer) - input_buffer);
61 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(UnicodeConversion::InputAdvanced(result) ? 1 : 0), output_pointer - output_buffer);
63 if(UnicodeConversion::InputAdvanced(result) && i < 0x80)
65 CPPUNIT_ASSERT_EQUAL(uint32_t(i), uint32_t(output_buffer[0]));
69 input_pointer = input_buffer;
70 output_pointer = output_buffer;
72 result = UTF8ToUTF32(input_pointer, output_pointer, 1,
true);
75 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
77 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
79 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidValue, result);
81 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InputTruncated, result);
83 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidValue, result);
85 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(UnicodeConversion::InputAdvanced(result) ? 1 : 0), const_cast<char *>(input_pointer) - input_buffer);
86 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(UnicodeConversion::InputAdvanced(result) ? 1 : 0), output_pointer - output_buffer);
88 if(UnicodeConversion::InputAdvanced(result) && i < 0x80)
90 CPPUNIT_ASSERT_EQUAL(uint32_t(i), uint32_t(output_buffer[0]));
94 for(
size_t sequence_length = 2; sequence_length < 8; sequence_length++)
97 char32_t output_buffer[1];
99 for(int32_t bit_position = -1; uint32_t(bit_position + 1) <= 1 + sequence_length * 5 && uint32_t(bit_position + 1) <= 32; bit_position ++)
101 input_buffer[0] = initial_bytes[sequence_length];
102 for(
size_t i = 1; i < sequence_length; i++)
104 input_buffer[i] = 0x80;
107 if(bit_position >= 0)
108 input_buffer[sequence_length - 1 - bit_position / 6] |= 1 << (bit_position % 6);
111 input_pointer = input_buffer;
112 output_pointer = output_buffer;
114 result = UTF8ToUTF32(input_pointer, output_pointer, sequence_length,
true);
115 if(bit_position == -1)
116 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
117 else if(bit_position < 21)
118 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
120 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::OutOfRangeCharacter, result);
122 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(sequence_length),
const_cast<char *
>(input_pointer) - input_buffer);
123 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
126 CPPUNIT_ASSERT_EQUAL(uint32_t(0), uint32_t(output_buffer[0]));
128 CPPUNIT_ASSERT_EQUAL(uint32_t(1 << bit_position), uint32_t(output_buffer[0]));
131 input_pointer = input_buffer;
132 output_pointer = output_buffer;
134 result = UTF8ToUTF32(input_pointer, output_pointer, sequence_length,
false);
135 if(sequence_length >= 5)
136 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidValue, result);
137 else if(bit_position == -1)
138 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
140 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
142 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(UnicodeConversion::IsSuccess(result) ? sequence_length : 1), const_cast<char *>(input_pointer) - input_buffer);
143 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
145 if(UnicodeConversion::IsSuccess(result))
148 CPPUNIT_ASSERT_EQUAL(uint32_t(0), uint32_t(output_buffer[0]));
150 CPPUNIT_ASSERT_EQUAL(uint32_t(1 << bit_position), uint32_t(output_buffer[0]));
154 CPPUNIT_ASSERT_EQUAL(uint32_t(input_buffer[0] & 0xFF), uint32_t(output_buffer[0]));
160void TestUnicode::testUTF32ToUTF8()
162 UnicodeConversion::Result result;
163 char32_t const * input_pointer;
164 char * output_pointer;
165 size_t required_output;
167 for(int32_t bit_position = -1; bit_position < 32; bit_position ++)
169 char32_t input_buffer[1];
170 char output_buffer[7];
172 size_t actual_required_output = bit_position <= 6 ? 1 : (bit_position + 4) / 5;
176 input_buffer[0] = 1 << bit_position;
178 input_pointer = input_buffer;
179 output_pointer = output_buffer;
180 required_output = size_t(-1);
182 result = UTF32ToUTF8(input_pointer, output_pointer, actual_required_output, required_output);
183 if(bit_position == -1)
184 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
185 else if(bit_position < 21)
186 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
188 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::OutOfRangeCharacter, result);
190 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char32_t *
>(input_pointer) - input_buffer);
191 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(actual_required_output), output_pointer - output_buffer);
192 CPPUNIT_ASSERT_EQUAL(actual_required_output, required_output);
194 if(actual_required_output > 1)
196 input_pointer = input_buffer;
197 output_pointer = output_buffer;
198 required_output = size_t(-1);
200 result = UTF32ToUTF8(input_pointer, output_pointer, actual_required_output - 1, required_output);
201 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::BufferOverflow, result);
203 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(0),
const_cast<char32_t *
>(input_pointer) - input_buffer);
204 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(0), output_pointer - output_buffer);
205 CPPUNIT_ASSERT_EQUAL(actual_required_output, required_output);
210void TestUnicode::testUTF16ToUTF32()
212 UnicodeConversion::Result result;
213 char16_t const * input_pointer;
214 char32_t * output_pointer;
216 for(uint16_t i = 0; i < 256; i++)
218 char16_t input_buffer[1];
219 char32_t output_buffer[1];
223 input_pointer = input_buffer;
224 output_pointer = output_buffer;
226 result = UTF16ToUTF32(input_pointer, output_pointer, 1);
229 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
231 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
233 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char16_t *
>(input_pointer) - input_buffer);
234 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
235 CPPUNIT_ASSERT_EQUAL(uint32_t(i), uint32_t(output_buffer[0]));
238 input_buffer[0] = i << 8;
240 input_pointer = input_buffer;
241 output_pointer = output_buffer;
243 result = UTF16ToUTF32(input_pointer, output_pointer, 1);
245 if(0xD8 <= i && i <= 0xDB)
246 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InputTruncated, result);
247 else if(0xDC <= i && i <= 0xDF)
248 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidValue, result);
250 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
252 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
254 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char16_t *
>(input_pointer) - input_buffer);
255 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
256 if(!(0xD8 <= i && i <= 0xDF))
257 CPPUNIT_ASSERT_EQUAL(uint32_t(i << 8), uint32_t(output_buffer[0]));
260 for(int32_t bit_position = -1; bit_position < 20; bit_position ++)
262 char16_t input_buffer[2];
263 char32_t output_buffer[1];
265 input_buffer[0] = 0xD800;
266 input_buffer[1] = 0xDC00;
268 if(bit_position >= 0)
269 input_buffer[1 - bit_position / 10] |= 1 << (bit_position % 10);
271 input_pointer = input_buffer;
272 output_pointer = output_buffer;
274 result = UTF16ToUTF32(input_pointer, output_pointer, 2);
276 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
277 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(2),
const_cast<char16_t *
>(input_pointer) - input_buffer);
278 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
279 CPPUNIT_ASSERT_EQUAL(uint32_t(0x00100000 | (bit_position >= 0 ? 1 << bit_position : 0)), uint32_t(output_buffer[0]));
282 input_pointer = input_buffer;
283 output_pointer = output_buffer;
285 result = UTF16ToUTF32(input_pointer, output_pointer, 1);
287 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InputTruncated, result);
288 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char16_t *
>(input_pointer) - input_buffer);
289 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
290 CPPUNIT_ASSERT_EQUAL(uint32_t(0x00100000 | (bit_position >= 10 ? 1 << bit_position : 0)), uint32_t(output_buffer[0]));
294void TestUnicode::testUTF32ToUTF16()
296 UnicodeConversion::Result result;
297 char32_t const * input_pointer;
298 char16_t * output_pointer;
299 size_t required_output;
301 for(uint16_t i = 0; i < 256; i++)
303 char32_t input_buffer[1];
304 char16_t output_buffer[1];
308 input_pointer = input_buffer;
309 output_pointer = output_buffer;
310 required_output = size_t(-1);
312 result = UTF32ToUTF16(input_pointer, output_pointer, 1, required_output);
315 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
317 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
319 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char32_t *
>(input_pointer) - input_buffer);
320 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
321 CPPUNIT_ASSERT_EQUAL(uint32_t(i), uint32_t(output_buffer[0]));
324 input_buffer[0] = i << 8;
326 input_pointer = input_buffer;
327 output_pointer = output_buffer;
328 required_output = size_t(-1);
330 result = UTF32ToUTF16(input_pointer, output_pointer, 1, required_output);
332 if(0xD8 <= i && i <= 0xDF)
333 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::InvalidCharacter, result);
335 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::NullCharacter, result);
337 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
339 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char32_t *
>(input_pointer) - input_buffer);
340 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1), output_pointer - output_buffer);
341 if(!(0xD8 <= i && i <= 0xDF))
342 CPPUNIT_ASSERT_EQUAL(uint32_t(i << 8), uint32_t(output_buffer[0]));
345 for(int32_t bit_position = -1; bit_position < 16; bit_position ++)
347 char32_t input_buffer[1];
348 char16_t output_buffer[2];
350 input_buffer[0] = 0x00100000;
351 if(bit_position >= 0)
352 input_buffer[0] |= 1 << bit_position;
354 input_pointer = input_buffer;
355 output_pointer = output_buffer;
356 required_output = size_t(-1);
358 result = UTF32ToUTF16(input_pointer, output_pointer, 2, required_output);
359 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::Success, result);
361 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char32_t *
>(input_pointer) - input_buffer);
362 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(2), output_pointer - output_buffer);
363 CPPUNIT_ASSERT_EQUAL(
size_t(2), required_output);
366 input_pointer = input_buffer;
367 output_pointer = output_buffer;
368 required_output = size_t(-1);
370 result = UTF32ToUTF16(input_pointer, output_pointer, 1, required_output);
371 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::BufferOverflow, result);
373 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(0),
const_cast<char32_t *
>(input_pointer) - input_buffer);
374 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(0), output_pointer - output_buffer);
377 for(int32_t bit_position = 16; bit_position < 32; bit_position ++)
379 char32_t input_buffer[1];
380 char16_t output_buffer[2];
382 input_buffer[0] = 0x00100000 + (1 << bit_position);
384 input_pointer = input_buffer;
385 output_pointer = output_buffer;
386 required_output = size_t(-1);
388 result = UTF32ToUTF16(input_pointer, output_pointer, 2, required_output);
389 CPPUNIT_ASSERT_EQUAL(UnicodeConversion::OutOfRangeCharacter, result);
391 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(1),
const_cast<char32_t *
>(input_pointer) - input_buffer);
392 CPPUNIT_ASSERT_EQUAL(ptrdiff_t(0), output_pointer - output_buffer);