blob: d0a850724107cd46c62b993f029b967d8b57c698 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com5e5adfd2009-03-07 03:39:23 +00008#include "Test.h"
9#include "SkRandom.h"
10#include "SkStream.h"
reed@google.com8d0b5772011-06-24 13:07:31 +000011#include "SkData.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000012
reed@google.com789c6f22013-02-25 20:24:24 +000013#ifndef SK_BUILD_FOR_WIN
14#include <unistd.h>
15#include <fcntl.h>
16#endif
17
reed@android.com5e5adfd2009-03-07 03:39:23 +000018#define MAX_SIZE (256 * 1024)
19
jvanverth@google.comc490f802013-03-04 13:56:38 +000020static void random_fill(SkMWCRandom& rand, void* buffer, size_t size) {
reed@android.com5e5adfd2009-03-07 03:39:23 +000021 char* p = (char*)buffer;
22 char* stop = p + size;
23 while (p < stop) {
24 *p++ = (char)(rand.nextU() >> 8);
25 }
26}
27
28static void test_buffer(skiatest::Reporter* reporter) {
jvanverth@google.comc490f802013-03-04 13:56:38 +000029 SkMWCRandom rand;
reed@android.com5e5adfd2009-03-07 03:39:23 +000030 SkAutoMalloc am(MAX_SIZE * 2);
31 char* storage = (char*)am.get();
32 char* storage2 = storage + MAX_SIZE;
33
34 random_fill(rand, storage, MAX_SIZE);
35
36 for (int sizeTimes = 0; sizeTimes < 100; sizeTimes++) {
37 int size = rand.nextU() % MAX_SIZE;
38 if (size == 0) {
39 size = MAX_SIZE;
40 }
41 for (int times = 0; times < 100; times++) {
42 int bufferSize = 1 + (rand.nextU() & 0xFFFF);
43 SkMemoryStream mstream(storage, size);
44 SkBufferStream bstream(&mstream, bufferSize);
reed@android.com80e39a72009-04-02 16:59:40 +000045
reed@android.com5e5adfd2009-03-07 03:39:23 +000046 int bytesRead = 0;
47 while (bytesRead < size) {
48 int s = 17 + (rand.nextU() & 0xFFFF);
49 int ss = bstream.read(storage2, s);
50 REPORTER_ASSERT(reporter, ss > 0 && ss <= s);
51 REPORTER_ASSERT(reporter, bytesRead + ss <= size);
reed@android.com80e39a72009-04-02 16:59:40 +000052 REPORTER_ASSERT(reporter,
53 memcmp(storage + bytesRead, storage2, ss) == 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +000054 bytesRead += ss;
55 }
56 REPORTER_ASSERT(reporter, bytesRead == size);
57 }
58 }
59}
60
61static void TestRStream(skiatest::Reporter* reporter) {
reed@android.com80e39a72009-04-02 16:59:40 +000062 static const char s[] =
63 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
reed@android.com5e5adfd2009-03-07 03:39:23 +000064 char copy[sizeof(s)];
jvanverth@google.comc490f802013-03-04 13:56:38 +000065 SkMWCRandom rand;
reed@android.com80e39a72009-04-02 16:59:40 +000066
67 for (int i = 0; i < 65; i++) {
reed@android.com5e5adfd2009-03-07 03:39:23 +000068 char* copyPtr = copy;
69 SkMemoryStream mem(s, sizeof(s));
70 SkBufferStream buff(&mem, i);
reed@android.com80e39a72009-04-02 16:59:40 +000071
reed@android.com5e5adfd2009-03-07 03:39:23 +000072 do {
73 copyPtr += buff.read(copyPtr, rand.nextU() & 15);
74 } while (copyPtr < copy + sizeof(s));
75 REPORTER_ASSERT(reporter, copyPtr == copy + sizeof(s));
76 REPORTER_ASSERT(reporter, memcmp(s, copy, sizeof(s)) == 0);
77 }
78 test_buffer(reporter);
79}
80
reed@google.com789c6f22013-02-25 20:24:24 +000081static void test_loop_stream(skiatest::Reporter* reporter, SkStream* stream,
82 const void* src, size_t len, int repeat) {
83 SkAutoSMalloc<256> storage(len);
84 void* tmp = storage.get();
85
86 for (int i = 0; i < repeat; ++i) {
87 size_t bytes = stream->read(tmp, len);
88 REPORTER_ASSERT(reporter, bytes == len);
89 REPORTER_ASSERT(reporter, !memcmp(tmp, src, len));
90 }
91
92 // expect EOF
93 size_t bytes = stream->read(tmp, 1);
94 REPORTER_ASSERT(reporter, 0 == bytes);
95}
96
97static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) {
98 SkString path;
99 path.printf("%s%s", tmpDir, "wstream_test");
100
101 const char s[] = "abcdefghijklmnopqrstuvwxyz";
102
103 {
104 SkFILEWStream writer(path.c_str());
105 if (!writer.isValid()) {
106 SkString msg;
107 msg.printf("Failed to create tmp file %s\n", path.c_str());
108 reporter->reportFailed(msg.c_str());
109 return;
110 }
111
112 for (int i = 0; i < 100; ++i) {
113 writer.write(s, 26);
114 }
115 }
116
117 {
118 SkFILEStream stream(path.c_str());
119 REPORTER_ASSERT(reporter, stream.isValid());
120 test_loop_stream(reporter, &stream, s, 26, 100);
121 }
122
123#ifndef SK_BUILD_FOR_WIN
124 {
125 int fd = ::open(path.c_str(), O_RDONLY);
126 SkFDStream stream(fd, true);
127 REPORTER_ASSERT(reporter, stream.isValid());
128 test_loop_stream(reporter, &stream, s, 26, 100);
129 }
130#endif
131}
132
reed@android.com80e39a72009-04-02 16:59:40 +0000133static void TestWStream(skiatest::Reporter* reporter) {
134 SkDynamicMemoryWStream ds;
135 const char s[] = "abcdefghijklmnopqrstuvwxyz";
136 int i;
137 for (i = 0; i < 100; i++) {
138 REPORTER_ASSERT(reporter, ds.write(s, 26));
reed@android.com5e5adfd2009-03-07 03:39:23 +0000139 }
reed@android.com80e39a72009-04-02 16:59:40 +0000140 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
141 char* dst = new char[100 * 26 + 1];
142 dst[100*26] = '*';
143 ds.copyTo(dst);
144 REPORTER_ASSERT(reporter, dst[100*26] == '*');
145// char* p = dst;
146 for (i = 0; i < 100; i++) {
147 REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +0000148 }
reed@google.com70442a62011-06-23 21:48:04 +0000149
150 {
reed@google.com8d0b5772011-06-24 13:07:31 +0000151 SkData* data = ds.copyToData();
reed@google.com70442a62011-06-23 21:48:04 +0000152 REPORTER_ASSERT(reporter, 100 * 26 == data->size());
153 REPORTER_ASSERT(reporter, memcmp(dst, data->data(), data->size()) == 0);
154 data->unref();
155 }
reed@android.com80e39a72009-04-02 16:59:40 +0000156 delete[] dst;
reed@google.com789c6f22013-02-25 20:24:24 +0000157
djsollen@google.comcb626502013-03-20 13:48:20 +0000158 if (!skiatest::Test::GetTmpDir().isEmpty()) {
159 test_filestreams(reporter, skiatest::Test::GetTmpDir().c_str());
reed@google.com789c6f22013-02-25 20:24:24 +0000160 }
reed@android.com5e5adfd2009-03-07 03:39:23 +0000161}
162
reed@google.com19f286b2011-10-18 11:49:52 +0000163static void TestPackedUInt(skiatest::Reporter* reporter) {
164 // we know that packeduint tries to write 1, 2 or 4 bytes for the length,
165 // so we test values around each of those transitions (and a few others)
166 const size_t sizes[] = {
167 0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769,
168 0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001,
169 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001,
170 0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF
171 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000172
173
reed@google.com19f286b2011-10-18 11:49:52 +0000174 size_t i;
175 char buffer[sizeof(sizes) * 4];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000176
reed@google.com19f286b2011-10-18 11:49:52 +0000177 SkMemoryWStream wstream(buffer, sizeof(buffer));
178 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
179 bool success = wstream.writePackedUInt(sizes[i]);
180 REPORTER_ASSERT(reporter, success);
181 }
182 wstream.flush();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000183
reed@google.com19f286b2011-10-18 11:49:52 +0000184 SkMemoryStream rstream(buffer, sizeof(buffer));
185 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
186 size_t n = rstream.readPackedUInt();
187 if (sizes[i] != n) {
188 SkDebugf("-- %d: sizes:%x n:%x\n", i, sizes[i], n);
189 }
190 REPORTER_ASSERT(reporter, sizes[i] == n);
191 }
192}
193
scroggo@google.come4904202013-01-09 22:02:58 +0000194// Test that setting an SkMemoryStream to a NULL data does not result in a crash when calling
195// methods that access fData.
196static void TestDereferencingData(SkMemoryStream* memStream) {
197 memStream->read(NULL, 0);
198 memStream->getMemoryBase();
199 SkAutoDataUnref data(memStream->copyToData());
200}
201
202static void TestNullData() {
203 SkData* nullData = NULL;
204 SkMemoryStream memStream(nullData);
205 TestDereferencingData(&memStream);
206
207 memStream.setData(nullData);
208 TestDereferencingData(&memStream);
209
210}
211
reed@android.com5e5adfd2009-03-07 03:39:23 +0000212static void TestStreams(skiatest::Reporter* reporter) {
213 TestRStream(reporter);
214 TestWStream(reporter);
reed@google.com19f286b2011-10-18 11:49:52 +0000215 TestPackedUInt(reporter);
scroggo@google.come4904202013-01-09 22:02:58 +0000216 TestNullData();
reed@android.com5e5adfd2009-03-07 03:39:23 +0000217}
218
219#include "TestClassDef.h"
220DEFINE_TESTCLASS("Stream", StreamTestClass, TestStreams)