blob: ad4f1244ee9f9444f461a2951d54f5b78e6d7cca [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkData.h"
9#include "include/core/SkDataTable.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkRefCnt.h"
11#include "include/core/SkStream.h"
12#include "include/core/SkString.h"
13#include "include/core/SkTypes.h"
14#include "include/private/SkTArray.h"
15#include "include/private/SkTemplates.h"
16#include "src/core/SkOSFile.h"
17#include "src/core/SkTaskGroup.h"
18#include "src/utils/SkOSPath.h"
19#include "tests/Test.h"
reed@google.com91bd4592012-07-11 17:24:49 +000020
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040021#include <cstdio>
22#include <cstring>
23#include <memory>
Ben Wagnerd90cd3b2018-05-22 10:48:08 -040024
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000025static void test_is_equal(skiatest::Reporter* reporter,
26 const SkDataTable* a, const SkDataTable* b) {
27 REPORTER_ASSERT(reporter, a->count() == b->count());
28 for (int i = 0; i < a->count(); ++i) {
29 size_t sizea, sizeb;
30 const void* mema = a->at(i, &sizea);
31 const void* memb = b->at(i, &sizeb);
32 REPORTER_ASSERT(reporter, sizea == sizeb);
33 REPORTER_ASSERT(reporter, !memcmp(mema, memb, sizea));
34 }
35}
36
bungemanfeb3c1a2016-08-05 06:51:50 -070037static void test_datatable_is_empty(skiatest::Reporter* reporter, SkDataTable* table) {
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000038 REPORTER_ASSERT(reporter, table->isEmpty());
39 REPORTER_ASSERT(reporter, 0 == table->count());
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000040}
41
42static void test_emptytable(skiatest::Reporter* reporter) {
bungemanfeb3c1a2016-08-05 06:51:50 -070043 sk_sp<SkDataTable> table0(SkDataTable::MakeEmpty());
44 sk_sp<SkDataTable> table1(SkDataTable::MakeCopyArrays(nullptr, nullptr, 0));
45 sk_sp<SkDataTable> table2(SkDataTable::MakeCopyArray(nullptr, 0, 0));
46 sk_sp<SkDataTable> table3(SkDataTable::MakeArrayProc(nullptr, 0, 0, nullptr, nullptr));
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000047
bungemanfeb3c1a2016-08-05 06:51:50 -070048 test_datatable_is_empty(reporter, table0.get());
49 test_datatable_is_empty(reporter, table1.get());
50 test_datatable_is_empty(reporter, table2.get());
51 test_datatable_is_empty(reporter, table3.get());
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000052
bungemanfeb3c1a2016-08-05 06:51:50 -070053 test_is_equal(reporter, table0.get(), table1.get());
54 test_is_equal(reporter, table0.get(), table2.get());
55 test_is_equal(reporter, table0.get(), table3.get());
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000056}
57
reed@google.com8c5c7a92013-04-19 20:16:01 +000058static void test_simpletable(skiatest::Reporter* reporter) {
59 const int idata[] = { 1, 4, 9, 16, 25, 63 };
60 int icount = SK_ARRAY_COUNT(idata);
bungemanfeb3c1a2016-08-05 06:51:50 -070061 sk_sp<SkDataTable> itable(SkDataTable::MakeCopyArray(idata, sizeof(idata[0]), icount));
reed@google.com8c5c7a92013-04-19 20:16:01 +000062 REPORTER_ASSERT(reporter, itable->count() == icount);
63 for (int i = 0; i < icount; ++i) {
64 size_t size;
65 REPORTER_ASSERT(reporter, sizeof(int) == itable->atSize(i));
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000066 REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]);
reed@google.com8c5c7a92013-04-19 20:16:01 +000067 REPORTER_ASSERT(reporter, sizeof(int) == size);
68 }
69}
70
71static void test_vartable(skiatest::Reporter* reporter) {
72 const char* str[] = {
73 "", "a", "be", "see", "deigh", "ef", "ggggggggggggggggggggggggggg"
74 };
75 int count = SK_ARRAY_COUNT(str);
76 size_t sizes[SK_ARRAY_COUNT(str)];
77 for (int i = 0; i < count; ++i) {
78 sizes[i] = strlen(str[i]) + 1;
79 }
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +000080
bungemanfeb3c1a2016-08-05 06:51:50 -070081 sk_sp<SkDataTable> table(SkDataTable::MakeCopyArrays((const void*const*)str, sizes, count));
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +000082
reed@google.com8c5c7a92013-04-19 20:16:01 +000083 REPORTER_ASSERT(reporter, table->count() == count);
84 for (int i = 0; i < count; ++i) {
85 size_t size;
86 REPORTER_ASSERT(reporter, table->atSize(i) == sizes[i]);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000087 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size),
reed@google.com8c5c7a92013-04-19 20:16:01 +000088 str[i]));
89 REPORTER_ASSERT(reporter, size == sizes[i]);
skia.committer@gmail.com64b682c2013-04-20 07:01:07 +000090
reed@google.com8c5c7a92013-04-19 20:16:01 +000091 const char* s = table->atStr(i);
92 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i]));
93 }
94}
95
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +000096static void test_globaltable(skiatest::Reporter* reporter) {
97 static const int gData[] = {
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
99 };
100 int count = SK_ARRAY_COUNT(gData);
101
bungemanfeb3c1a2016-08-05 06:51:50 -0700102 sk_sp<SkDataTable> table(
103 SkDataTable::MakeArrayProc(gData, sizeof(gData[0]), count, nullptr, nullptr));
rmistry@google.comc9f3b382013-04-22 12:45:30 +0000104
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000105 REPORTER_ASSERT(reporter, table->count() == count);
106 for (int i = 0; i < count; ++i) {
107 size_t size;
108 REPORTER_ASSERT(reporter, table->atSize(i) == sizeof(int));
109 REPORTER_ASSERT(reporter, *table->atT<const char>(i, &size) == i);
110 REPORTER_ASSERT(reporter, sizeof(int) == size);
111 }
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000112}
113
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000114DEF_TEST(DataTable, reporter) {
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000115 test_emptytable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000116 test_simpletable(reporter);
117 test_vartable(reporter);
mike@reedtribe.orgcac3ae32013-04-21 01:37:46 +0000118 test_globaltable(reporter);
reed@google.com8c5c7a92013-04-19 20:16:01 +0000119}
120
reed@google.com1622c992011-06-14 19:22:21 +0000121static void* gGlobal;
122
reed6b7f34e2015-06-17 09:58:24 -0700123static void delete_int_proc(const void* ptr, void* context) {
reed@google.com1622c992011-06-14 19:22:21 +0000124 int* data = (int*)ptr;
125 SkASSERT(context == gGlobal);
126 delete[] data;
127}
128
bungeman38d909e2016-08-02 14:40:46 -0700129static void assert_len(skiatest::Reporter* reporter, const sk_sp<SkData>& ref, size_t len) {
reed@google.com1622c992011-06-14 19:22:21 +0000130 REPORTER_ASSERT(reporter, ref->size() == len);
131}
132
bungeman38d909e2016-08-02 14:40:46 -0700133static void assert_data(skiatest::Reporter* reporter, const sk_sp<SkData>& ref,
reed@google.com1622c992011-06-14 19:22:21 +0000134 const void* data, size_t len) {
135 REPORTER_ASSERT(reporter, ref->size() == len);
136 REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len));
137}
138
reed@google.comdbc936d2012-06-28 15:40:09 +0000139static void test_cstring(skiatest::Reporter* reporter) {
140 const char str[] = "Hello world";
141 size_t len = strlen(str);
142
bungeman38d909e2016-08-02 14:40:46 -0700143 sk_sp<SkData> r0(SkData::MakeWithCopy(str, len + 1));
144 sk_sp<SkData> r1(SkData::MakeWithCString(str));
reed@google.comdbc936d2012-06-28 15:40:09 +0000145
bungeman38d909e2016-08-02 14:40:46 -0700146 REPORTER_ASSERT(reporter, r0->equals(r1.get()));
reed@google.comdbc936d2012-06-28 15:40:09 +0000147
bungeman38d909e2016-08-02 14:40:46 -0700148 sk_sp<SkData> r2(SkData::MakeWithCString(nullptr));
reed@google.coma63a8512012-07-02 20:29:00 +0000149 REPORTER_ASSERT(reporter, 1 == r2->size());
150 REPORTER_ASSERT(reporter, 0 == *r2->bytes());
reed@google.comdbc936d2012-06-28 15:40:09 +0000151}
152
bungeman@google.com11c9a552013-06-03 17:10:35 +0000153static void test_files(skiatest::Reporter* reporter) {
halcanary87f3ba42015-01-20 09:30:20 -0800154 SkString tmpDir = skiatest::GetTmpDir();
scroggo@google.com99d43ff2013-06-07 14:30:36 +0000155 if (tmpDir.isEmpty()) {
bungeman@google.com11c9a552013-06-03 17:10:35 +0000156 return;
157 }
skia.committer@gmail.com11f2b442013-06-04 07:00:53 +0000158
tfarinaa8e2e152014-07-28 19:26:58 -0700159 SkString path = SkOSPath::Join(tmpDir.c_str(), "data_test");
skia.committer@gmail.com11f2b442013-06-04 07:00:53 +0000160
bungeman@google.com11c9a552013-06-03 17:10:35 +0000161 const char s[] = "abcdefghijklmnopqrstuvwxyz";
162 {
163 SkFILEWStream writer(path.c_str());
164 if (!writer.isValid()) {
halcanary@google.coma9325fa2014-01-10 14:58:10 +0000165 ERRORF(reporter, "Failed to create tmp file %s\n", path.c_str());
bungeman@google.com11c9a552013-06-03 17:10:35 +0000166 return;
167 }
168 writer.write(s, 26);
169 }
170
halcanaryd76be9c2015-11-20 13:47:49 -0800171 FILE* file = sk_fopen(path.c_str(), kRead_SkFILE_Flag);
bungeman38d909e2016-08-02 14:40:46 -0700172 sk_sp<SkData> r1(SkData::MakeFromFILE(file));
halcanary96fcdcc2015-08-27 07:41:13 -0700173 REPORTER_ASSERT(reporter, r1.get() != nullptr);
bungeman@google.com11c9a552013-06-03 17:10:35 +0000174 REPORTER_ASSERT(reporter, r1->size() == 26);
175 REPORTER_ASSERT(reporter, strncmp(static_cast<const char*>(r1->data()), s, 26) == 0);
skia.committer@gmail.com11f2b442013-06-04 07:00:53 +0000176
bungeman@google.com11c9a552013-06-03 17:10:35 +0000177 int fd = sk_fileno(file);
bungeman38d909e2016-08-02 14:40:46 -0700178 sk_sp<SkData> r2(SkData::MakeFromFD(fd));
halcanary96fcdcc2015-08-27 07:41:13 -0700179 REPORTER_ASSERT(reporter, r2.get() != nullptr);
bungeman@google.com11c9a552013-06-03 17:10:35 +0000180 REPORTER_ASSERT(reporter, r2->size() == 26);
181 REPORTER_ASSERT(reporter, strncmp(static_cast<const char*>(r2->data()), s, 26) == 0);
182}
183
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000184DEF_TEST(Data, reporter) {
reed@google.com1622c992011-06-14 19:22:21 +0000185 const char* str = "We the people, in order to form a more perfect union.";
186 const int N = 10;
187
bungeman38d909e2016-08-02 14:40:46 -0700188 sk_sp<SkData> r0(SkData::MakeEmpty());
189 sk_sp<SkData> r1(SkData::MakeWithCopy(str, strlen(str)));
190 sk_sp<SkData> r2(SkData::MakeWithProc(new int[N], N*sizeof(int), delete_int_proc, gGlobal));
191 sk_sp<SkData> r3(SkData::MakeSubset(r1.get(), 7, 6));
reed@google.com1622c992011-06-14 19:22:21 +0000192
reed@google.com1622c992011-06-14 19:22:21 +0000193 assert_len(reporter, r0, 0);
194 assert_len(reporter, r1, strlen(str));
195 assert_len(reporter, r2, N * sizeof(int));
196 assert_len(reporter, r3, 6);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000197
reed@google.com1622c992011-06-14 19:22:21 +0000198 assert_data(reporter, r1, str, strlen(str));
199 assert_data(reporter, r3, "people", 6);
200
bungeman38d909e2016-08-02 14:40:46 -0700201 sk_sp<SkData> tmp(SkData::MakeSubset(r1.get(), strlen(str), 10));
reed@google.com1622c992011-06-14 19:22:21 +0000202 assert_len(reporter, tmp, 0);
bungeman38d909e2016-08-02 14:40:46 -0700203 tmp = SkData::MakeSubset(r1.get(), 0, 0);
reed@google.com1622c992011-06-14 19:22:21 +0000204 assert_len(reporter, tmp, 0);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000205
reed@google.comdbc936d2012-06-28 15:40:09 +0000206 test_cstring(reporter);
bungeman@google.com11c9a552013-06-03 17:10:35 +0000207 test_files(reporter);
reed@google.com1622c992011-06-14 19:22:21 +0000208}
reed5b6db072015-04-28 17:50:31 -0700209
Mike Reed706f6b42020-02-17 11:54:25 -0500210DEF_TEST(Data_empty, reporter) {
211 sk_sp<SkData> array[] = {
212 SkData::MakeEmpty(),
213 SkData::MakeUninitialized(0),
214 SkData::MakeFromMalloc(sk_malloc_throw(0), 0),
215 SkData::MakeWithCopy("", 0),
216 SkData::MakeWithProc(nullptr, 0, [](const void*, void*){}, nullptr),
217 SkData::MakeWithoutCopy(nullptr, 0),
218 };
219 constexpr int N = SK_ARRAY_COUNT(array);
220
221 for (int i = 0; i < N; ++i) {
222 REPORTER_ASSERT(reporter, array[i]->size() == 0);
223 for (int j = 0; j < N; ++j) {
224 REPORTER_ASSERT(reporter, array[i]->equals(array[j].get()));
225 }
226 }
227}