blob: 194164dd1c37959d81b6ecc91c28b4b9c19c91e3 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comdde09562011-05-23 12:21:05 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.comdde09562011-05-23 12:21:05 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
scroggo@google.comdd394882012-07-24 20:47:55 +000011#include "SkRandom.h"
reed@google.comdde09562011-05-23 12:21:05 +000012#include "SkReader32.h"
13#include "SkWriter32.h"
14#include "Test.h"
15
reed@google.com1cf58d02012-08-30 14:03:21 +000016static 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
commit-bot@chromium.org47fa1362013-08-09 16:03:05 +000024static void test_string_null(skiatest::Reporter* reporter) {
25 uint8_t storage[8];
26 SkWriter32 writer(0, storage, sizeof(storage));
commit-bot@chromium.org47fa1362013-08-09 16:03:05 +000027
28 // Can we write NULL?
29 writer.writeString(NULL);
mtklein@google.com0038c122013-08-15 21:01:32 +000030 const int32_t expected[] = { 0x0, 0x0 };
31 check_contents(reporter, writer, expected, sizeof(expected));
commit-bot@chromium.org47fa1362013-08-09 16:03:05 +000032}
33
reed@google.com1cf58d02012-08-30 14:03:21 +000034static void test_rewind(skiatest::Reporter* reporter) {
35 SkSWriter32<32> writer(32);
36 int32_t array[3] = { 1, 2, 4 };
skia.committer@gmail.coma27096b2012-08-30 14:38:00 +000037
reed@google.com1cf58d02012-08-30 14:03:21 +000038 REPORTER_ASSERT(reporter, 0 == writer.bytesWritten());
39 for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) {
40 writer.writeInt(array[i]);
41 }
42 check_contents(reporter, writer, array, sizeof(array));
43
44 writer.rewindToOffset(2*sizeof(int32_t));
45 REPORTER_ASSERT(reporter, sizeof(array) - 4 == writer.bytesWritten());
46 writer.writeInt(3);
47 REPORTER_ASSERT(reporter, sizeof(array) == writer.bytesWritten());
48 array[2] = 3;
49 check_contents(reporter, writer, array, sizeof(array));
reed@google.comd7e27822012-08-31 20:17:56 +000050
51 // test rewinding past allocated chunks. This used to crash because we
52 // didn't truncate our link-list after freeing trailing blocks
53 {
54 SkWriter32 writer(64);
55 for (int i = 0; i < 100; ++i) {
56 writer.writeInt(i);
57 }
58 REPORTER_ASSERT(reporter, 100*4 == writer.bytesWritten());
59 for (int j = 100*4; j >= 0; j -= 16) {
60 writer.rewindToOffset(j);
61 }
62 REPORTER_ASSERT(reporter, writer.bytesWritten() < 16);
63 }
reed@google.com1cf58d02012-08-30 14:03:21 +000064}
65
reed@google.com51c62a62012-06-12 20:47:53 +000066static void test_ptr(skiatest::Reporter* reporter) {
67 SkSWriter32<32> writer(32);
rmistry@google.comd6176b02012-08-23 18:14:13 +000068
reed@google.com51c62a62012-06-12 20:47:53 +000069 void* p0 = reporter;
70 void* p1 = &writer;
71
72 // try writing ptrs where at least one of them may be at a non-multiple of
73 // 8 boundary, to confirm this works on 64bit machines.
74
75 writer.writePtr(p0);
76 writer.write8(0x33);
77 writer.writePtr(p1);
78 writer.write8(0x66);
79
80 size_t size = writer.size();
81 REPORTER_ASSERT(reporter, 2 * sizeof(void*) + 2 * sizeof(int32_t));
82
83 char buffer[32];
84 SkASSERT(sizeof(buffer) >= size);
85 writer.flatten(buffer);
86
87 SkReader32 reader(buffer, size);
88 REPORTER_ASSERT(reporter, reader.readPtr() == p0);
89 REPORTER_ASSERT(reporter, reader.readInt() == 0x33);
90 REPORTER_ASSERT(reporter, reader.readPtr() == p1);
91 REPORTER_ASSERT(reporter, reader.readInt() == 0x66);
92}
93
reed@google.comdde09562011-05-23 12:21:05 +000094static void test1(skiatest::Reporter* reporter, SkWriter32* writer) {
95 const uint32_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
96 for (size_t i = 0; i < SK_ARRAY_COUNT(data); ++i) {
97 REPORTER_ASSERT(reporter, i*4 == writer->size());
98 writer->write32(data[i]);
99 uint32_t* addr = writer->peek32(i * 4);
100 REPORTER_ASSERT(reporter, data[i] == *addr);
101 }
102
103 char buffer[sizeof(data)];
104 REPORTER_ASSERT(reporter, sizeof(buffer) == writer->size());
105 writer->flatten(buffer);
106 REPORTER_ASSERT(reporter, !memcmp(data, buffer, sizeof(buffer)));
107}
108
109static void test2(skiatest::Reporter* reporter, SkWriter32* writer) {
110 static const char gStr[] = "abcdefghimjklmnopqrstuvwxyz";
111 size_t i;
112
113 size_t len = 0;
114 for (i = 0; i <= 26; ++i) {
115 len += SkWriter32::WriteStringSize(gStr, i);
116 writer->writeString(gStr, i);
117 }
118 REPORTER_ASSERT(reporter, writer->size() == len);
119
120 SkAutoMalloc storage(len);
121 writer->flatten(storage.get());
122
123 SkReader32 reader;
124 reader.setMemory(storage.get(), len);
125 for (i = 0; i <= 26; ++i) {
126 REPORTER_ASSERT(reporter, !reader.eof());
127 const char* str = reader.readString(&len);
128 REPORTER_ASSERT(reporter, i == len);
129 REPORTER_ASSERT(reporter, strlen(str) == len);
130 REPORTER_ASSERT(reporter, !memcmp(str, gStr, len));
scroggo@google.come9617eb2012-07-23 13:44:10 +0000131 // Ensure that the align4 of the string is padded with zeroes.
132 size_t alignedSize = SkAlign4(len + 1);
133 for (size_t j = len; j < alignedSize; j++) {
134 REPORTER_ASSERT(reporter, 0 == str[j]);
135 }
reed@google.comdde09562011-05-23 12:21:05 +0000136 }
137 REPORTER_ASSERT(reporter, reader.eof());
138}
139
scroggo@google.comdd394882012-07-24 20:47:55 +0000140static void testWritePad(skiatest::Reporter* reporter, SkWriter32* writer) {
141 // Create some random data to write.
142 const size_t dataSize = 10<<2;
143 SkASSERT(SkIsAlign4(dataSize));
144
145 SkAutoMalloc originalData(dataSize);
146 {
jvanverth@google.comc490f802013-03-04 13:56:38 +0000147 SkMWCRandom rand(0);
scroggo@google.comdd394882012-07-24 20:47:55 +0000148 uint32_t* ptr = static_cast<uint32_t*>(originalData.get());
149 uint32_t* stop = ptr + (dataSize>>2);
150 while (ptr < stop) {
151 *ptr++ = rand.nextU();
152 }
153
154 // Write the random data to the writer at different lengths for
155 // different alignments.
156 for (size_t len = 0; len < dataSize; len++) {
157 writer->writePad(originalData.get(), len);
158 }
159 }
160
161 uint32_t totalBytes = writer->size();
162
163 SkAutoMalloc readStorage(totalBytes);
164 writer->flatten(readStorage.get());
165
166 SkReader32 reader;
167 reader.setMemory(readStorage.get(), totalBytes);
168
169 for (size_t len = 0; len < dataSize; len++) {
170 const char* readPtr = static_cast<const char*>(reader.skip(len));
171 // Ensure that the data read is the same as what was written.
172 REPORTER_ASSERT(reporter, memcmp(readPtr, originalData.get(), len) == 0);
173 // Ensure that the rest is padded with zeroes.
174 const char* stop = readPtr + SkAlign4(len);
175 readPtr += len;
176 while (readPtr < stop) {
177 REPORTER_ASSERT(reporter, *readPtr++ == 0);
178 }
179 }
180}
181
reed@google.comdde09562011-05-23 12:21:05 +0000182static void Tests(skiatest::Reporter* reporter) {
183 // dynamic allocator
184 {
185 SkWriter32 writer(256 * 4);
reed@google.comdde09562011-05-23 12:21:05 +0000186 test1(reporter, &writer);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000187
reed@google.comdde09562011-05-23 12:21:05 +0000188 writer.reset();
189 test2(reporter, &writer);
scroggo@google.comdd394882012-07-24 20:47:55 +0000190
191 writer.reset();
192 testWritePad(reporter, &writer);
reed@google.comdde09562011-05-23 12:21:05 +0000193 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000194
reed@google.com5595af12012-12-21 15:36:33 +0000195 // storage-block
reed@google.comdde09562011-05-23 12:21:05 +0000196 {
197 SkWriter32 writer(0);
198 uint32_t storage[256];
reed@google.comdde09562011-05-23 12:21:05 +0000199 writer.reset(storage, sizeof(storage));
commit-bot@chromium.orgff36a1d2013-07-24 20:37:30 +0000200 // These three writes are small enough to fit in storage.
reed@google.comdde09562011-05-23 12:21:05 +0000201 test1(reporter, &writer);
commit-bot@chromium.orgff36a1d2013-07-24 20:37:30 +0000202 REPORTER_ASSERT(reporter, writer.wroteOnlyToStorage());
reed@google.comdde09562011-05-23 12:21:05 +0000203
204 writer.reset(storage, sizeof(storage));
205 test2(reporter, &writer);
commit-bot@chromium.orgff36a1d2013-07-24 20:37:30 +0000206 REPORTER_ASSERT(reporter, writer.wroteOnlyToStorage());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000207
scroggo@google.comdd394882012-07-24 20:47:55 +0000208 writer.reset(storage, sizeof(storage));
209 testWritePad(reporter, &writer);
commit-bot@chromium.orgff36a1d2013-07-24 20:37:30 +0000210 REPORTER_ASSERT(reporter, writer.wroteOnlyToStorage());
skia.committer@gmail.comb89a03c2012-12-22 02:02:33 +0000211
commit-bot@chromium.orgff36a1d2013-07-24 20:37:30 +0000212 // Try overflowing the storage-block.
reed@google.com5595af12012-12-21 15:36:33 +0000213 uint32_t smallStorage[8];
214 writer.reset(smallStorage, sizeof(smallStorage));
215 test2(reporter, &writer);
commit-bot@chromium.orgff36a1d2013-07-24 20:37:30 +0000216 REPORTER_ASSERT(reporter, !writer.wroteOnlyToStorage());
reed@google.comdde09562011-05-23 12:21:05 +0000217 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000218
reed@google.come49aca92012-04-24 21:12:39 +0000219 // small storage
220 {
reed@google.com51c62a62012-06-12 20:47:53 +0000221 SkSWriter32<8 * sizeof(intptr_t)> writer(100);
reed@google.come49aca92012-04-24 21:12:39 +0000222 test1(reporter, &writer);
223 writer.reset(); // should just rewind our storage
224 test2(reporter, &writer);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000225
scroggo@google.comdd394882012-07-24 20:47:55 +0000226 writer.reset();
227 testWritePad(reporter, &writer);
reed@google.come49aca92012-04-24 21:12:39 +0000228 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000229
reed@google.come49aca92012-04-24 21:12:39 +0000230 // large storage
231 {
reed@google.com51c62a62012-06-12 20:47:53 +0000232 SkSWriter32<1024 * sizeof(intptr_t)> writer(100);
reed@google.come49aca92012-04-24 21:12:39 +0000233 test1(reporter, &writer);
234 writer.reset(); // should just rewind our storage
235 test2(reporter, &writer);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000236
scroggo@google.comdd394882012-07-24 20:47:55 +0000237 writer.reset();
238 testWritePad(reporter, &writer);
reed@google.come49aca92012-04-24 21:12:39 +0000239 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000240
commit-bot@chromium.org47fa1362013-08-09 16:03:05 +0000241 test_string_null(reporter);
reed@google.com51c62a62012-06-12 20:47:53 +0000242 test_ptr(reporter);
reed@google.com1cf58d02012-08-30 14:03:21 +0000243 test_rewind(reporter);
reed@google.comdde09562011-05-23 12:21:05 +0000244}
245
246#include "TestClassDef.h"
247DEFINE_TESTCLASS("Writer32", Writer32Class, Tests)