blob: 74e60557d1cb83603527081f95326199ade2e5f0 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00007
scroggo028a4132015-04-02 13:19:51 -07008#include "Resources.h"
reed@google.com8d0b5772011-06-24 13:07:31 +00009#include "SkData.h"
scroggo028a4132015-04-02 13:19:51 -070010#include "SkFrontBufferedStream.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000011#include "SkOSFile.h"
12#include "SkRandom.h"
13#include "SkStream.h"
halcanary48305e82015-08-18 13:30:25 -070014#include "SkStreamPriv.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000015#include "Test.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000016
reed@google.com789c6f22013-02-25 20:24:24 +000017#ifndef SK_BUILD_FOR_WIN
18#include <unistd.h>
19#include <fcntl.h>
20#endif
21
reed@android.com5e5adfd2009-03-07 03:39:23 +000022#define MAX_SIZE (256 * 1024)
23
reed@google.com789c6f22013-02-25 20:24:24 +000024static void test_loop_stream(skiatest::Reporter* reporter, SkStream* stream,
25 const void* src, size_t len, int repeat) {
26 SkAutoSMalloc<256> storage(len);
27 void* tmp = storage.get();
28
29 for (int i = 0; i < repeat; ++i) {
30 size_t bytes = stream->read(tmp, len);
31 REPORTER_ASSERT(reporter, bytes == len);
32 REPORTER_ASSERT(reporter, !memcmp(tmp, src, len));
33 }
34
35 // expect EOF
36 size_t bytes = stream->read(tmp, 1);
37 REPORTER_ASSERT(reporter, 0 == bytes);
bungeman@google.com88682b72013-07-19 13:55:41 +000038 // isAtEnd might not return true until after the first failing read.
39 REPORTER_ASSERT(reporter, stream->isAtEnd());
reed@google.com789c6f22013-02-25 20:24:24 +000040}
41
42static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) {
tfarinaa8e2e152014-07-28 19:26:58 -070043 SkString path = SkOSPath::Join(tmpDir, "wstream_test");
reed@google.com789c6f22013-02-25 20:24:24 +000044
45 const char s[] = "abcdefghijklmnopqrstuvwxyz";
46
47 {
48 SkFILEWStream writer(path.c_str());
49 if (!writer.isValid()) {
halcanary@google.coma9325fa2014-01-10 14:58:10 +000050 ERRORF(reporter, "Failed to create tmp file %s\n", path.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +000051 return;
52 }
53
54 for (int i = 0; i < 100; ++i) {
55 writer.write(s, 26);
56 }
57 }
58
59 {
60 SkFILEStream stream(path.c_str());
61 REPORTER_ASSERT(reporter, stream.isValid());
62 test_loop_stream(reporter, &stream, s, 26, 100);
bungeman@google.com6cab1a42013-05-29 13:43:31 +000063
scroggoa1193e42015-01-21 12:09:53 -080064 SkAutoTDelete<SkStreamAsset> stream2(stream.duplicate());
bungeman@google.com6cab1a42013-05-29 13:43:31 +000065 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com789c6f22013-02-25 20:24:24 +000066 }
67
reed@google.com789c6f22013-02-25 20:24:24 +000068 {
bungeman@google.com6cab1a42013-05-29 13:43:31 +000069 FILE* file = ::fopen(path.c_str(), "rb");
70 SkFILEStream stream(file, SkFILEStream::kCallerPasses_Ownership);
reed@google.com789c6f22013-02-25 20:24:24 +000071 REPORTER_ASSERT(reporter, stream.isValid());
72 test_loop_stream(reporter, &stream, s, 26, 100);
bungeman@google.com6cab1a42013-05-29 13:43:31 +000073
scroggoa1193e42015-01-21 12:09:53 -080074 SkAutoTDelete<SkStreamAsset> stream2(stream.duplicate());
bungeman@google.com6cab1a42013-05-29 13:43:31 +000075 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com789c6f22013-02-25 20:24:24 +000076 }
reed@google.com789c6f22013-02-25 20:24:24 +000077}
78
reed@android.com80e39a72009-04-02 16:59:40 +000079static void TestWStream(skiatest::Reporter* reporter) {
80 SkDynamicMemoryWStream ds;
81 const char s[] = "abcdefghijklmnopqrstuvwxyz";
82 int i;
83 for (i = 0; i < 100; i++) {
84 REPORTER_ASSERT(reporter, ds.write(s, 26));
reed@android.com5e5adfd2009-03-07 03:39:23 +000085 }
reed@android.com80e39a72009-04-02 16:59:40 +000086 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
bungeman@google.com88682b72013-07-19 13:55:41 +000087
reed@android.com80e39a72009-04-02 16:59:40 +000088 char* dst = new char[100 * 26 + 1];
89 dst[100*26] = '*';
90 ds.copyTo(dst);
91 REPORTER_ASSERT(reporter, dst[100*26] == '*');
reed@android.com80e39a72009-04-02 16:59:40 +000092 for (i = 0; i < 100; i++) {
93 REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +000094 }
reed@google.com70442a62011-06-23 21:48:04 +000095
96 {
scroggoa1193e42015-01-21 12:09:53 -080097 SkAutoTDelete<SkStreamAsset> stream(ds.detachAsStream());
bungeman@google.com88682b72013-07-19 13:55:41 +000098 REPORTER_ASSERT(reporter, 100 * 26 == stream->getLength());
99 REPORTER_ASSERT(reporter, ds.getOffset() == 0);
100 test_loop_stream(reporter, stream.get(), s, 26, 100);
101
scroggoa1193e42015-01-21 12:09:53 -0800102 SkAutoTDelete<SkStreamAsset> stream2(stream->duplicate());
bungeman@google.com88682b72013-07-19 13:55:41 +0000103 test_loop_stream(reporter, stream2.get(), s, 26, 100);
104
scroggoa1193e42015-01-21 12:09:53 -0800105 SkAutoTDelete<SkStreamAsset> stream3(stream->fork());
bungeman@google.com88682b72013-07-19 13:55:41 +0000106 REPORTER_ASSERT(reporter, stream3->isAtEnd());
107 char tmp;
108 size_t bytes = stream->read(&tmp, 1);
109 REPORTER_ASSERT(reporter, 0 == bytes);
110 stream3->rewind();
111 test_loop_stream(reporter, stream3.get(), s, 26, 100);
112 }
113
114 for (i = 0; i < 100; i++) {
115 REPORTER_ASSERT(reporter, ds.write(s, 26));
116 }
117 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
118
119 {
reed42943c82016-09-12 12:01:44 -0700120 sk_sp<SkData> data = ds.snapshotAsData();
reed@google.com70442a62011-06-23 21:48:04 +0000121 REPORTER_ASSERT(reporter, 100 * 26 == data->size());
122 REPORTER_ASSERT(reporter, memcmp(dst, data->data(), data->size()) == 0);
bungeman@google.com88682b72013-07-19 13:55:41 +0000123 }
124
125 {
reed42943c82016-09-12 12:01:44 -0700126 // Test that this works after a snapshot.
scroggoa1193e42015-01-21 12:09:53 -0800127 SkAutoTDelete<SkStreamAsset> stream(ds.detachAsStream());
bungeman@google.com88682b72013-07-19 13:55:41 +0000128 REPORTER_ASSERT(reporter, ds.getOffset() == 0);
129 test_loop_stream(reporter, stream.get(), s, 26, 100);
130
scroggoa1193e42015-01-21 12:09:53 -0800131 SkAutoTDelete<SkStreamAsset> stream2(stream->duplicate());
bungeman@google.com88682b72013-07-19 13:55:41 +0000132 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com70442a62011-06-23 21:48:04 +0000133 }
reed@android.com80e39a72009-04-02 16:59:40 +0000134 delete[] dst;
reed@google.com789c6f22013-02-25 20:24:24 +0000135
halcanary87f3ba42015-01-20 09:30:20 -0800136 SkString tmpDir = skiatest::GetTmpDir();
scroggo@google.comc76218d2013-06-06 14:59:56 +0000137 if (!tmpDir.isEmpty()) {
138 test_filestreams(reporter, tmpDir.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +0000139 }
reed@android.com5e5adfd2009-03-07 03:39:23 +0000140}
141
reed@google.com19f286b2011-10-18 11:49:52 +0000142static void TestPackedUInt(skiatest::Reporter* reporter) {
143 // we know that packeduint tries to write 1, 2 or 4 bytes for the length,
144 // so we test values around each of those transitions (and a few others)
145 const size_t sizes[] = {
146 0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769,
147 0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001,
148 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001,
149 0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF
150 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000151
152
reed@google.com19f286b2011-10-18 11:49:52 +0000153 size_t i;
154 char buffer[sizeof(sizes) * 4];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000155
reed@google.com19f286b2011-10-18 11:49:52 +0000156 SkMemoryWStream wstream(buffer, sizeof(buffer));
157 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
158 bool success = wstream.writePackedUInt(sizes[i]);
159 REPORTER_ASSERT(reporter, success);
160 }
161 wstream.flush();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000162
reed@google.com19f286b2011-10-18 11:49:52 +0000163 SkMemoryStream rstream(buffer, sizeof(buffer));
164 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
165 size_t n = rstream.readPackedUInt();
166 if (sizes[i] != n) {
halcanary7d571242016-02-24 17:59:16 -0800167 ERRORF(reporter, "sizes:%x != n:%x\n", i, sizes[i], n);
reed@google.com19f286b2011-10-18 11:49:52 +0000168 }
reed@google.com19f286b2011-10-18 11:49:52 +0000169 }
170}
171
halcanary96fcdcc2015-08-27 07:41:13 -0700172// Test that setting an SkMemoryStream to a nullptr data does not result in a crash when calling
scroggo@google.come4904202013-01-09 22:02:58 +0000173// methods that access fData.
174static void TestDereferencingData(SkMemoryStream* memStream) {
halcanary96fcdcc2015-08-27 07:41:13 -0700175 memStream->read(nullptr, 0);
scroggo@google.come4904202013-01-09 22:02:58 +0000176 memStream->getMemoryBase();
reed42943c82016-09-12 12:01:44 -0700177 (void)memStream->asData();
scroggo@google.come4904202013-01-09 22:02:58 +0000178}
179
180static void TestNullData() {
reed42943c82016-09-12 12:01:44 -0700181 SkMemoryStream memStream(nullptr);
scroggo@google.come4904202013-01-09 22:02:58 +0000182 TestDereferencingData(&memStream);
183
reed42943c82016-09-12 12:01:44 -0700184 memStream.setData(nullptr);
scroggo@google.come4904202013-01-09 22:02:58 +0000185 TestDereferencingData(&memStream);
186
187}
188
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000189DEF_TEST(Stream, reporter) {
reed@android.com5e5adfd2009-03-07 03:39:23 +0000190 TestWStream(reporter);
reed@google.com19f286b2011-10-18 11:49:52 +0000191 TestPackedUInt(reporter);
scroggo@google.come4904202013-01-09 22:02:58 +0000192 TestNullData();
reed@android.com5e5adfd2009-03-07 03:39:23 +0000193}
scroggo028a4132015-04-02 13:19:51 -0700194
195/**
196 * Tests peeking and then reading the same amount. The two should provide the
197 * same results.
scroggod61c3842015-12-07 11:37:13 -0800198 * Returns the amount successfully read minus the amount successfully peeked.
scroggo028a4132015-04-02 13:19:51 -0700199 */
scroggod61c3842015-12-07 11:37:13 -0800200static size_t compare_peek_to_read(skiatest::Reporter* reporter,
201 SkStream* stream, size_t bytesToPeek) {
scroggo028a4132015-04-02 13:19:51 -0700202 // The rest of our tests won't be very interesting if bytesToPeek is zero.
203 REPORTER_ASSERT(reporter, bytesToPeek > 0);
204 SkAutoMalloc peekStorage(bytesToPeek);
205 SkAutoMalloc readStorage(bytesToPeek);
206 void* peekPtr = peekStorage.get();
207 void* readPtr = peekStorage.get();
208
scroggod61c3842015-12-07 11:37:13 -0800209 const size_t bytesPeeked = stream->peek(peekPtr, bytesToPeek);
scroggo028a4132015-04-02 13:19:51 -0700210 const size_t bytesRead = stream->read(readPtr, bytesToPeek);
211
212 // bytesRead should only be less than attempted if the stream is at the
213 // end.
214 REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd());
215
216 // peek and read should behave the same, except peek returned to the
217 // original position, so they read the same data.
scroggod61c3842015-12-07 11:37:13 -0800218 REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesPeeked));
scroggo028a4132015-04-02 13:19:51 -0700219
scroggod61c3842015-12-07 11:37:13 -0800220 // A stream should never be able to peek more than it can read.
221 REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked);
222
223 return bytesRead - bytesPeeked;
scroggo028a4132015-04-02 13:19:51 -0700224}
225
scroggod61c3842015-12-07 11:37:13 -0800226static void test_fully_peekable_stream(skiatest::Reporter* r, SkStream* stream, size_t limit) {
scroggo028a4132015-04-02 13:19:51 -0700227 for (size_t i = 1; !stream->isAtEnd(); i++) {
scroggod61c3842015-12-07 11:37:13 -0800228 REPORTER_ASSERT(r, compare_peek_to_read(r, stream, i) == 0);
scroggo028a4132015-04-02 13:19:51 -0700229 }
230}
231
232static void test_peeking_front_buffered_stream(skiatest::Reporter* r,
233 const SkStream& original,
234 size_t bufferSize) {
235 SkStream* dupe = original.duplicate();
halcanary96fcdcc2015-08-27 07:41:13 -0700236 REPORTER_ASSERT(r, dupe != nullptr);
scroggo028a4132015-04-02 13:19:51 -0700237 SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, bufferSize));
halcanary96fcdcc2015-08-27 07:41:13 -0700238 REPORTER_ASSERT(r, bufferedStream != nullptr);
scroggod61c3842015-12-07 11:37:13 -0800239
240 size_t peeked = 0;
241 for (size_t i = 1; !bufferedStream->isAtEnd(); i++) {
242 const size_t unpeekableBytes = compare_peek_to_read(r, bufferedStream, i);
243 if (unpeekableBytes > 0) {
244 // This could not have returned a number greater than i.
245 REPORTER_ASSERT(r, unpeekableBytes <= i);
246
247 // We have reached the end of the buffer. Verify that it was at least
248 // bufferSize.
249 REPORTER_ASSERT(r, peeked + i - unpeekableBytes >= bufferSize);
250 // No more peeking is supported.
251 break;
252 }
253 peeked += i;
254 }
255
256 // Test that attempting to peek beyond the length of the buffer does not prevent rewinding.
257 bufferedStream.reset(SkFrontBufferedStream::Create(original.duplicate(), bufferSize));
258 REPORTER_ASSERT(r, bufferedStream != nullptr);
259
260 const size_t bytesToPeek = bufferSize + 1;
261 SkAutoMalloc peekStorage(bytesToPeek);
262 SkAutoMalloc readStorage(bytesToPeek);
263
264 for (size_t start = 0; start <= bufferSize; start++) {
265 // Skip to the starting point
266 REPORTER_ASSERT(r, bufferedStream->skip(start) == start);
scroggod61c3842015-12-07 11:37:13 -0800267
268 const size_t bytesPeeked = bufferedStream->peek(peekStorage.get(), bytesToPeek);
269 if (0 == bytesPeeked) {
scroggoef0fed32016-02-18 05:59:25 -0800270 // Peeking should only fail completely if we have read/skipped beyond the buffer.
271 REPORTER_ASSERT(r, start >= bufferSize);
scroggod61c3842015-12-07 11:37:13 -0800272 break;
273 }
274
275 // Only read the amount that was successfully peeked.
276 const size_t bytesRead = bufferedStream->read(readStorage.get(), bytesPeeked);
277 REPORTER_ASSERT(r, bytesRead == bytesPeeked);
278 REPORTER_ASSERT(r, !memcmp(peekStorage.get(), readStorage.get(), bytesPeeked));
279
280 // This should be safe to rewind.
281 REPORTER_ASSERT(r, bufferedStream->rewind());
282 }
scroggo028a4132015-04-02 13:19:51 -0700283}
284
halcanary9d524f22016-03-29 09:03:52 -0700285// This test uses file system operations that don't work out of the
286// box on iOS. It's likely that we don't need them on iOS. Ignoring for now.
287// TODO(stephana): Re-evaluate if we need this in the future.
stephana195f62d2015-04-09 07:57:54 -0700288#ifndef SK_BUILD_FOR_IOS
scroggo028a4132015-04-02 13:19:51 -0700289DEF_TEST(StreamPeek, reporter) {
290 // Test a memory stream.
291 const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz";
292 SkMemoryStream memStream(gAbcs, strlen(gAbcs), false);
scroggod61c3842015-12-07 11:37:13 -0800293 test_fully_peekable_stream(reporter, &memStream, memStream.getLength());
scroggo028a4132015-04-02 13:19:51 -0700294
295 // Test an arbitrary file stream. file streams do not support peeking.
296 SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str());
297 REPORTER_ASSERT(reporter, fileStream.isValid());
caryclark30ac4642015-04-14 06:08:04 -0700298 if (!fileStream.isValid()) {
299 return;
300 }
scroggo028a4132015-04-02 13:19:51 -0700301 SkAutoMalloc storage(fileStream.getLength());
302 for (size_t i = 1; i < fileStream.getLength(); i++) {
scroggod61c3842015-12-07 11:37:13 -0800303 REPORTER_ASSERT(reporter, fileStream.peek(storage.get(), i) == 0);
scroggo028a4132015-04-02 13:19:51 -0700304 }
305
306 // Now test some FrontBufferedStreams
307 for (size_t i = 1; i < memStream.getLength(); i++) {
308 test_peeking_front_buffered_stream(reporter, memStream, i);
309 }
310}
halcanarye797d0d2015-05-21 08:13:27 -0700311#endif
312
313// Asserts that asset == expected and is peekable.
314static void stream_peek_test(skiatest::Reporter* rep,
315 SkStreamAsset* asset,
316 const SkData* expected) {
317 if (asset->getLength() != expected->size()) {
318 ERRORF(rep, "Unexpected length.");
319 return;
320 }
321 SkRandom rand;
322 uint8_t buffer[4096];
323 const uint8_t* expect = expected->bytes();
324 for (size_t i = 0; i < asset->getLength(); ++i) {
325 uint32_t maxSize =
326 SkToU32(SkTMin(sizeof(buffer), asset->getLength() - i));
327 size_t size = rand.nextRangeU(1, maxSize);
328 SkASSERT(size >= 1);
329 SkASSERT(size <= sizeof(buffer));
330 SkASSERT(size + i <= asset->getLength());
scroggod61c3842015-12-07 11:37:13 -0800331 if (asset->peek(buffer, size) < size) {
halcanarye797d0d2015-05-21 08:13:27 -0700332 ERRORF(rep, "Peek Failed!");
333 return;
334 }
335 if (0 != memcmp(buffer, &expect[i], size)) {
336 ERRORF(rep, "Peek returned wrong bytes!");
337 return;
338 }
339 uint8_t value;
340 REPORTER_ASSERT(rep, 1 == asset->read(&value, 1));
341 if (value != expect[i]) {
342 ERRORF(rep, "Read Failed!");
343 return;
344 }
345 }
346}
347
348DEF_TEST(StreamPeek_BlockMemoryStream, rep) {
349 const static int kSeed = 1234;
350 SkRandom valueSource(kSeed);
351 SkRandom rand(kSeed << 1);
352 uint8_t buffer[4096];
353 SkDynamicMemoryWStream dynamicMemoryWStream;
354 for (int i = 0; i < 32; ++i) {
355 // Randomize the length of the blocks.
356 size_t size = rand.nextRangeU(1, sizeof(buffer));
357 for (size_t j = 0; j < size; ++j) {
358 buffer[j] = valueSource.nextU() & 0xFF;
359 }
360 dynamicMemoryWStream.write(buffer, size);
361 }
362 SkAutoTDelete<SkStreamAsset> asset(dynamicMemoryWStream.detachAsStream());
bungeman38d909e2016-08-02 14:40:46 -0700363 sk_sp<SkData> expected(SkData::MakeUninitialized(asset->getLength()));
halcanarye797d0d2015-05-21 08:13:27 -0700364 uint8_t* expectedPtr = static_cast<uint8_t*>(expected->writable_data());
365 valueSource.setSeed(kSeed); // reseed.
366 // We want the exact same same "random" string of numbers to put
367 // in expected. i.e.: don't rely on SkDynamicMemoryStream to work
368 // correctly while we are testing SkDynamicMemoryStream.
369 for (size_t i = 0; i < asset->getLength(); ++i) {
370 expectedPtr[i] = valueSource.nextU() & 0xFF;
371 }
bungeman38d909e2016-08-02 14:40:46 -0700372 stream_peek_test(rep, asset, expected.get());
halcanarye797d0d2015-05-21 08:13:27 -0700373}
halcanary48305e82015-08-18 13:30:25 -0700374
375namespace {
376class DumbStream : public SkStream {
377public:
378 DumbStream(const uint8_t* data, size_t n)
379 : fData(data), fCount(n), fIdx(0) {}
380 size_t read(void* buffer, size_t size) override {
halcanaryd75e21d2015-08-19 07:22:04 -0700381 size_t copyCount = SkTMin(fCount - fIdx, size);
382 if (copyCount) {
383 memcpy(buffer, &fData[fIdx], copyCount);
384 fIdx += copyCount;
halcanary48305e82015-08-18 13:30:25 -0700385 }
halcanaryd75e21d2015-08-19 07:22:04 -0700386 return copyCount;
halcanary48305e82015-08-18 13:30:25 -0700387 }
388 bool isAtEnd() const override {
halcanaryd75e21d2015-08-19 07:22:04 -0700389 return fCount == fIdx;
halcanary48305e82015-08-18 13:30:25 -0700390 }
391 private:
392 const uint8_t* fData;
393 size_t fCount, fIdx;
394};
395} // namespace
396
397static void stream_copy_test(skiatest::Reporter* reporter,
398 const void* srcData,
399 size_t N,
400 SkStream* stream) {
401 SkDynamicMemoryWStream tgt;
402 if (!SkStreamCopy(&tgt, stream)) {
403 ERRORF(reporter, "SkStreamCopy failed");
404 return;
405 }
reed42943c82016-09-12 12:01:44 -0700406 sk_sp<SkData> data(tgt.detachAsData());
halcanary48305e82015-08-18 13:30:25 -0700407 if (data->size() != N) {
408 ERRORF(reporter, "SkStreamCopy incorrect size");
409 return;
410 }
411 if (0 != memcmp(data->data(), srcData, N)) {
412 ERRORF(reporter, "SkStreamCopy bad copy");
413 }
414}
415
416DEF_TEST(StreamCopy, reporter) {
417 SkRandom random(123456);
halcanarycb9241b2015-08-19 06:12:40 -0700418 static const int N = 10000;
419 SkAutoTMalloc<uint8_t> src((size_t)N);
420 for (int j = 0; j < N; ++j) {
halcanary48305e82015-08-18 13:30:25 -0700421 src[j] = random.nextU() & 0xff;
422 }
423 // SkStreamCopy had two code paths; this test both.
halcanarycb9241b2015-08-19 06:12:40 -0700424 DumbStream dumbStream(src.get(), (size_t)N);
halcanary48305e82015-08-18 13:30:25 -0700425 stream_copy_test(reporter, src, N, &dumbStream);
halcanarycb9241b2015-08-19 06:12:40 -0700426 SkMemoryStream smartStream(src.get(), (size_t)N);
halcanary48305e82015-08-18 13:30:25 -0700427 stream_copy_test(reporter, src, N, &smartStream);
halcanary48305e82015-08-18 13:30:25 -0700428}
halcanary209c1622015-09-28 07:29:39 -0700429
430DEF_TEST(StreamEmptyStreamMemoryBase, r) {
431 SkDynamicMemoryWStream tmp;
432 SkAutoTDelete<SkStreamAsset> asset(tmp.detachAsStream());
433 REPORTER_ASSERT(r, nullptr == asset->getMemoryBase());
434}