SkUTFTest.cpp 5.3 KB

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