1 // Copyright 2018 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
4 #include "src/utils/SkUTF.h"
5 #include "tests/Test.h"
6
DEF_TEST(SkUTF_UTF16,reporter)7 DEF_TEST(SkUTF_UTF16, reporter) {
8 // Test non-basic-multilingual-plane unicode.
9 static const SkUnichar gUni[] = {
10 0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
11 };
12 for (SkUnichar uni : gUni) {
13 uint16_t buf[2];
14 size_t count = SkUTF::ToUTF16(uni, buf);
15 REPORTER_ASSERT(reporter, count == 2);
16 size_t count2 = SkUTF::CountUTF16(buf, sizeof(buf));
17 REPORTER_ASSERT(reporter, count2 == 1);
18 const uint16_t* ptr = buf;
19 SkUnichar c = SkUTF::NextUTF16(&ptr, buf + SK_ARRAY_COUNT(buf));
20 REPORTER_ASSERT(reporter, c == uni);
21 REPORTER_ASSERT(reporter, ptr - buf == 2);
22 }
23 }
24
DEF_TEST(SkUTF_UTF8,reporter)25 DEF_TEST(SkUTF_UTF8, reporter) {
26 static const struct {
27 const char* fUtf8;
28 SkUnichar fUni;
29 } gTest[] = {
30 { "a", 'a' },
31 { "\x7f", 0x7f },
32 { "\xC2\x80", 0x80 },
33 { "\xC3\x83", (3 << 6) | 3 },
34 { "\xDF\xBF", 0x7ff },
35 { "\xE0\xA0\x80", 0x800 },
36 { "\xE0\xB0\xB8", 0xC38 },
37 { "\xE3\x83\x83", (3 << 12) | (3 << 6) | 3 },
38 { "\xEF\xBF\xBF", 0xFFFF },
39 { "\xF0\x90\x80\x80", 0x10000 },
40 { "\xF3\x83\x83\x83", (3 << 18) | (3 << 12) | (3 << 6) | 3 }
41 };
42 for (auto test : gTest) {
43 const char* p = test.fUtf8;
44 const char* stop = p + strlen(p);
45 int n = SkUTF::CountUTF8(p, strlen(p));
46 SkUnichar u1 = SkUTF::NextUTF8(&p, stop);
47
48 REPORTER_ASSERT(reporter, n == 1);
49 REPORTER_ASSERT(reporter, u1 == test.fUni);
50 REPORTER_ASSERT(reporter, p - test.fUtf8 == (int)strlen(test.fUtf8));
51 }
52 }
53
54 #define ASCII_BYTE "X"
55 #define CONTINUATION_BYTE "\xA1"
56 #define LEADING_TWO_BYTE "\xC2"
57 #define LEADING_THREE_BYTE "\xE1"
58 #define LEADING_FOUR_BYTE "\xF0"
59 #define INVALID_BYTE "\xFC"
DEF_TEST(SkUTF_CountUTF8,r)60 DEF_TEST(SkUTF_CountUTF8, r) {
61 static const struct {
62 int expectedCount;
63 const char* utf8String;
64 } testCases[] = {
65 { 0, "" },
66 { 1, ASCII_BYTE },
67 { 2, ASCII_BYTE ASCII_BYTE },
68 { 1, LEADING_TWO_BYTE CONTINUATION_BYTE },
69 { 2, ASCII_BYTE LEADING_TWO_BYTE CONTINUATION_BYTE },
70 { 3, ASCII_BYTE ASCII_BYTE LEADING_TWO_BYTE CONTINUATION_BYTE },
71 { 1, LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
72 { 2, ASCII_BYTE LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
73 { 3, ASCII_BYTE ASCII_BYTE LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
74 { 1, LEADING_FOUR_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
75 { 2, ASCII_BYTE LEADING_FOUR_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
76 { 3, ASCII_BYTE ASCII_BYTE LEADING_FOUR_BYTE CONTINUATION_BYTE CONTINUATION_BYTE
77 CONTINUATION_BYTE },
78 { -1, INVALID_BYTE },
79 { -1, INVALID_BYTE CONTINUATION_BYTE },
80 { -1, INVALID_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
81 { -1, INVALID_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
82 { -1, LEADING_TWO_BYTE },
83 { -1, CONTINUATION_BYTE },
84 { -1, CONTINUATION_BYTE CONTINUATION_BYTE },
85 { -1, LEADING_THREE_BYTE CONTINUATION_BYTE },
86 { -1, CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
87 { -1, LEADING_FOUR_BYTE CONTINUATION_BYTE },
88 { -1, CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
89 };
90 for (auto testCase : testCases) {
91 const char* str = testCase.utf8String;
92 REPORTER_ASSERT(r, testCase.expectedCount == SkUTF::CountUTF8(str, strlen(str)));
93 }
94 }
95
DEF_TEST(SkUTF_NextUTF8_ToUTF8,r)96 DEF_TEST(SkUTF_NextUTF8_ToUTF8, r) {
97 struct {
98 SkUnichar expected;
99 const char* utf8String;
100 } testCases[] = {
101 { -1, INVALID_BYTE },
102 { -1, "" },
103 { 0x0058, ASCII_BYTE },
104 { 0x00A1, LEADING_TWO_BYTE CONTINUATION_BYTE },
105 { 0x1861, LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE },
106 { 0x010330, LEADING_FOUR_BYTE "\x90\x8C\xB0" },
107 };
108 for (auto testCase : testCases) {
109 const char* str = testCase.utf8String;
110 SkUnichar uni = SkUTF::NextUTF8(&str, str + strlen(str));
111 REPORTER_ASSERT(r, str == testCase.utf8String + strlen(testCase.utf8String));
112 REPORTER_ASSERT(r, uni == testCase.expected);
113 char buff[5] = {0, 0, 0, 0, 0};
114 size_t len = SkUTF::ToUTF8(uni, buff);
115 if (buff[len] != 0) {
116 ERRORF(r, "unexpected write");
117 continue;
118 }
119 if (uni == -1) {
120 REPORTER_ASSERT(r, len == 0);
121 continue;
122 }
123 if (len == 0) {
124 ERRORF(r, "unexpected failure.");
125 continue;
126 }
127 if (len > 4) {
128 ERRORF(r, "wrote too much");
129 continue;
130 }
131 str = testCase.utf8String;
132 REPORTER_ASSERT(r, len == strlen(buff));
133 REPORTER_ASSERT(r, len == strlen(str));
134 REPORTER_ASSERT(r, 0 == strcmp(str, buff));
135 }
136 }
137 #undef ASCII_BYTE
138 #undef CONTINUATION_BYTE
139 #undef LEADING_TWO_BYTE
140 #undef LEADING_THREE_BYTE
141 #undef LEADING_FOUR_BYTE
142 #undef INVALID_BYTE
143