Writer32Test.cpp revision cae5d8d5705081cb4d22af7a30be0f01bffce745
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 9 10 11#include "SkRandom.h" 12#include "SkReader32.h" 13#include "SkWriter32.h" 14#include "Test.h" 15 16static void check_contents(skiatest::Reporter* reporter, const SkWriter32& writer, 17 const void* expected, size_t size) { 18 SkAutoSMalloc<256> storage(size); 19 REPORTER_ASSERT(reporter, writer.bytesWritten() == size); 20 writer.flatten(storage.get()); 21 REPORTER_ASSERT(reporter, !memcmp(storage.get(), expected, size)); 22} 23 24static void test_rewind(skiatest::Reporter* reporter) { 25 SkSWriter32<32> writer(32); 26 int32_t array[3] = { 1, 2, 4 }; 27 28 REPORTER_ASSERT(reporter, 0 == writer.bytesWritten()); 29 for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) { 30 writer.writeInt(array[i]); 31 } 32 check_contents(reporter, writer, array, sizeof(array)); 33 34 writer.rewindToOffset(2*sizeof(int32_t)); 35 REPORTER_ASSERT(reporter, sizeof(array) - 4 == writer.bytesWritten()); 36 writer.writeInt(3); 37 REPORTER_ASSERT(reporter, sizeof(array) == writer.bytesWritten()); 38 array[2] = 3; 39 check_contents(reporter, writer, array, sizeof(array)); 40 41 // test rewinding past allocated chunks. This used to crash because we 42 // didn't truncate our link-list after freeing trailing blocks 43 { 44 SkWriter32 writer(64); 45 for (int i = 0; i < 100; ++i) { 46 writer.writeInt(i); 47 } 48 REPORTER_ASSERT(reporter, 100*4 == writer.bytesWritten()); 49 for (int j = 100*4; j >= 0; j -= 16) { 50 writer.rewindToOffset(j); 51 } 52 REPORTER_ASSERT(reporter, writer.bytesWritten() < 16); 53 } 54} 55 56static void test_ptr(skiatest::Reporter* reporter) { 57 SkSWriter32<32> writer(32); 58 59 void* p0 = reporter; 60 void* p1 = &writer; 61 62 // try writing ptrs where at least one of them may be at a non-multiple of 63 // 8 boundary, to confirm this works on 64bit machines. 64 65 writer.writePtr(p0); 66 writer.write8(0x33); 67 writer.writePtr(p1); 68 writer.write8(0x66); 69 70 size_t size = writer.size(); 71 REPORTER_ASSERT(reporter, 2 * sizeof(void*) + 2 * sizeof(int32_t)); 72 73 char buffer[32]; 74 SkASSERT(sizeof(buffer) >= size); 75 writer.flatten(buffer); 76 77 SkReader32 reader(buffer, size); 78 REPORTER_ASSERT(reporter, reader.readPtr() == p0); 79 REPORTER_ASSERT(reporter, reader.readInt() == 0x33); 80 REPORTER_ASSERT(reporter, reader.readPtr() == p1); 81 REPORTER_ASSERT(reporter, reader.readInt() == 0x66); 82} 83 84static void test1(skiatest::Reporter* reporter, SkWriter32* writer) { 85 const uint32_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 86 for (size_t i = 0; i < SK_ARRAY_COUNT(data); ++i) { 87 REPORTER_ASSERT(reporter, i*4 == writer->size()); 88 writer->write32(data[i]); 89 uint32_t* addr = writer->peek32(i * 4); 90 REPORTER_ASSERT(reporter, data[i] == *addr); 91 } 92 93 char buffer[sizeof(data)]; 94 REPORTER_ASSERT(reporter, sizeof(buffer) == writer->size()); 95 writer->flatten(buffer); 96 REPORTER_ASSERT(reporter, !memcmp(data, buffer, sizeof(buffer))); 97} 98 99static void test2(skiatest::Reporter* reporter, SkWriter32* writer) { 100 static const char gStr[] = "abcdefghimjklmnopqrstuvwxyz"; 101 size_t i; 102 103 size_t len = 0; 104 for (i = 0; i <= 26; ++i) { 105 len += SkWriter32::WriteStringSize(gStr, i); 106 writer->writeString(gStr, i); 107 } 108 REPORTER_ASSERT(reporter, writer->size() == len); 109 110 SkAutoMalloc storage(len); 111 writer->flatten(storage.get()); 112 113 SkReader32 reader; 114 reader.setMemory(storage.get(), len); 115 for (i = 0; i <= 26; ++i) { 116 REPORTER_ASSERT(reporter, !reader.eof()); 117 const char* str = reader.readString(&len); 118 REPORTER_ASSERT(reporter, i == len); 119 REPORTER_ASSERT(reporter, strlen(str) == len); 120 REPORTER_ASSERT(reporter, !memcmp(str, gStr, len)); 121 // Ensure that the align4 of the string is padded with zeroes. 122 size_t alignedSize = SkAlign4(len + 1); 123 for (size_t j = len; j < alignedSize; j++) { 124 REPORTER_ASSERT(reporter, 0 == str[j]); 125 } 126 } 127 REPORTER_ASSERT(reporter, reader.eof()); 128} 129 130static void testWritePad(skiatest::Reporter* reporter, SkWriter32* writer) { 131 // Create some random data to write. 132 const size_t dataSize = 10<<2; 133 SkASSERT(SkIsAlign4(dataSize)); 134 135 SkAutoMalloc originalData(dataSize); 136 { 137 SkMWCRandom rand(0); 138 uint32_t* ptr = static_cast<uint32_t*>(originalData.get()); 139 uint32_t* stop = ptr + (dataSize>>2); 140 while (ptr < stop) { 141 *ptr++ = rand.nextU(); 142 } 143 144 // Write the random data to the writer at different lengths for 145 // different alignments. 146 for (size_t len = 0; len < dataSize; len++) { 147 writer->writePad(originalData.get(), len); 148 } 149 } 150 151 uint32_t totalBytes = writer->size(); 152 153 SkAutoMalloc readStorage(totalBytes); 154 writer->flatten(readStorage.get()); 155 156 SkReader32 reader; 157 reader.setMemory(readStorage.get(), totalBytes); 158 159 for (size_t len = 0; len < dataSize; len++) { 160 const char* readPtr = static_cast<const char*>(reader.skip(len)); 161 // Ensure that the data read is the same as what was written. 162 REPORTER_ASSERT(reporter, memcmp(readPtr, originalData.get(), len) == 0); 163 // Ensure that the rest is padded with zeroes. 164 const char* stop = readPtr + SkAlign4(len); 165 readPtr += len; 166 while (readPtr < stop) { 167 REPORTER_ASSERT(reporter, *readPtr++ == 0); 168 } 169 } 170} 171 172static void Tests(skiatest::Reporter* reporter) { 173 // dynamic allocator 174 { 175 SkWriter32 writer(256 * 4); 176 test1(reporter, &writer); 177 178 writer.reset(); 179 test2(reporter, &writer); 180 181 writer.reset(); 182 testWritePad(reporter, &writer); 183 } 184 185 // storage-block 186 { 187 SkWriter32 writer(0); 188 uint32_t storage[256]; 189 writer.reset(storage, sizeof(storage)); 190 // These three writes are small enough to fit in storage. 191 test1(reporter, &writer); 192 REPORTER_ASSERT(reporter, writer.wroteOnlyToStorage()); 193 194 writer.reset(storage, sizeof(storage)); 195 test2(reporter, &writer); 196 REPORTER_ASSERT(reporter, writer.wroteOnlyToStorage()); 197 198 writer.reset(storage, sizeof(storage)); 199 testWritePad(reporter, &writer); 200 REPORTER_ASSERT(reporter, writer.wroteOnlyToStorage()); 201 202 // Try overflowing the storage-block. 203 uint32_t smallStorage[8]; 204 writer.reset(smallStorage, sizeof(smallStorage)); 205 test2(reporter, &writer); 206 REPORTER_ASSERT(reporter, !writer.wroteOnlyToStorage()); 207 } 208 209 // small storage 210 { 211 SkSWriter32<8 * sizeof(intptr_t)> writer(100); 212 test1(reporter, &writer); 213 writer.reset(); // should just rewind our storage 214 test2(reporter, &writer); 215 216 writer.reset(); 217 testWritePad(reporter, &writer); 218 } 219 220 // large storage 221 { 222 SkSWriter32<1024 * sizeof(intptr_t)> writer(100); 223 test1(reporter, &writer); 224 writer.reset(); // should just rewind our storage 225 test2(reporter, &writer); 226 227 writer.reset(); 228 testWritePad(reporter, &writer); 229 } 230 231 test_ptr(reporter); 232 test_rewind(reporter); 233} 234 235#include "TestClassDef.h" 236DEFINE_TESTCLASS("Writer32", Writer32Class, Tests) 237