blob: 0cbce3fcd1df1df4802da263b55116a216fa8cae [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
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000052 test_is_equal(reporter, table, newTable);
53}
54
55static void test_datatable_is_empty(skiatest::Reporter* reporter,
56 SkDataTable* table) {
57 REPORTER_ASSERT(reporter, table->isEmpty());
58 REPORTER_ASSERT(reporter, 0 == table->count());
59 test_datatable_flatten(reporter, table);
60}
61
62static void test_emptytable(skiatest::Reporter* reporter) {
63 SkAutoTUnref<SkDataTable> table0(SkDataTable::NewEmpty());
64 SkAutoTUnref<SkDataTable> table1(SkDataTable::NewCopyArrays(NULL, NULL, 0));
mike@reedtribe.org9ca81a72013-04-21 01:43:09 +000065 SkAutoTUnref<SkDataTable> table2(SkDataTable::NewCopyArray(NULL, 0, 0));
66 SkAutoTUnref<SkDataTable> table3(SkDataTable::NewArrayProc(NULL, 0, 0,
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000067 NULL, NULL));
68
69 test_datatable_is_empty(reporter, table0);
70 test_datatable_is_empty(reporter, table1);
71 test_datatable_is_empty(reporter, table2);
72 test_datatable_is_empty(reporter, table3);
73
74 test_is_equal(reporter, table0, table1);
75 test_is_equal(reporter, table0, table2);
76 test_is_equal(reporter, table0, table3);
77}
78
reed@google.com8c5c7a92013-04-19 20:16:01 +000079static void test_simpletable(skiatest::Reporter* reporter) {
80 const int idata[] = { 1, 4, 9, 16, 25, 63 };
81 int icount = SK_ARRAY_COUNT(idata);
82 SkAutoTUnref<SkDataTable> itable(SkDataTable::NewCopyArray(idata,
83 sizeof(idata[0]),
84 icount));
85 REPORTER_ASSERT(reporter, itable->count() == icount);
86 for (int i = 0; i < icount; ++i) {
87 size_t size;
88 REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000089 REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
reed@google.com8c5c7a92013-04-19 20:16:01 +000090 REPORTER_ASSERT(reporter, sizeof(int) == size);
91 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000092 test_datatable_flatten(reporter, itable);
reed@google.com8c5c7a92013-04-19 20:16:01 +000093}
94
95static void test_vartable(skiatest::Reporter* reporter) {
96 const char* str[] = {
97 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
98 };
99 int count = SK_ARRAY_COUNT(str);
100 size_t sizes[SK_ARRAY_COUNT(str)];
101 for (int i = 0; i < count; ++i) {
102 sizes[i] = strlen(str[i]) + 1;
103 }
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000104
reed@google.com8c5c7a92013-04-19 20:16:01 +0000105 SkAutoTUnref<SkDataTable> table(SkDataTable::NewCopyArrays(
106 (const void*const*)str, sizes, count));
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000107
reed@google.com8c5c7a92013-04-19 20:16:01 +0000108 REPORTER_ASSERT(reporter, table->count() == count);
109 for (int i = 0; i < count; ++i) {
110 size_t size;
111 REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000112 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +0000113 str[i]));
114 REPORTER_ASSERT(reporter, size == sizes[i]);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000115
reed@google.com8c5c7a92013-04-19 20:16:01 +0000116 const char* s = table->atStr(i);
117 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
118 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000119 test_datatable_flatten(reporter, table);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000120}
121
122static void test_tablebuilder(skiatest::Reporter* reporter) {
123 const char* str[] = {
124 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
125 };
126 int count = SK_ARRAY_COUNT(str);
127
128 SkDataTableBuilder builder(16);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000129
reed@google.com8c5c7a92013-04-19 20:16:01 +0000130 for (int i = 0; i < count; ++i) {
131 builder.append(str[i], strlen(str[i]) + 1);
132 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000133 SkAutoTUnref<SkDataTable> table(builder.detachDataTable());
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000134
reed@google.com8c5c7a92013-04-19 20:16:01 +0000135 REPORTER_ASSERT(reporter, table->count() == count);
136 for (int i = 0; i < count; ++i) {
137 size_t size;
138 REPORTER_ASSERT(reporter, table->atSize(i) == strlen(str[i]) + 1);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000139 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +0000140 str[i]));
141 REPORTER_ASSERT(reporter, size == strlen(str[i]) + 1);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000142
reed@google.com8c5c7a92013-04-19 20:16:01 +0000143 const char* s = table->atStr(i);
144 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
145 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000146 test_datatable_flatten(reporter, table);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000147}
148
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000149static void test_globaltable(skiatest::Reporter* reporter) {
150 static const int gData[] = {
151 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
152 };
153 int count = SK_ARRAY_COUNT(gData);
154
155 SkAutoTUnref<SkDataTable> table(SkDataTable::NewArrayProc(gData,
156 sizeof(gData[0]), count, NULL, NULL));
rmistry@google.comc9f3b382013-04-22 12:45:30 +0000157
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000158 REPORTER_ASSERT(reporter, table->count() == count);
159 for (int i = 0; i < count; ++i) {
160 size_t size;
161 REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
162 REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
163 REPORTER_ASSERT(reporter, sizeof(int) == size);
164 }
165 test_datatable_flatten(reporter, table);
166}
167
168static void TestDataTable(skiatest::Reporter* reporter) {
169 test_emptytable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000170 test_simpletable(reporter);
171 test_vartable(reporter);
172 test_tablebuilder(reporter);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000173 test_globaltable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000174}
175
reed@google.com91bd4592012-07-11 17:24:49 +0000176static void unrefAll(const SkDataSet::Pair pairs[], int count) {
177 for (int i = 0; i < count; ++i) {
178 pairs[i].fValue->unref();
179 }
180}
181
182// asserts that inner is a subset of outer
183static void test_dataset_subset(skiatest::Reporter* reporter,
184 const SkDataSet& outer, const SkDataSet& inner) {
185 SkDataSet::Iter iter(inner);
186 for (; !iter.done(); iter.next()) {
187 SkData* outerData = outer.find(iter.key());
188 REPORTER_ASSERT(reporter, outerData);
189 REPORTER_ASSERT(reporter, outerData->equals(iter.value()));
190 }
191}
192
193static void test_datasets_equal(skiatest::Reporter* reporter,
194 const SkDataSet& ds0, const SkDataSet& ds1) {
195 REPORTER_ASSERT(reporter, ds0.count() == ds1.count());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000196
reed@google.com91bd4592012-07-11 17:24:49 +0000197 test_dataset_subset(reporter, ds0, ds1);
198 test_dataset_subset(reporter, ds1, ds0);
199}
200
201static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds,
202 int count) {
203 REPORTER_ASSERT(reporter, ds.count() == count);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000204
reed@google.com91bd4592012-07-11 17:24:49 +0000205 SkDataSet::Iter iter(ds);
206 int index = 0;
207 for (; !iter.done(); iter.next()) {
humper@google.com05af1af2013-01-07 16:47:43 +0000208// const char* name = iter.key();
209// SkData* data = iter.value();
reed@google.com79382af2012-07-11 18:55:23 +0000210// SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes());
reed@google.com91bd4592012-07-11 17:24:49 +0000211 index += 1;
212 }
213 REPORTER_ASSERT(reporter, index == count);
214
215 SkDynamicMemoryWStream ostream;
216 ds.writeToStream(&ostream);
217 SkMemoryStream istream;
218 istream.setData(ostream.copyToData())->unref();
219 SkDataSet copy(&istream);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000220
reed@google.com91bd4592012-07-11 17:24:49 +0000221 test_datasets_equal(reporter, ds, copy);
222}
223
224static void test_dataset(skiatest::Reporter* reporter) {
225 SkDataSet set0(NULL, 0);
226 SkDataSet set1("hello", SkTUnref<SkData>(SkData::NewWithCString("world")));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000227
reed@google.com91bd4592012-07-11 17:24:49 +0000228 const SkDataSet::Pair pairs[] = {
229 { "one", SkData::NewWithCString("1") },
230 { "two", SkData::NewWithCString("2") },
231 { "three", SkData::NewWithCString("3") },
232 };
233 SkDataSet set3(pairs, 3);
234 unrefAll(pairs, 3);
235
236 test_dataset(reporter, set0, 0);
237 test_dataset(reporter, set1, 1);
238 test_dataset(reporter, set3, 3);
239}
reed@google.com1622c992011-06-14 19:22:21 +0000240
241static void* gGlobal;
242
243static void delete_int_proc(const void* ptr, size_t len, void* context) {
244 int* data = (int*)ptr;
245 SkASSERT(context == gGlobal);
246 delete[] data;
247}
248
reed@google.com8d0b5772011-06-24 13:07:31 +0000249static void assert_len(skiatest::Reporter* reporter, SkData* ref, size_t len) {
reed@google.com1622c992011-06-14 19:22:21 +0000250 REPORTER_ASSERT(reporter, ref->size() == len);
251}
252
reed@google.com8d0b5772011-06-24 13:07:31 +0000253static void assert_data(skiatest::Reporter* reporter, SkData* ref,
reed@google.com1622c992011-06-14 19:22:21 +0000254 const void* data, size_t len) {
255 REPORTER_ASSERT(reporter, ref->size() == len);
256 REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
257}
258
reed@google.comdbc936d2012-06-28 15:40:09 +0000259static void test_cstring(skiatest::Reporter* reporter) {
260 const char str[] = "Hello world";
261 size_t len = strlen(str);
262
reed@google.coma63a8512012-07-02 20:29:00 +0000263 SkAutoTUnref<SkData> r0(SkData::NewWithCopy(str, len + 1));
reed@google.comdbc936d2012-06-28 15:40:09 +0000264 SkAutoTUnref<SkData> r1(SkData::NewWithCString(str));
265
266 REPORTER_ASSERT(reporter, r0->equals(r1));
267
268 SkAutoTUnref<SkData> r2(SkData::NewWithCString(NULL));
reed@google.coma63a8512012-07-02 20:29:00 +0000269 REPORTER_ASSERT(reporter, 1 == r2->size());
270 REPORTER_ASSERT(reporter, 0 == *r2->bytes());
reed@google.comdbc936d2012-06-28 15:40:09 +0000271}
272
reed@google.com91bd4592012-07-11 17:24:49 +0000273static void TestData(skiatest::Reporter* reporter) {
reed@google.com1622c992011-06-14 19:22:21 +0000274 const char* str = "We the people, in order to form a more perfect union.";
275 const int N = 10;
276
reed@google.comdbc936d2012-06-28 15:40:09 +0000277 SkAutoTUnref<SkData> r0(SkData::NewEmpty());
278 SkAutoTUnref<SkData> r1(SkData::NewWithCopy(str, strlen(str)));
279 SkAutoTUnref<SkData> r2(SkData::NewWithProc(new int[N], N*sizeof(int),
280 delete_int_proc, gGlobal));
281 SkAutoTUnref<SkData> r3(SkData::NewSubset(r1, 7, 6));
reed@google.com1622c992011-06-14 19:22:21 +0000282
reed@google.com1622c992011-06-14 19:22:21 +0000283 assert_len(reporter, r0, 0);
284 assert_len(reporter, r1, strlen(str));
285 assert_len(reporter, r2, N * sizeof(int));
286 assert_len(reporter, r3, 6);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000287
reed@google.com1622c992011-06-14 19:22:21 +0000288 assert_data(reporter, r1, str, strlen(str));
289 assert_data(reporter, r3, "people", 6);
290
reed@google.com8d0b5772011-06-24 13:07:31 +0000291 SkData* tmp = SkData::NewSubset(r1, strlen(str), 10);
reed@google.com1622c992011-06-14 19:22:21 +0000292 assert_len(reporter, tmp, 0);
293 tmp->unref();
reed@google.com8d0b5772011-06-24 13:07:31 +0000294 tmp = SkData::NewSubset(r1, 0, 0);
reed@google.com1622c992011-06-14 19:22:21 +0000295 assert_len(reporter, tmp, 0);
296 tmp->unref();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000297
reed@google.comdbc936d2012-06-28 15:40:09 +0000298 test_cstring(reporter);
reed@google.com91bd4592012-07-11 17:24:49 +0000299 test_dataset(reporter);
reed@google.com1622c992011-06-14 19:22:21 +0000300}
301
302#include "TestClassDef.h"
reed@google.com91bd4592012-07-11 17:24:49 +0000303DEFINE_TESTCLASS("Data", DataTestClass, TestData)
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000304DEFINE_TESTCLASS("DataTable", DataTableTestClass, TestDataTable)