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 "SkRandom.h"
9 #include "SkRefCnt.h"
10 #include "SkTSearch.h"
11 #include "SkTSort.h"
12 #include "Test.h"
13 
14 class RefClass : public SkRefCnt {
15 public:
16 
17 
RefClass(int n)18     RefClass(int n) : fN(n) {}
get() const19     int get() const { return fN; }
20 
21 private:
22     int fN;
23 
24     typedef SkRefCnt INHERITED;
25 };
26 
test_autounref(skiatest::Reporter * reporter)27 static void test_autounref(skiatest::Reporter* reporter) {
28     RefClass obj(0);
29     REPORTER_ASSERT(reporter, obj.unique());
30 
31     sk_sp<RefClass> tmp(&obj);
32     REPORTER_ASSERT(reporter, &obj == tmp.get());
33     REPORTER_ASSERT(reporter, obj.unique());
34 
35     REPORTER_ASSERT(reporter, &obj == tmp.release());
36     REPORTER_ASSERT(reporter, obj.unique());
37     REPORTER_ASSERT(reporter, nullptr == tmp.release());
38     REPORTER_ASSERT(reporter, nullptr == tmp.get());
39 
40     obj.ref();
41     REPORTER_ASSERT(reporter, !obj.unique());
42     {
43         sk_sp<RefClass> tmp2(&obj);
44     }
45     REPORTER_ASSERT(reporter, obj.unique());
46 }
47 
test_autostarray(skiatest::Reporter * reporter)48 static void test_autostarray(skiatest::Reporter* reporter) {
49     RefClass obj0(0);
50     RefClass obj1(1);
51     REPORTER_ASSERT(reporter, obj0.unique());
52     REPORTER_ASSERT(reporter, obj1.unique());
53 
54     {
55         SkAutoSTArray<2, sk_sp<RefClass> > tmp;
56         REPORTER_ASSERT(reporter, 0 == tmp.count());
57 
58         tmp.reset(0);   // test out reset(0) when already at 0
59         tmp.reset(4);   // this should force a new allocation
60         REPORTER_ASSERT(reporter, 4 == tmp.count());
61         tmp[0].reset(SkRef(&obj0));
62         tmp[1].reset(SkRef(&obj1));
63         REPORTER_ASSERT(reporter, !obj0.unique());
64         REPORTER_ASSERT(reporter, !obj1.unique());
65 
66         // test out reset with data in the array (and a new allocation)
67         tmp.reset(0);
68         REPORTER_ASSERT(reporter, 0 == tmp.count());
69         REPORTER_ASSERT(reporter, obj0.unique());
70         REPORTER_ASSERT(reporter, obj1.unique());
71 
72         tmp.reset(2);   // this should use the preexisting allocation
73         REPORTER_ASSERT(reporter, 2 == tmp.count());
74         tmp[0].reset(SkRef(&obj0));
75         tmp[1].reset(SkRef(&obj1));
76     }
77 
78     // test out destructor with data in the array (and using existing allocation)
79     REPORTER_ASSERT(reporter, obj0.unique());
80     REPORTER_ASSERT(reporter, obj1.unique());
81 
82     {
83         // test out allocating ctor (this should allocate new memory)
84         SkAutoSTArray<2, sk_sp<RefClass> > tmp(4);
85         REPORTER_ASSERT(reporter, 4 == tmp.count());
86 
87         tmp[0].reset(SkRef(&obj0));
88         tmp[1].reset(SkRef(&obj1));
89         REPORTER_ASSERT(reporter, !obj0.unique());
90         REPORTER_ASSERT(reporter, !obj1.unique());
91 
92         // Test out resut with data in the array and malloced storage
93         tmp.reset(0);
94         REPORTER_ASSERT(reporter, obj0.unique());
95         REPORTER_ASSERT(reporter, obj1.unique());
96 
97         tmp.reset(2);   // this should use the preexisting storage
98         tmp[0].reset(SkRef(&obj0));
99         tmp[1].reset(SkRef(&obj1));
100         REPORTER_ASSERT(reporter, !obj0.unique());
101         REPORTER_ASSERT(reporter, !obj1.unique());
102 
103         tmp.reset(4);   // this should force a new malloc
104         REPORTER_ASSERT(reporter, obj0.unique());
105         REPORTER_ASSERT(reporter, obj1.unique());
106 
107         tmp[0].reset(SkRef(&obj0));
108         tmp[1].reset(SkRef(&obj1));
109         REPORTER_ASSERT(reporter, !obj0.unique());
110         REPORTER_ASSERT(reporter, !obj1.unique());
111     }
112 
113     REPORTER_ASSERT(reporter, obj0.unique());
114     REPORTER_ASSERT(reporter, obj1.unique());
115 }
116 
117 /////////////////////////////////////////////////////////////////////////////
118 
119 #define kSEARCH_COUNT   91
120 
test_search(skiatest::Reporter * reporter)121 static void test_search(skiatest::Reporter* reporter) {
122     int         i, array[kSEARCH_COUNT];
123     SkRandom    rand;
124 
125     for (i = 0; i < kSEARCH_COUNT; i++) {
126         array[i] = rand.nextS();
127     }
128 
129     SkTHeapSort<int>(array, kSEARCH_COUNT);
130     // make sure we got sorted properly
131     for (i = 1; i < kSEARCH_COUNT; i++) {
132         REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
133     }
134 
135     // make sure we can find all of our values
136     for (i = 0; i < kSEARCH_COUNT; i++) {
137         int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
138         REPORTER_ASSERT(reporter, index == i);
139     }
140 
141     // make sure that random values are either found, or the correct
142     // insertion index is returned
143     for (i = 0; i < 10000; i++) {
144         int value = rand.nextS();
145         int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
146 
147         if (index >= 0) {
148             REPORTER_ASSERT(reporter,
149                             index < kSEARCH_COUNT && array[index] == value);
150         } else {
151             index = ~index;
152             REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
153             if (index < kSEARCH_COUNT) {
154                 REPORTER_ASSERT(reporter, value < array[index]);
155                 if (index > 0) {
156                     REPORTER_ASSERT(reporter, value > array[index - 1]);
157                 }
158             } else {
159                 // we should append the new value
160                 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
161             }
162         }
163     }
164 }
165 
DEF_TEST(Utils,reporter)166 DEF_TEST(Utils, reporter) {
167     test_search(reporter);
168     test_autounref(reporter);
169     test_autostarray(reporter);
170 }
171