• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkUTF.h"
5 #include "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