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