blob: ecb8336596ba9175e736c3592ad2cf8118dc64aa [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
reed@android.com5e5adfd2009-03-07 03:39:23 +00008#include "Test.h"
9#include "SkRandom.h"
bungeman@google.com6cab1a42013-05-29 13:43:31 +000010#include "SkOSFile.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000011#include "SkStream.h"
reed@google.com8d0b5772011-06-24 13:07:31 +000012#include "SkData.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000013
reed@google.com789c6f22013-02-25 20:24:24 +000014#ifndef SK_BUILD_FOR_WIN
15#include <unistd.h>
16#include <fcntl.h>
17#endif
18
reed@android.com5e5adfd2009-03-07 03:39:23 +000019#define MAX_SIZE (256 * 1024)
20
reed@google.com789c6f22013-02-25 20:24:24 +000021static void test_loop_stream(skiatest::Reporter* reporter, SkStream* stream,
22 const void* src, size_t len, int repeat) {
23 SkAutoSMalloc<256> storage(len);
24 void* tmp = storage.get();
25
26 for (int i = 0; i < repeat; ++i) {
27 size_t bytes = stream->read(tmp, len);
28 REPORTER_ASSERT(reporter, bytes == len);
29 REPORTER_ASSERT(reporter, !memcmp(tmp, src, len));
30 }
31
32 // expect EOF
33 size_t bytes = stream->read(tmp, 1);
34 REPORTER_ASSERT(reporter, 0 == bytes);
bungeman@google.com88682b72013-07-19 13:55:41 +000035 // isAtEnd might not return true until after the first failing read.
36 REPORTER_ASSERT(reporter, stream->isAtEnd());
reed@google.com789c6f22013-02-25 20:24:24 +000037}
38
39static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) {
scroggo@google.comc76218d2013-06-06 14:59:56 +000040 SkString path = SkOSPath::SkPathJoin(tmpDir, "wstream_test");
reed@google.com789c6f22013-02-25 20:24:24 +000041
42 const char s[] = "abcdefghijklmnopqrstuvwxyz";
43
44 {
45 SkFILEWStream writer(path.c_str());
46 if (!writer.isValid()) {
halcanary@google.coma9325fa2014-01-10 14:58:10 +000047 ERRORF(reporter, "Failed to create tmp file %s\n", path.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +000048 return;
49 }
50
51 for (int i = 0; i < 100; ++i) {
52 writer.write(s, 26);
53 }
54 }
55
56 {
57 SkFILEStream stream(path.c_str());
58 REPORTER_ASSERT(reporter, stream.isValid());
59 test_loop_stream(reporter, &stream, s, 26, 100);
bungeman@google.com6cab1a42013-05-29 13:43:31 +000060
61 SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate());
62 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com789c6f22013-02-25 20:24:24 +000063 }
64
reed@google.com789c6f22013-02-25 20:24:24 +000065 {
bungeman@google.com6cab1a42013-05-29 13:43:31 +000066 FILE* file = ::fopen(path.c_str(), "rb");
67 SkFILEStream stream(file, SkFILEStream::kCallerPasses_Ownership);
reed@google.com789c6f22013-02-25 20:24:24 +000068 REPORTER_ASSERT(reporter, stream.isValid());
69 test_loop_stream(reporter, &stream, s, 26, 100);
bungeman@google.com6cab1a42013-05-29 13:43:31 +000070
71 SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate());
72 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com789c6f22013-02-25 20:24:24 +000073 }
reed@google.com789c6f22013-02-25 20:24:24 +000074}
75
reed@android.com80e39a72009-04-02 16:59:40 +000076static 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));
reed@android.com5e5adfd2009-03-07 03:39:23 +000082 }
reed@android.com80e39a72009-04-02 16:59:40 +000083 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
bungeman@google.com88682b72013-07-19 13:55:41 +000084
reed@android.com80e39a72009-04-02 16:59:40 +000085 char* dst = new char[100 * 26 + 1];
86 dst[100*26] = '*';
87 ds.copyTo(dst);
88 REPORTER_ASSERT(reporter, dst[100*26] == '*');
reed@android.com80e39a72009-04-02 16:59:40 +000089 for (i = 0; i < 100; i++) {
90 REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +000091 }
reed@google.com70442a62011-06-23 21:48:04 +000092
93 {
bungeman@google.comc29f3d82013-07-19 22:32:11 +000094 SkAutoTUnref<SkStreamAsset> stream(ds.detachAsStream());
bungeman@google.com88682b72013-07-19 13:55:41 +000095 REPORTER_ASSERT(reporter, 100 * 26 == stream->getLength());
96 REPORTER_ASSERT(reporter, ds.getOffset() == 0);
97 test_loop_stream(reporter, stream.get(), s, 26, 100);
98
99 SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate());
100 test_loop_stream(reporter, stream2.get(), s, 26, 100);
101
102 SkAutoTUnref<SkStreamAsset> stream3(stream->fork());
103 REPORTER_ASSERT(reporter, stream3->isAtEnd());
104 char tmp;
105 size_t bytes = stream->read(&tmp, 1);
106 REPORTER_ASSERT(reporter, 0 == bytes);
107 stream3->rewind();
108 test_loop_stream(reporter, stream3.get(), s, 26, 100);
109 }
110
111 for (i = 0; i < 100; i++) {
112 REPORTER_ASSERT(reporter, ds.write(s, 26));
113 }
114 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
115
116 {
117 SkAutoTUnref<SkData> data(ds.copyToData());
reed@google.com70442a62011-06-23 21:48:04 +0000118 REPORTER_ASSERT(reporter, 100 * 26 == data->size());
119 REPORTER_ASSERT(reporter, memcmp(dst, data->data(), data->size()) == 0);
bungeman@google.com88682b72013-07-19 13:55:41 +0000120 }
121
122 {
123 // Test that this works after a copyToData.
bungeman@google.comc29f3d82013-07-19 22:32:11 +0000124 SkAutoTUnref<SkStreamAsset> stream(ds.detachAsStream());
bungeman@google.com88682b72013-07-19 13:55:41 +0000125 REPORTER_ASSERT(reporter, ds.getOffset() == 0);
126 test_loop_stream(reporter, stream.get(), s, 26, 100);
127
128 SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate());
129 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com70442a62011-06-23 21:48:04 +0000130 }
reed@android.com80e39a72009-04-02 16:59:40 +0000131 delete[] dst;
reed@google.com789c6f22013-02-25 20:24:24 +0000132
scroggo@google.comc76218d2013-06-06 14:59:56 +0000133 SkString tmpDir = skiatest::Test::GetTmpDir();
134 if (!tmpDir.isEmpty()) {
135 test_filestreams(reporter, tmpDir.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +0000136 }
reed@android.com5e5adfd2009-03-07 03:39:23 +0000137}
138
reed@google.com19f286b2011-10-18 11:49:52 +0000139static void TestPackedUInt(skiatest::Reporter* reporter) {
140 // we know that packeduint tries to write 1, 2 or 4 bytes for the length,
141 // so we test values around each of those transitions (and a few others)
142 const size_t sizes[] = {
143 0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769,
144 0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001,
145 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001,
146 0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF
147 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000148
149
reed@google.com19f286b2011-10-18 11:49:52 +0000150 size_t i;
151 char buffer[sizeof(sizes) * 4];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000152
reed@google.com19f286b2011-10-18 11:49:52 +0000153 SkMemoryWStream wstream(buffer, sizeof(buffer));
154 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
155 bool success = wstream.writePackedUInt(sizes[i]);
156 REPORTER_ASSERT(reporter, success);
157 }
158 wstream.flush();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000159
reed@google.com19f286b2011-10-18 11:49:52 +0000160 SkMemoryStream rstream(buffer, sizeof(buffer));
161 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
162 size_t n = rstream.readPackedUInt();
163 if (sizes[i] != n) {
164 SkDebugf("-- %d: sizes:%x n:%x\n", i, sizes[i], n);
165 }
166 REPORTER_ASSERT(reporter, sizes[i] == n);
167 }
168}
169
scroggo@google.come4904202013-01-09 22:02:58 +0000170// Test that setting an SkMemoryStream to a NULL data does not result in a crash when calling
171// methods that access fData.
172static void TestDereferencingData(SkMemoryStream* memStream) {
173 memStream->read(NULL, 0);
174 memStream->getMemoryBase();
175 SkAutoDataUnref data(memStream->copyToData());
176}
177
178static void TestNullData() {
179 SkData* nullData = NULL;
180 SkMemoryStream memStream(nullData);
181 TestDereferencingData(&memStream);
182
183 memStream.setData(nullData);
184 TestDereferencingData(&memStream);
185
186}
187
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000188DEF_TEST(Stream, reporter) {
reed@android.com5e5adfd2009-03-07 03:39:23 +0000189 TestWStream(reporter);
reed@google.com19f286b2011-10-18 11:49:52 +0000190 TestPackedUInt(reporter);
scroggo@google.come4904202013-01-09 22:02:58 +0000191 TestNullData();
reed@android.com5e5adfd2009-03-07 03:39:23 +0000192}