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