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 "SkRandom.h" 10 #include "SkStream.h" 11 #include "SkData.h" 12 13 #define MAX_SIZE (256 * 1024) 14 15 static void random_fill(SkRandom& rand, void* buffer, size_t size) { 16 char* p = (char*)buffer; 17 char* stop = p + size; 18 while (p < stop) { 19 *p++ = (char)(rand.nextU() >> 8); 20 } 21 } 22 23 static void test_buffer(skiatest::Reporter* reporter) { 24 SkRandom rand; 25 SkAutoMalloc am(MAX_SIZE * 2); 26 char* storage = (char*)am.get(); 27 char* storage2 = storage + MAX_SIZE; 28 29 random_fill(rand, storage, MAX_SIZE); 30 31 for (int sizeTimes = 0; sizeTimes < 100; sizeTimes++) { 32 int size = rand.nextU() % MAX_SIZE; 33 if (size == 0) { 34 size = MAX_SIZE; 35 } 36 for (int times = 0; times < 100; times++) { 37 int bufferSize = 1 + (rand.nextU() & 0xFFFF); 38 SkMemoryStream mstream(storage, size); 39 SkBufferStream bstream(&mstream, bufferSize); 40 41 int bytesRead = 0; 42 while (bytesRead < size) { 43 int s = 17 + (rand.nextU() & 0xFFFF); 44 int ss = bstream.read(storage2, s); 45 REPORTER_ASSERT(reporter, ss > 0 && ss <= s); 46 REPORTER_ASSERT(reporter, bytesRead + ss <= size); 47 REPORTER_ASSERT(reporter, 48 memcmp(storage + bytesRead, storage2, ss) == 0); 49 bytesRead += ss; 50 } 51 REPORTER_ASSERT(reporter, bytesRead == size); 52 } 53 } 54 } 55 56 static void TestRStream(skiatest::Reporter* reporter) { 57 static const char s[] = 58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 59 char copy[sizeof(s)]; 60 SkRandom rand; 61 62 for (int i = 0; i < 65; i++) { 63 char* copyPtr = copy; 64 SkMemoryStream mem(s, sizeof(s)); 65 SkBufferStream buff(&mem, i); 66 67 do { 68 copyPtr += buff.read(copyPtr, rand.nextU() & 15); 69 } while (copyPtr < copy + sizeof(s)); 70 REPORTER_ASSERT(reporter, copyPtr == copy + sizeof(s)); 71 REPORTER_ASSERT(reporter, memcmp(s, copy, sizeof(s)) == 0); 72 } 73 test_buffer(reporter); 74 } 75 76 static void TestWStream(skiatest::Reporter* reporter) { 77 SkDynamicMemoryWStream ds; 78 const char s[] = "abcdefghijklmnopqrstuvwxyz"; 79 int i; 80 for (i = 0; i < 100; i++) { 81 REPORTER_ASSERT(reporter, ds.write(s, 26)); 82 } 83 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26); 84 char* dst = new char[100 * 26 + 1]; 85 dst[100*26] = '*'; 86 ds.copyTo(dst); 87 REPORTER_ASSERT(reporter, dst[100*26] == '*'); 88 // char* p = dst; 89 for (i = 0; i < 100; i++) { 90 REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0); 91 } 92 93 { 94 SkData* data = ds.copyToData(); 95 REPORTER_ASSERT(reporter, 100 * 26 == data->size()); 96 REPORTER_ASSERT(reporter, memcmp(dst, data->data(), data->size()) == 0); 97 data->unref(); 98 } 99 delete[] dst; 100 } 101 102 static void TestPackedUInt(skiatest::Reporter* reporter) { 103 // we know that packeduint tries to write 1, 2 or 4 bytes for the length, 104 // so we test values around each of those transitions (and a few others) 105 const size_t sizes[] = { 106 0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769, 107 0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001, 108 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001, 109 0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF 110 }; 111 112 113 size_t i; 114 char buffer[sizeof(sizes) * 4]; 115 116 SkMemoryWStream wstream(buffer, sizeof(buffer)); 117 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) { 118 bool success = wstream.writePackedUInt(sizes[i]); 119 REPORTER_ASSERT(reporter, success); 120 } 121 wstream.flush(); 122 123 SkMemoryStream rstream(buffer, sizeof(buffer)); 124 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) { 125 size_t n = rstream.readPackedUInt(); 126 if (sizes[i] != n) { 127 SkDebugf("-- %d: sizes:%x n:%x\n", i, sizes[i], n); 128 } 129 REPORTER_ASSERT(reporter, sizes[i] == n); 130 } 131 } 132 133 // Test that setting an SkMemoryStream to a NULL data does not result in a crash when calling 134 // methods that access fData. 135 static void TestDereferencingData(SkMemoryStream* memStream) { 136 memStream->read(NULL, 0); 137 memStream->getMemoryBase(); 138 SkAutoDataUnref data(memStream->copyToData()); 139 } 140 141 static void TestNullData() { 142 SkData* nullData = NULL; 143 SkMemoryStream memStream(nullData); 144 TestDereferencingData(&memStream); 145 146 memStream.setData(nullData); 147 TestDereferencingData(&memStream); 148 149 } 150 151 static void TestStreams(skiatest::Reporter* reporter) { 152 TestRStream(reporter); 153 TestWStream(reporter); 154 TestPackedUInt(reporter); 155 TestNullData(); 156 } 157 158 #include "TestClassDef.h" 159 DEFINE_TESTCLASS("Stream", StreamTestClass, TestStreams) 160