blob: dbe02e88d420980fbd3b5379d5023d8fffa15730 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@google.com1622c992011-06-14 19:22:21 +00008#include "Test.h"
reed@google.com8d0b5772011-06-24 13:07:31 +00009#include "SkData.h"
reed@google.com91bd4592012-07-11 17:24:49 +000010#include "SkDataSet.h"
reed@google.com8c5c7a92013-04-19 20:16:01 +000011#include "SkDataTable.h"
reed@google.com91bd4592012-07-11 17:24:49 +000012#include "SkStream.h"
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000013#include "SkOrderedReadBuffer.h"
14#include "SkOrderedWriteBuffer.h"
reed@google.com91bd4592012-07-11 17:24:49 +000015
16template <typename T> class SkTUnref {
17public:
18 SkTUnref(T* ref) : fRef(ref) {}
19 ~SkTUnref() { fRef->unref(); }
rmistry@google.comd6176b02012-08-23 18:14:13 +000020
reed@google.com91bd4592012-07-11 17:24:49 +000021 operator T*() { return fRef; }
22 operator const T*() { return fRef; }
23
24private:
25 T* fRef;
26};
27
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000028static void test_is_equal(skiatest::Reporter* reporter,
29 const SkDataTable* a, const SkDataTable* b) {
30 REPORTER_ASSERT(reporter, a->count() == b->count());
31 for (int i = 0; i < a->count(); ++i) {
32 size_t sizea, sizeb;
33 const void* mema = a->at(i, &sizea);
34 const void* memb = b->at(i, &sizeb);
35 REPORTER_ASSERT(reporter, sizea == sizeb);
36 REPORTER_ASSERT(reporter, !memcmp(mema, memb, sizea));
37 }
38}
39
40static void test_datatable_flatten(skiatest::Reporter* reporter,
41 SkDataTable* table) {
42 SkOrderedWriteBuffer wb(1024);
43 wb.writeFlattenable(table);
44
45 size_t wsize = wb.size();
46 SkAutoMalloc storage(wsize);
47 wb.writeToMemory(storage.get());
48
49 SkOrderedReadBuffer rb(storage.get(), wsize);
50 SkAutoTUnref<SkDataTable> newTable((SkDataTable*)rb.readFlattenable());
51
52 SkDebugf("%d entries, %d flatten-size\n", table->count(), wsize);
53 test_is_equal(reporter, table, newTable);
54}
55
56static void test_datatable_is_empty(skiatest::Reporter* reporter,
57 SkDataTable* table) {
58 REPORTER_ASSERT(reporter, table->isEmpty());
59 REPORTER_ASSERT(reporter, 0 == table->count());
60 test_datatable_flatten(reporter, table);
61}
62
63static void test_emptytable(skiatest::Reporter* reporter) {
64 SkAutoTUnref<SkDataTable> table0(SkDataTable::NewEmpty());
65 SkAutoTUnref<SkDataTable> table1(SkDataTable::NewCopyArrays(NULL, NULL, 0));
66 SkAutoTUnref<SkDataTable> table2(SkDataTable::NewCopyArray(NULL, NULL, 0));
67 SkAutoTUnref<SkDataTable> table3(SkDataTable::NewArrayProc(NULL, NULL, 0,
68 NULL, NULL));
69
70 test_datatable_is_empty(reporter, table0);
71 test_datatable_is_empty(reporter, table1);
72 test_datatable_is_empty(reporter, table2);
73 test_datatable_is_empty(reporter, table3);
74
75 test_is_equal(reporter, table0, table1);
76 test_is_equal(reporter, table0, table2);
77 test_is_equal(reporter, table0, table3);
78}
79
reed@google.com8c5c7a92013-04-19 20:16:01 +000080static void test_simpletable(skiatest::Reporter* reporter) {
81 const int idata[] = { 1, 4, 9, 16, 25, 63 };
82 int icount = SK_ARRAY_COUNT(idata);
83 SkAutoTUnref<SkDataTable> itable(SkDataTable::NewCopyArray(idata,
84 sizeof(idata[0]),
85 icount));
86 REPORTER_ASSERT(reporter, itable->count() == icount);
87 for (int i = 0; i < icount; ++i) {
88 size_t size;
89 REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000090 REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
reed@google.com8c5c7a92013-04-19 20:16:01 +000091 REPORTER_ASSERT(reporter, sizeof(int) == size);
92 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000093 test_datatable_flatten(reporter, itable);
reed@google.com8c5c7a92013-04-19 20:16:01 +000094}
95
96static void test_vartable(skiatest::Reporter* reporter) {
97 const char* str[] = {
98 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
99 };
100 int count = SK_ARRAY_COUNT(str);
101 size_t sizes[SK_ARRAY_COUNT(str)];
102 for (int i = 0; i < count; ++i) {
103 sizes[i] = strlen(str[i]) + 1;
104 }
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000105
reed@google.com8c5c7a92013-04-19 20:16:01 +0000106 SkAutoTUnref<SkDataTable> table(SkDataTable::NewCopyArrays(
107 (const void*const*)str, sizes, count));
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000108
reed@google.com8c5c7a92013-04-19 20:16:01 +0000109 REPORTER_ASSERT(reporter, table->count() == count);
110 for (int i = 0; i < count; ++i) {
111 size_t size;
112 REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000113 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +0000114 str[i]));
115 REPORTER_ASSERT(reporter, size == sizes[i]);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000116
reed@google.com8c5c7a92013-04-19 20:16:01 +0000117 const char* s = table->atStr(i);
118 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
119 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000120 test_datatable_flatten(reporter, table);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000121}
122
123static void test_tablebuilder(skiatest::Reporter* reporter) {
124 const char* str[] = {
125 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
126 };
127 int count = SK_ARRAY_COUNT(str);
128
129 SkDataTableBuilder builder(16);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000130
reed@google.com8c5c7a92013-04-19 20:16:01 +0000131 for (int i = 0; i < count; ++i) {
132 builder.append(str[i], strlen(str[i]) + 1);
133 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000134 SkAutoTUnref<SkDataTable> table(builder.detachDataTable());
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000135
reed@google.com8c5c7a92013-04-19 20:16:01 +0000136 REPORTER_ASSERT(reporter, table->count() == count);
137 for (int i = 0; i < count; ++i) {
138 size_t size;
139 REPORTER_ASSERT(reporter, table->atSize(i) == strlen(str[i]) + 1);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000140 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +0000141 str[i]));
142 REPORTER_ASSERT(reporter, size == strlen(str[i]) + 1);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000143
reed@google.com8c5c7a92013-04-19 20:16:01 +0000144 const char* s = table->atStr(i);
145 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
146 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000147 test_datatable_flatten(reporter, table);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000148}
149
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000150static void test_globaltable(skiatest::Reporter* reporter) {
151 static const int gData[] = {
152 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
153 };
154 int count = SK_ARRAY_COUNT(gData);
155
156 SkAutoTUnref<SkDataTable> table(SkDataTable::NewArrayProc(gData,
157 sizeof(gData[0]), count, NULL, NULL));
158
159 REPORTER_ASSERT(reporter, table->count() == count);
160 for (int i = 0; i < count; ++i) {
161 size_t size;
162 REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
163 REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
164 REPORTER_ASSERT(reporter, sizeof(int) == size);
165 }
166 test_datatable_flatten(reporter, table);
167}
168
169static void TestDataTable(skiatest::Reporter* reporter) {
170 test_emptytable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000171 test_simpletable(reporter);
172 test_vartable(reporter);
173 test_tablebuilder(reporter);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000174 test_globaltable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000175}
176
reed@google.com91bd4592012-07-11 17:24:49 +0000177static void unrefAll(const SkDataSet::Pair pairs[], int count) {
178 for (int i = 0; i < count; ++i) {
179 pairs[i].fValue->unref();
180 }
181}
182
183// asserts that inner is a subset of outer
184static void test_dataset_subset(skiatest::Reporter* reporter,
185 const SkDataSet& outer, const SkDataSet& inner) {
186 SkDataSet::Iter iter(inner);
187 for (; !iter.done(); iter.next()) {
188 SkData* outerData = outer.find(iter.key());
189 REPORTER_ASSERT(reporter, outerData);
190 REPORTER_ASSERT(reporter, outerData->equals(iter.value()));
191 }
192}
193
194static void test_datasets_equal(skiatest::Reporter* reporter,
195 const SkDataSet& ds0, const SkDataSet& ds1) {
196 REPORTER_ASSERT(reporter, ds0.count() == ds1.count());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000197
reed@google.com91bd4592012-07-11 17:24:49 +0000198 test_dataset_subset(reporter, ds0, ds1);
199 test_dataset_subset(reporter, ds1, ds0);
200}
201
202static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds,
203 int count) {
204 REPORTER_ASSERT(reporter, ds.count() == count);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000205
reed@google.com91bd4592012-07-11 17:24:49 +0000206 SkDataSet::Iter iter(ds);
207 int index = 0;
208 for (; !iter.done(); iter.next()) {
humper@google.com05af1af2013-01-07 16:47:43 +0000209// const char* name = iter.key();
210// SkData* data = iter.value();
reed@google.com79382af2012-07-11 18:55:23 +0000211// SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes());
reed@google.com91bd4592012-07-11 17:24:49 +0000212 index += 1;
213 }
214 REPORTER_ASSERT(reporter, index == count);
215
216 SkDynamicMemoryWStream ostream;
217 ds.writeToStream(&ostream);
218 SkMemoryStream istream;
219 istream.setData(ostream.copyToData())->unref();
220 SkDataSet copy(&istream);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000221
reed@google.com91bd4592012-07-11 17:24:49 +0000222 test_datasets_equal(reporter, ds, copy);
223}
224
225static void test_dataset(skiatest::Reporter* reporter) {
226 SkDataSet set0(NULL, 0);
227 SkDataSet set1("hello", SkTUnref<SkData>(SkData::NewWithCString("world")));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000228
reed@google.com91bd4592012-07-11 17:24:49 +0000229 const SkDataSet::Pair pairs[] = {
230 { "one", SkData::NewWithCString("1") },
231 { "two", SkData::NewWithCString("2") },
232 { "three", SkData::NewWithCString("3") },
233 };
234 SkDataSet set3(pairs, 3);
235 unrefAll(pairs, 3);
236
237 test_dataset(reporter, set0, 0);
238 test_dataset(reporter, set1, 1);
239 test_dataset(reporter, set3, 3);
240}
reed@google.com1622c992011-06-14 19:22:21 +0000241
242static void* gGlobal;
243
244static void delete_int_proc(const void* ptr, size_t len, void* context) {
245 int* data = (int*)ptr;
246 SkASSERT(context == gGlobal);
247 delete[] data;
248}
249
reed@google.com8d0b5772011-06-24 13:07:31 +0000250static void assert_len(skiatest::Reporter* reporter, SkData* ref, size_t len) {
reed@google.com1622c992011-06-14 19:22:21 +0000251 REPORTER_ASSERT(reporter, ref->size() == len);
252}
253
reed@google.com8d0b5772011-06-24 13:07:31 +0000254static void assert_data(skiatest::Reporter* reporter, SkData* ref,
reed@google.com1622c992011-06-14 19:22:21 +0000255 const void* data, size_t len) {
256 REPORTER_ASSERT(reporter, ref->size() == len);
257 REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
258}
259
reed@google.comdbc936d2012-06-28 15:40:09 +0000260static void test_cstring(skiatest::Reporter* reporter) {
261 const char str[] = "Hello world";
262 size_t len = strlen(str);
263
reed@google.coma63a8512012-07-02 20:29:00 +0000264 SkAutoTUnref<SkData> r0(SkData::NewWithCopy(str, len + 1));
reed@google.comdbc936d2012-06-28 15:40:09 +0000265 SkAutoTUnref<SkData> r1(SkData::NewWithCString(str));
266
267 REPORTER_ASSERT(reporter, r0->equals(r1));
268
269 SkAutoTUnref<SkData> r2(SkData::NewWithCString(NULL));
reed@google.coma63a8512012-07-02 20:29:00 +0000270 REPORTER_ASSERT(reporter, 1 == r2->size());
271 REPORTER_ASSERT(reporter, 0 == *r2->bytes());
reed@google.comdbc936d2012-06-28 15:40:09 +0000272}
273
reed@google.com91bd4592012-07-11 17:24:49 +0000274static void TestData(skiatest::Reporter* reporter) {
reed@google.com1622c992011-06-14 19:22:21 +0000275 const char* str = "We the people, in order to form a more perfect union.";
276 const int N = 10;
277
reed@google.comdbc936d2012-06-28 15:40:09 +0000278 SkAutoTUnref<SkData> r0(SkData::NewEmpty());
279 SkAutoTUnref<SkData> r1(SkData::NewWithCopy(str, strlen(str)));
280 SkAutoTUnref<SkData> r2(SkData::NewWithProc(new int[N], N*sizeof(int),
281 delete_int_proc, gGlobal));
282 SkAutoTUnref<SkData> r3(SkData::NewSubset(r1, 7, 6));
reed@google.com1622c992011-06-14 19:22:21 +0000283
reed@google.com1622c992011-06-14 19:22:21 +0000284 assert_len(reporter, r0, 0);
285 assert_len(reporter, r1, strlen(str));
286 assert_len(reporter, r2, N * sizeof(int));
287 assert_len(reporter, r3, 6);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000288
reed@google.com1622c992011-06-14 19:22:21 +0000289 assert_data(reporter, r1, str, strlen(str));
290 assert_data(reporter, r3, "people", 6);
291
reed@google.com8d0b5772011-06-24 13:07:31 +0000292 SkData* tmp = SkData::NewSubset(r1, strlen(str), 10);
reed@google.com1622c992011-06-14 19:22:21 +0000293 assert_len(reporter, tmp, 0);
294 tmp->unref();
reed@google.com8d0b5772011-06-24 13:07:31 +0000295 tmp = SkData::NewSubset(r1, 0, 0);
reed@google.com1622c992011-06-14 19:22:21 +0000296 assert_len(reporter, tmp, 0);
297 tmp->unref();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000298
reed@google.comdbc936d2012-06-28 15:40:09 +0000299 test_cstring(reporter);
reed@google.com91bd4592012-07-11 17:24:49 +0000300 test_dataset(reporter);
reed@google.com1622c992011-06-14 19:22:21 +0000301}
302
303#include "TestClassDef.h"
reed@google.com91bd4592012-07-11 17:24:49 +0000304DEFINE_TESTCLASS("Data", DataTestClass, TestData)
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000305DEFINE_TESTCLASS("DataTable", DataTableTestClass, TestDataTable)