1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "Test.h" 9 #include "SkRandom.h" 10 #include "SkRefCnt.h" 11 #include "SkTSearch.h" 12 #include "SkTSort.h" 13 #include "SkUtils.h" 14 15 class RefClass : public SkRefCnt { 16 public: 17 RefClass(int n) : fN(n) {} 18 int get() const { return fN; } 19 20 private: 21 int fN; 22 }; 23 24 static void test_refptr(skiatest::Reporter* reporter) { 25 RefClass* r0 = new RefClass(0); 26 27 SkRefPtr<RefClass> rc0; 28 REPORTER_ASSERT(reporter, rc0.get() == NULL); 29 REPORTER_ASSERT(reporter, !rc0); 30 31 SkRefPtr<RefClass> rc1; 32 REPORTER_ASSERT(reporter, rc0 == rc1); 33 REPORTER_ASSERT(reporter, rc0.get() != r0); 34 35 rc0 = r0; 36 REPORTER_ASSERT(reporter, rc0); 37 REPORTER_ASSERT(reporter, rc0 != rc1); 38 REPORTER_ASSERT(reporter, rc0.get() == r0); 39 40 rc1 = rc0; 41 REPORTER_ASSERT(reporter, rc1); 42 REPORTER_ASSERT(reporter, rc0 == rc1); 43 REPORTER_ASSERT(reporter, rc0.get() == r0); 44 45 rc0 = NULL; 46 REPORTER_ASSERT(reporter, rc0.get() == NULL); 47 REPORTER_ASSERT(reporter, !rc0); 48 REPORTER_ASSERT(reporter, rc0 != rc1); 49 50 r0->unref(); 51 } 52 53 static void test_autounref(skiatest::Reporter* reporter) { 54 RefClass obj(0); 55 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 56 57 SkAutoTUnref<RefClass> tmp(&obj); 58 REPORTER_ASSERT(reporter, &obj == tmp.get()); 59 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 60 61 REPORTER_ASSERT(reporter, &obj == tmp.detach()); 62 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 63 REPORTER_ASSERT(reporter, NULL == tmp.detach()); 64 REPORTER_ASSERT(reporter, NULL == tmp.get()); 65 66 obj.ref(); 67 REPORTER_ASSERT(reporter, 2 == obj.getRefCnt()); 68 { 69 SkAutoTUnref<RefClass> tmp2(&obj); 70 } 71 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 72 } 73 74 ///////////////////////////////////////////////////////////////////////////// 75 76 #define kSEARCH_COUNT 91 77 78 static void test_search(skiatest::Reporter* reporter) { 79 int i, array[kSEARCH_COUNT]; 80 SkRandom rand; 81 82 for (i = 0; i < kSEARCH_COUNT; i++) { 83 array[i] = rand.nextS(); 84 } 85 86 SkTHeapSort<int>(array, kSEARCH_COUNT); 87 // make sure we got sorted properly 88 for (i = 1; i < kSEARCH_COUNT; i++) { 89 REPORTER_ASSERT(reporter, array[i-1] <= array[i]); 90 } 91 92 // make sure we can find all of our values 93 for (i = 0; i < kSEARCH_COUNT; i++) { 94 int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int)); 95 REPORTER_ASSERT(reporter, index == i); 96 } 97 98 // make sure that random values are either found, or the correct 99 // insertion index is returned 100 for (i = 0; i < 10000; i++) { 101 int value = rand.nextS(); 102 int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int)); 103 104 if (index >= 0) { 105 REPORTER_ASSERT(reporter, 106 index < kSEARCH_COUNT && array[index] == value); 107 } else { 108 index = ~index; 109 REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT); 110 if (index < kSEARCH_COUNT) { 111 REPORTER_ASSERT(reporter, value < array[index]); 112 if (index > 0) { 113 REPORTER_ASSERT(reporter, value > array[index - 1]); 114 } 115 } else { 116 // we should append the new value 117 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]); 118 } 119 } 120 } 121 } 122 123 static void test_utf16(skiatest::Reporter* reporter) { 124 static const SkUnichar gUni[] = { 125 0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234 126 }; 127 128 uint16_t buf[2]; 129 130 for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) { 131 size_t count = SkUTF16_FromUnichar(gUni[i], buf); 132 REPORTER_ASSERT(reporter, count == 2); 133 size_t count2 = SkUTF16_CountUnichars(buf, 2); 134 REPORTER_ASSERT(reporter, count2 == 1); 135 const uint16_t* ptr = buf; 136 SkUnichar c = SkUTF16_NextUnichar(&ptr); 137 REPORTER_ASSERT(reporter, c == gUni[i]); 138 REPORTER_ASSERT(reporter, ptr - buf == 2); 139 } 140 } 141 142 static void TestUTF(skiatest::Reporter* reporter) { 143 static const struct { 144 const char* fUtf8; 145 SkUnichar fUni; 146 } gTest[] = { 147 { "a", 'a' }, 148 { "\x7f", 0x7f }, 149 { "\xC2\x80", 0x80 }, 150 { "\xC3\x83", (3 << 6) | 3 }, 151 { "\xDF\xBF", 0x7ff }, 152 { "\xE0\xA0\x80", 0x800 }, 153 { "\xE0\xB0\xB8", 0xC38 }, 154 { "\xE3\x83\x83", (3 << 12) | (3 << 6) | 3 }, 155 { "\xEF\xBF\xBF", 0xFFFF }, 156 { "\xF0\x90\x80\x80", 0x10000 }, 157 { "\xF3\x83\x83\x83", (3 << 18) | (3 << 12) | (3 << 6) | 3 } 158 }; 159 160 for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) { 161 const char* p = gTest[i].fUtf8; 162 int n = SkUTF8_CountUnichars(p); 163 SkUnichar u0 = SkUTF8_ToUnichar(gTest[i].fUtf8); 164 SkUnichar u1 = SkUTF8_NextUnichar(&p); 165 166 REPORTER_ASSERT(reporter, n == 1); 167 REPORTER_ASSERT(reporter, u0 == u1); 168 REPORTER_ASSERT(reporter, u0 == gTest[i].fUni); 169 REPORTER_ASSERT(reporter, 170 p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8)); 171 } 172 173 test_utf16(reporter); 174 test_search(reporter); 175 test_refptr(reporter); 176 test_autounref(reporter); 177 } 178 179 #include "TestClassDef.h" 180 DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF) 181