• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     SK_DECLARE_INST_COUNT(RefClass)
18 
RefClass(int n)19     RefClass(int n) : fN(n) {}
get() const20     int get() const { return fN; }
21 
22 private:
23     int fN;
24 
25     typedef SkRefCnt INHERITED;
26 };
27 
SK_DEFINE_INST_COUNT(RefClass)28 SK_DEFINE_INST_COUNT(RefClass)
29 
30 static void test_autounref(skiatest::Reporter* reporter) {
31     RefClass obj(0);
32     REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
33 
34     SkAutoTUnref<RefClass> tmp(&obj);
35     REPORTER_ASSERT(reporter, &obj == tmp.get());
36     REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
37 
38     REPORTER_ASSERT(reporter, &obj == tmp.detach());
39     REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
40     REPORTER_ASSERT(reporter, NULL == tmp.detach());
41     REPORTER_ASSERT(reporter, NULL == tmp.get());
42 
43     obj.ref();
44     REPORTER_ASSERT(reporter, 2 == obj.getRefCnt());
45     {
46         SkAutoTUnref<RefClass> tmp2(&obj);
47     }
48     REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
49 }
50 
51 /////////////////////////////////////////////////////////////////////////////
52 
53 #define kSEARCH_COUNT   91
54 
test_search(skiatest::Reporter * reporter)55 static void test_search(skiatest::Reporter* reporter) {
56     int         i, array[kSEARCH_COUNT];
57     SkRandom    rand;
58 
59     for (i = 0; i < kSEARCH_COUNT; i++) {
60         array[i] = rand.nextS();
61     }
62 
63     SkTHeapSort<int>(array, kSEARCH_COUNT);
64     // make sure we got sorted properly
65     for (i = 1; i < kSEARCH_COUNT; i++) {
66         REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
67     }
68 
69     // make sure we can find all of our values
70     for (i = 0; i < kSEARCH_COUNT; i++) {
71         int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
72         REPORTER_ASSERT(reporter, index == i);
73     }
74 
75     // make sure that random values are either found, or the correct
76     // insertion index is returned
77     for (i = 0; i < 10000; i++) {
78         int value = rand.nextS();
79         int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
80 
81         if (index >= 0) {
82             REPORTER_ASSERT(reporter,
83                             index < kSEARCH_COUNT && array[index] == value);
84         } else {
85             index = ~index;
86             REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
87             if (index < kSEARCH_COUNT) {
88                 REPORTER_ASSERT(reporter, value < array[index]);
89                 if (index > 0) {
90                     REPORTER_ASSERT(reporter, value > array[index - 1]);
91                 }
92             } else {
93                 // we should append the new value
94                 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
95             }
96         }
97     }
98 }
99 
test_utf16(skiatest::Reporter * reporter)100 static void test_utf16(skiatest::Reporter* reporter) {
101     static const SkUnichar gUni[] = {
102         0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
103     };
104 
105     uint16_t buf[2];
106 
107     for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) {
108         size_t count = SkUTF16_FromUnichar(gUni[i], buf);
109         REPORTER_ASSERT(reporter, count == 2);
110         size_t count2 = SkUTF16_CountUnichars(buf, 2);
111         REPORTER_ASSERT(reporter, count2 == 1);
112         const uint16_t* ptr = buf;
113         SkUnichar c = SkUTF16_NextUnichar(&ptr);
114         REPORTER_ASSERT(reporter, c == gUni[i]);
115         REPORTER_ASSERT(reporter, ptr - buf == 2);
116     }
117 }
118 
TestUTF(skiatest::Reporter * reporter)119 static void TestUTF(skiatest::Reporter* reporter) {
120     static const struct {
121         const char* fUtf8;
122         SkUnichar   fUni;
123     } gTest[] = {
124         { "a",                  'a' },
125         { "\x7f",               0x7f },
126         { "\xC2\x80",           0x80 },
127         { "\xC3\x83",           (3 << 6) | 3    },
128         { "\xDF\xBF",           0x7ff },
129         { "\xE0\xA0\x80",       0x800 },
130         { "\xE0\xB0\xB8",       0xC38 },
131         { "\xE3\x83\x83",       (3 << 12) | (3 << 6) | 3    },
132         { "\xEF\xBF\xBF",       0xFFFF },
133         { "\xF0\x90\x80\x80",   0x10000 },
134         { "\xF3\x83\x83\x83",   (3 << 18) | (3 << 12) | (3 << 6) | 3    }
135     };
136 
137     for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) {
138         const char* p = gTest[i].fUtf8;
139         int         n = SkUTF8_CountUnichars(p);
140         SkUnichar   u0 = SkUTF8_ToUnichar(gTest[i].fUtf8);
141         SkUnichar   u1 = SkUTF8_NextUnichar(&p);
142 
143         REPORTER_ASSERT(reporter, n == 1);
144         REPORTER_ASSERT(reporter, u0 == u1);
145         REPORTER_ASSERT(reporter, u0 == gTest[i].fUni);
146         REPORTER_ASSERT(reporter,
147                         p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8));
148     }
149 
150     test_utf16(reporter);
151     test_search(reporter);
152     test_autounref(reporter);
153 }
154 
155 #include "TestClassDef.h"
156 DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF)
157