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:
RefClass(int n)17 RefClass(int n) : fN(n) {}
get() const18 int get() const { return fN; }
19
20 private:
21 int fN;
22 };
23
test_refptr(skiatest::Reporter * reporter)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
test_autounref(skiatest::Reporter * reporter)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
test_search(skiatest::Reporter * reporter)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
test_utf16(skiatest::Reporter * reporter)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
TestUTF(skiatest::Reporter * reporter)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