1 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 */ 8 #include "Test.h" 9 #include "SkData.h" 10 #include "SkDataSet.h" 11 #include "SkDataTable.h" 12 #include "SkOrderedReadBuffer.h" 13 #include "SkOrderedWriteBuffer.h" 14 #include "SkOSFile.h" 15 #include "SkStream.h" 16 17 static 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 29 static 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 41 test_is_equal(reporter, table, newTable); 42 } 43 44 static 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 51 static void test_emptytable(skiatest::Reporter* reporter) { 52 SkAutoTUnref<SkDataTable> table0(SkDataTable::NewEmpty()); 53 SkAutoTUnref<SkDataTable> table1(SkDataTable::NewCopyArrays(NULL, NULL, 0)); 54 SkAutoTUnref<SkDataTable> table2(SkDataTable::NewCopyArray(NULL, 0, 0)); 55 SkAutoTUnref<SkDataTable> table3(SkDataTable::NewArrayProc(NULL, 0, 0, 56 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 68 static 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)); 78 REPORTER_ASSERT(reporter, *itable->atT<int>(i, &size) == idata[i]); 79 REPORTER_ASSERT(reporter, sizeof(int) == size); 80 } 81 test_datatable_flatten(reporter, itable); 82 } 83 84 static 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 } 93 94 SkAutoTUnref<SkDataTable> table(SkDataTable::NewCopyArrays( 95 (const void*const*)str, sizes, count)); 96 97 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]); 101 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size), 102 str[i])); 103 REPORTER_ASSERT(reporter, size == sizes[i]); 104 105 const char* s = table->atStr(i); 106 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i])); 107 } 108 test_datatable_flatten(reporter, table); 109 } 110 111 static 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); 118 119 for (int i = 0; i < count; ++i) { 120 builder.append(str[i], strlen(str[i]) + 1); 121 } 122 SkAutoTUnref<SkDataTable> table(builder.detachDataTable()); 123 124 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); 128 REPORTER_ASSERT(reporter, !strcmp(table->atT<const char>(i, &size), 129 str[i])); 130 REPORTER_ASSERT(reporter, size == strlen(str[i]) + 1); 131 132 const char* s = table->atStr(i); 133 REPORTER_ASSERT(reporter, strlen(s) == strlen(str[i])); 134 } 135 test_datatable_flatten(reporter, table); 136 } 137 138 static 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)); 146 147 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 157 static void TestDataTable(skiatest::Reporter* reporter) { 158 test_emptytable(reporter); 159 test_simpletable(reporter); 160 test_vartable(reporter); 161 test_tablebuilder(reporter); 162 test_globaltable(reporter); 163 } 164 165 static 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 172 static 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 182 static void test_datasets_equal(skiatest::Reporter* reporter, 183 const SkDataSet& ds0, const SkDataSet& ds1) { 184 REPORTER_ASSERT(reporter, ds0.count() == ds1.count()); 185 186 test_dataset_subset(reporter, ds0, ds1); 187 test_dataset_subset(reporter, ds1, ds0); 188 } 189 190 static void test_dataset(skiatest::Reporter* reporter, const SkDataSet& ds, 191 int count) { 192 REPORTER_ASSERT(reporter, ds.count() == count); 193 194 SkDataSet::Iter iter(ds); 195 int index = 0; 196 for (; !iter.done(); iter.next()) { 197 // const char* name = iter.key(); 198 // SkData* data = iter.value(); 199 // SkDebugf("[%d] %s:%s\n", index, name, (const char*)data->bytes()); 200 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); 209 210 test_datasets_equal(reporter, ds, copy); 211 } 212 213 static void test_dataset(skiatest::Reporter* reporter) { 214 SkDataSet set0(NULL, 0); 215 SkDataSet set1("hello", SkAutoTUnref<SkData>(SkData::NewWithCString("world"))); 216 217 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 } 229 230 static void* gGlobal; 231 232 static 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 238 static void assert_len(skiatest::Reporter* reporter, SkData* ref, size_t len) { 239 REPORTER_ASSERT(reporter, ref->size() == len); 240 } 241 242 static void assert_data(skiatest::Reporter* reporter, SkData* ref, 243 const void* data, size_t len) { 244 REPORTER_ASSERT(reporter, ref->size() == len); 245 REPORTER_ASSERT(reporter, !memcmp(ref->data(), data, len)); 246 } 247 248 static void test_cstring(skiatest::Reporter* reporter) { 249 const char str[] = "Hello world"; 250 size_t len = strlen(str); 251 252 SkAutoTUnref<SkData> r0(SkData::NewWithCopy(str, len + 1)); 253 SkAutoTUnref<SkData> r1(SkData::NewWithCString(str)); 254 255 REPORTER_ASSERT(reporter, r0->equals(r1)); 256 257 SkAutoTUnref<SkData> r2(SkData::NewWithCString(NULL)); 258 REPORTER_ASSERT(reporter, 1 == r2->size()); 259 REPORTER_ASSERT(reporter, 0 == *r2->bytes()); 260 } 261 262 static void test_files(skiatest::Reporter* reporter) { 263 SkString tmpDir = skiatest::Test::GetTmpDir(); 264 if (tmpDir.isEmpty()) { 265 return; 266 } 267 268 SkString path = SkOSPath::SkPathJoin(tmpDir.c_str(), "data_test"); 269 270 const char s[] = "abcdefghijklmnopqrstuvwxyz"; 271 { 272 SkFILEWStream writer(path.c_str()); 273 if (!writer.isValid()) { 274 SkString msg; 275 msg.printf("Failed to create tmp file %s\n", path.c_str()); 276 reporter->reportFailed(msg); 277 return; 278 } 279 writer.write(s, 26); 280 } 281 282 SkFILE* file = sk_fopen(path.c_str(), kRead_SkFILE_Flag); 283 SkAutoTUnref<SkData> r1(SkData::NewFromFILE(file)); 284 REPORTER_ASSERT(reporter, r1.get() != NULL); 285 REPORTER_ASSERT(reporter, r1->size() == 26); 286 REPORTER_ASSERT(reporter, strncmp(static_cast<const char*>(r1->data()), s, 26) == 0); 287 288 int fd = sk_fileno(file); 289 SkAutoTUnref<SkData> r2(SkData::NewFromFD(fd)); 290 REPORTER_ASSERT(reporter, r2.get() != NULL); 291 REPORTER_ASSERT(reporter, r2->size() == 26); 292 REPORTER_ASSERT(reporter, strncmp(static_cast<const char*>(r2->data()), s, 26) == 0); 293 } 294 295 static void TestData(skiatest::Reporter* reporter) { 296 const char* str = "We the people, in order to form a more perfect union."; 297 const int N = 10; 298 299 SkAutoTUnref<SkData> r0(SkData::NewEmpty()); 300 SkAutoTUnref<SkData> r1(SkData::NewWithCopy(str, strlen(str))); 301 SkAutoTUnref<SkData> r2(SkData::NewWithProc(new int[N], N*sizeof(int), 302 delete_int_proc, gGlobal)); 303 SkAutoTUnref<SkData> r3(SkData::NewSubset(r1, 7, 6)); 304 305 assert_len(reporter, r0, 0); 306 assert_len(reporter, r1, strlen(str)); 307 assert_len(reporter, r2, N * sizeof(int)); 308 assert_len(reporter, r3, 6); 309 310 assert_data(reporter, r1, str, strlen(str)); 311 assert_data(reporter, r3, "people", 6); 312 313 SkData* tmp = SkData::NewSubset(r1, strlen(str), 10); 314 assert_len(reporter, tmp, 0); 315 tmp->unref(); 316 tmp = SkData::NewSubset(r1, 0, 0); 317 assert_len(reporter, tmp, 0); 318 tmp->unref(); 319 320 test_cstring(reporter); 321 test_dataset(reporter); 322 test_files(reporter); 323 } 324 325 #include "TestClassDef.h" 326 DEFINE_TESTCLASS("Data", DataTestClass, TestData) 327 DEFINE_TESTCLASS("DataTable", DataTableTestClass, TestDataTable) 328