blob: 9ff7034ca0247370aaa0244b3170bff7400c2ccb [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"
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000012#include "SkOrderedReadBuffer.h"
13#include "SkOrderedWriteBuffer.h"
bungeman@google.com11c9a552013-06-03 17:10:35 +000014#include "SkOSFile.h"
15#include "SkStream.h"
reed@google.com91bd4592012-07-11 17:24:49 +000016
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000017static void test_is_equal(skiatest::Reporter* reporter,
18 const SkDataTable* a, const SkDataTable* b) {
19 REPORTER_ASSERT(reporter, a->count() == b->count());
20 for (int i = 0; i < a->count(); ++i) {
21 size_t sizea, sizeb;
22 const void* mema = a->at(i, &sizea);
23 const void* memb = b->at(i, &sizeb);
24 REPORTER_ASSERT(reporter, sizea == sizeb);
25 REPORTER_ASSERT(reporter, !memcmp(mema, memb, sizea));
26 }
27}
28
29static void test_datatable_flatten(skiatest::Reporter* reporter,
30 SkDataTable* table) {
31 SkOrderedWriteBuffer wb(1024);
32 wb.writeFlattenable(table);
33
34 size_t wsize = wb.size();
35 SkAutoMalloc storage(wsize);
36 wb.writeToMemory(storage.get());
37
38 SkOrderedReadBuffer rb(storage.get(), wsize);
39 SkAutoTUnref<SkDataTable> newTable((SkDataTable*)rb.readFlattenable());
40
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000041 test_is_equal(reporter, table, newTable);
42}
43
44static void test_datatable_is_empty(skiatest::Reporter* reporter,
45 SkDataTable* table) {
46 REPORTER_ASSERT(reporter, table->isEmpty());
47 REPORTER_ASSERT(reporter, 0 == table->count());
48 test_datatable_flatten(reporter, table);
49}
50
51static void test_emptytable(skiatest::Reporter* reporter) {
52 SkAutoTUnref<SkDataTable> table0(SkDataTable::NewEmpty());
53 SkAutoTUnref<SkDataTable> table1(SkDataTable::NewCopyArrays(NULL, NULL, 0));
mike@reedtribe.org9ca81a72013-04-21 01:43:09 +000054 SkAutoTUnref<SkDataTable> table2(SkDataTable::NewCopyArray(NULL, 0, 0));
55 SkAutoTUnref<SkDataTable> table3(SkDataTable::NewArrayProc(NULL, 0, 0,
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000056 NULL, NULL));
57
58 test_datatable_is_empty(reporter, table0);
59 test_datatable_is_empty(reporter, table1);
60 test_datatable_is_empty(reporter, table2);
61 test_datatable_is_empty(reporter, table3);
62
63 test_is_equal(reporter, table0, table1);
64 test_is_equal(reporter, table0, table2);
65 test_is_equal(reporter, table0, table3);
66}
67
reed@google.com8c5c7a92013-04-19 20:16:01 +000068static void test_simpletable(skiatest::Reporter* reporter) {
69 const int idata[] = { 1, 4, 9, 16, 25, 63 };
70 int icount = SK_ARRAY_COUNT(idata);
71 SkAutoTUnref<SkDataTable> itable(SkDataTable::NewCopyArray(idata,
72 sizeof(idata[0]),
73 icount));
74 REPORTER_ASSERT(reporter, itable->count() == icount);
75 for (int i = 0; i < icount; ++i) {
76 size_t size;
77 REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000078 REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
reed@google.com8c5c7a92013-04-19 20:16:01 +000079 REPORTER_ASSERT(reporter, sizeof(int) == size);
80 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000081 test_datatable_flatten(reporter, itable);
reed@google.com8c5c7a92013-04-19 20:16:01 +000082}
83
84static void test_vartable(skiatest::Reporter* reporter) {
85 const char* str[] = {
86 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
87 };
88 int count = SK_ARRAY_COUNT(str);
89 size_t sizes[SK_ARRAY_COUNT(str)];
90 for (int i = 0; i < count; ++i) {
91 sizes[i] = strlen(str[i]) + 1;
92 }
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +000093
reed@google.com8c5c7a92013-04-19 20:16:01 +000094 SkAutoTUnref<SkDataTable> table(SkDataTable::NewCopyArrays(
95 (const void*const*)str, sizes, count));
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +000096
reed@google.com8c5c7a92013-04-19 20:16:01 +000097 REPORTER_ASSERT(reporter, table->count() == count);
98 for (int i = 0; i < count; ++i) {
99 size_t size;
100 REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000101 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +0000102 str[i]));
103 REPORTER_ASSERT(reporter, size == sizes[i]);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000104
reed@google.com8c5c7a92013-04-19 20:16:01 +0000105 const char* s = table->atStr(i);
106 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
107 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000108 test_datatable_flatten(reporter, table);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000109}
110
111static void test_tablebuilder(skiatest::Reporter* reporter) {
112 const char* str[] = {
113 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
114 };
115 int count = SK_ARRAY_COUNT(str);
116
117 SkDataTableBuilder builder(16);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000118
reed@google.com8c5c7a92013-04-19 20:16:01 +0000119 for (int i = 0; i < count; ++i) {
120 builder.append(str[i], strlen(str[i]) + 1);
121 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000122 SkAutoTUnref<SkDataTable> table(builder.detachDataTable());
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000123
reed@google.com8c5c7a92013-04-19 20:16:01 +0000124 REPORTER_ASSERT(reporter, table->count() == count);
125 for (int i = 0; i < count; ++i) {
126 size_t size;
127 REPORTER_ASSERT(reporter, table->atSize(i) == strlen(str[i]) + 1);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000128 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +0000129 str[i]));
130 REPORTER_ASSERT(reporter, size == strlen(str[i]) + 1);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +0000131
reed@google.com8c5c7a92013-04-19 20:16:01 +0000132 const char* s = table->atStr(i);
133 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
134 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000135 test_datatable_flatten(reporter, table);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000136}
137
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000138static void test_globaltable(skiatest::Reporter* reporter) {
139 static const int gData[] = {
140 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
141 };
142 int count = SK_ARRAY_COUNT(gData);
143
144 SkAutoTUnref<SkDataTable> table(SkDataTable::NewArrayProc(gData,
145 sizeof(gData[0]), count, NULL, NULL));
rmistry@google.comc9f3b382013-04-22 12:45:30 +0000146
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000147 REPORTER_ASSERT(reporter, table->count() == count);
148 for (int i = 0; i < count; ++i) {
149 size_t size;
150 REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
151 REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
152 REPORTER_ASSERT(reporter, sizeof(int) == size);
153 }
154 test_datatable_flatten(reporter, table);
155}
156
157static void TestDataTable(skiatest::Reporter* reporter) {
158 test_emptytable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000159 test_simpletable(reporter);
160 test_vartable(reporter);
161 test_tablebuilder(reporter);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000162 test_globaltable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000163}
164
reed@google.com91bd4592012-07-11 17:24:49 +0000165static void unrefAll(const SkDataSet::Pair pairs[], int count) {
166 for (int i = 0; i < count; ++i) {
167 pairs[i].fValue->unref();
168 }
169}
170
171// asserts that inner is a subset of outer
172static void test_dataset_subset(skiatest::Reporter* reporter,
173 const SkDataSet& outer, const SkDataSet& inner) {
174 SkDataSet::Iter iter(inner);
175 for (; !iter.done(); iter.next()) {
176 SkData* outerData = outer.find(iter.key());
177 REPORTER_ASSERT(reporter, outerData);
178 REPORTER_ASSERT(reporter, outerData->equals(iter.value()));
179 }
180}
181
182static void test_datasets_equal(skiatest::Reporter* reporter,
183 const SkDataSet& ds0, const SkDataSet& ds1) {
184 REPORTER_ASSERT(reporter, ds0.count() == ds1.count());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000185
reed@google.com91bd4592012-07-11 17:24:49 +0000186 test_dataset_subset(reporter, ds0, ds1);
187 test_dataset_subset(reporter, ds1, ds0);
188}
189
190static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds,
191 int count) {
192 REPORTER_ASSERT(reporter, ds.count() == count);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000193
reed@google.com91bd4592012-07-11 17:24:49 +0000194 SkDataSet::Iter iter(ds);
195 int index = 0;
196 for (; !iter.done(); iter.next()) {
humper@google.com05af1af2013-01-07 16:47:43 +0000197// const char* name = iter.key();
198// SkData* data = iter.value();
reed@google.com79382af2012-07-11 18:55:23 +0000199// SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes());
reed@google.com91bd4592012-07-11 17:24:49 +0000200 index += 1;
201 }
202 REPORTER_ASSERT(reporter, index == count);
203
204 SkDynamicMemoryWStream ostream;
205 ds.writeToStream(&ostream);
206 SkMemoryStream istream;
207 istream.setData(ostream.copyToData())->unref();
208 SkDataSet copy(&istream);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000209
reed@google.com91bd4592012-07-11 17:24:49 +0000210 test_datasets_equal(reporter, ds, copy);
211}
212
213static void test_dataset(skiatest::Reporter* reporter) {
214 SkDataSet set0(NULL, 0);
bungeman@google.com11c9a552013-06-03 17:10:35 +0000215 SkDataSet set1("hello", SkAutoTUnref<SkData>(SkData::NewWithCString("world")));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000216
reed@google.com91bd4592012-07-11 17:24:49 +0000217 const SkDataSet::Pair pairs[] = {
218 { "one", SkData::NewWithCString("1") },
219 { "two", SkData::NewWithCString("2") },
220 { "three", SkData::NewWithCString("3") },
221 };
222 SkDataSet set3(pairs, 3);
223 unrefAll(pairs, 3);
224
225 test_dataset(reporter, set0, 0);
226 test_dataset(reporter, set1, 1);
227 test_dataset(reporter, set3, 3);
228}
reed@google.com1622c992011-06-14 19:22:21 +0000229
230static void* gGlobal;
231
232static void delete_int_proc(const void* ptr, size_t len, void* context) {
233 int* data = (int*)ptr;
234 SkASSERT(context == gGlobal);
235 delete[] data;
236}
237
reed@google.com8d0b5772011-06-24 13:07:31 +0000238static void assert_len(skiatest::Reporter* reporter, SkData* ref, size_t len) {
reed@google.com1622c992011-06-14 19:22:21 +0000239 REPORTER_ASSERT(reporter, ref->size() == len);
240}
241
reed@google.com8d0b5772011-06-24 13:07:31 +0000242static void assert_data(skiatest::Reporter* reporter, SkData* ref,
reed@google.com1622c992011-06-14 19:22:21 +0000243 const void* data, size_t len) {
244 REPORTER_ASSERT(reporter, ref->size() == len);
245 REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
246}
247
reed@google.comdbc936d2012-06-28 15:40:09 +0000248static void test_cstring(skiatest::Reporter* reporter) {
249 const char str[] = "Hello world";
250 size_t len = strlen(str);
251
reed@google.coma63a8512012-07-02 20:29:00 +0000252 SkAutoTUnref<SkData> r0(SkData::NewWithCopy(str, len + 1));
reed@google.comdbc936d2012-06-28 15:40:09 +0000253 SkAutoTUnref<SkData> r1(SkData::NewWithCString(str));
254
255 REPORTER_ASSERT(reporter, r0->equals(r1));
256
257 SkAutoTUnref<SkData> r2(SkData::NewWithCString(NULL));
reed@google.coma63a8512012-07-02 20:29:00 +0000258 REPORTER_ASSERT(reporter, 1 == r2->size());
259 REPORTER_ASSERT(reporter, 0 == *r2->bytes());
reed@google.comdbc936d2012-06-28 15:40:09 +0000260}
261
bungeman@google.com11c9a552013-06-03 17:10:35 +0000262static void test_files(skiatest::Reporter* reporter) {
263 if (skiatest::Test::GetTmpDir().isEmpty()) {
264 return;
265 }
skia.committer@gmail.com11f2b442013-06-04 07:00:53 +0000266
bungeman@google.com11c9a552013-06-03 17:10:35 +0000267 const char* tmpDir = skiatest::Test::GetTmpDir().c_str();
268 SkString path;
269 path.printf("%s%s", tmpDir, "data_test");
skia.committer@gmail.com11f2b442013-06-04 07:00:53 +0000270
bungeman@google.com11c9a552013-06-03 17:10:35 +0000271 const char s[] = "abcdefghijklmnopqrstuvwxyz";
272 {
273 SkFILEWStream writer(path.c_str());
274 if (!writer.isValid()) {
275 SkString msg;
276 msg.printf("Failed to create tmp file %s\n", path.c_str());
277 reporter->reportFailed(msg.c_str());
278 return;
279 }
280 writer.write(s, 26);
281 }
282
283 SkFILE* file = sk_fopen(path.c_str(), kRead_SkFILE_Flag);
284 SkAutoTUnref<SkData> r1(SkData::NewFromFILE(file));
285 REPORTER_ASSERT(reporter, r1.get() != NULL);
286 REPORTER_ASSERT(reporter, r1->size() == 26);
287 REPORTER_ASSERT(reporter, strncmp(static_cast<const char*>(r1->data()), s, 26) == 0);
skia.committer@gmail.com11f2b442013-06-04 07:00:53 +0000288
bungeman@google.com11c9a552013-06-03 17:10:35 +0000289 int fd = sk_fileno(file);
290 SkAutoTUnref<SkData> r2(SkData::NewFromFD(fd));
291 REPORTER_ASSERT(reporter, r2.get() != NULL);
292 REPORTER_ASSERT(reporter, r2->size() == 26);
293 REPORTER_ASSERT(reporter, strncmp(static_cast<const char*>(r2->data()), s, 26) == 0);
294}
295
reed@google.com91bd4592012-07-11 17:24:49 +0000296static void TestData(skiatest::Reporter* reporter) {
reed@google.com1622c992011-06-14 19:22:21 +0000297 const char* str = "We the people, in order to form a more perfect union.";
298 const int N = 10;
299
reed@google.comdbc936d2012-06-28 15:40:09 +0000300 SkAutoTUnref<SkData> r0(SkData::NewEmpty());
301 SkAutoTUnref<SkData> r1(SkData::NewWithCopy(str, strlen(str)));
302 SkAutoTUnref<SkData> r2(SkData::NewWithProc(new int[N], N*sizeof(int),
303 delete_int_proc, gGlobal));
304 SkAutoTUnref<SkData> r3(SkData::NewSubset(r1, 7, 6));
reed@google.com1622c992011-06-14 19:22:21 +0000305
reed@google.com1622c992011-06-14 19:22:21 +0000306 assert_len(reporter, r0, 0);
307 assert_len(reporter, r1, strlen(str));
308 assert_len(reporter, r2, N * sizeof(int));
309 assert_len(reporter, r3, 6);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000310
reed@google.com1622c992011-06-14 19:22:21 +0000311 assert_data(reporter, r1, str, strlen(str));
312 assert_data(reporter, r3, "people", 6);
313
reed@google.com8d0b5772011-06-24 13:07:31 +0000314 SkData* tmp = SkData::NewSubset(r1, strlen(str), 10);
reed@google.com1622c992011-06-14 19:22:21 +0000315 assert_len(reporter, tmp, 0);
316 tmp->unref();
reed@google.com8d0b5772011-06-24 13:07:31 +0000317 tmp = SkData::NewSubset(r1, 0, 0);
reed@google.com1622c992011-06-14 19:22:21 +0000318 assert_len(reporter, tmp, 0);
319 tmp->unref();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000320
reed@google.comdbc936d2012-06-28 15:40:09 +0000321 test_cstring(reporter);
reed@google.com91bd4592012-07-11 17:24:49 +0000322 test_dataset(reporter);
bungeman@google.com11c9a552013-06-03 17:10:35 +0000323 test_files(reporter);
reed@google.com1622c992011-06-14 19:22:21 +0000324}
325
326#include "TestClassDef.h"
reed@google.com91bd4592012-07-11 17:24:49 +0000327DEFINE_TESTCLASS("Data", DataTestClass, TestData)
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000328DEFINE_TESTCLASS("DataTable", DataTableTestClass, TestDataTable)