blob: 29d74fe9d89bd96ed85329335461df4a6f567113 [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"
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()) {
47 SkString msg;
48 msg.printf("Failed to create tmp file %s\n", path.c_str());
commit-bot@chromium.org1f792862013-06-18 20:50:34 +000049 reporter->reportFailed(msg);
reed@google.com789c6f22013-02-25 20:24:24 +000050 return;
51 }
52
53 for (int i = 0; i < 100; ++i) {
54 writer.write(s, 26);
55 }
56 }
57
58 {
59 SkFILEStream stream(path.c_str());
60 REPORTER_ASSERT(reporter, stream.isValid());
61 test_loop_stream(reporter, &stream, s, 26, 100);
bungeman@google.com6cab1a42013-05-29 13:43:31 +000062
63 SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate());
64 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com789c6f22013-02-25 20:24:24 +000065 }
66
reed@google.com789c6f22013-02-25 20:24:24 +000067 {
bungeman@google.com6cab1a42013-05-29 13:43:31 +000068 FILE* file = ::fopen(path.c_str(), "rb");
69 SkFILEStream stream(file, SkFILEStream::kCallerPasses_Ownership);
reed@google.com789c6f22013-02-25 20:24:24 +000070 REPORTER_ASSERT(reporter, stream.isValid());
71 test_loop_stream(reporter, &stream, s, 26, 100);
bungeman@google.com6cab1a42013-05-29 13:43:31 +000072
73 SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate());
74 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com789c6f22013-02-25 20:24:24 +000075 }
reed@google.com789c6f22013-02-25 20:24:24 +000076}
77
reed@android.com80e39a72009-04-02 16:59:40 +000078static void TestWStream(skiatest::Reporter* reporter) {
79 SkDynamicMemoryWStream ds;
80 const char s[] = "abcdefghijklmnopqrstuvwxyz";
81 int i;
82 for (i = 0; i < 100; i++) {
83 REPORTER_ASSERT(reporter, ds.write(s, 26));
reed@android.com5e5adfd2009-03-07 03:39:23 +000084 }
reed@android.com80e39a72009-04-02 16:59:40 +000085 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
bungeman@google.com88682b72013-07-19 13:55:41 +000086
reed@android.com80e39a72009-04-02 16:59:40 +000087 char* dst = new char[100 * 26 + 1];
88 dst[100*26] = '*';
89 ds.copyTo(dst);
90 REPORTER_ASSERT(reporter, dst[100*26] == '*');
reed@android.com80e39a72009-04-02 16:59:40 +000091 for (i = 0; i < 100; i++) {
92 REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +000093 }
reed@google.com70442a62011-06-23 21:48:04 +000094
95 {
bungeman@google.comc29f3d82013-07-19 22:32:11 +000096 SkAutoTUnref<SkStreamAsset> stream(ds.detachAsStream());
bungeman@google.com88682b72013-07-19 13:55:41 +000097 REPORTER_ASSERT(reporter, 100 * 26 == stream->getLength());
98 REPORTER_ASSERT(reporter, ds.getOffset() == 0);
99 test_loop_stream(reporter, stream.get(), s, 26, 100);
100
101 SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate());
102 test_loop_stream(reporter, stream2.get(), s, 26, 100);
103
104 SkAutoTUnref<SkStreamAsset> stream3(stream->fork());
105 REPORTER_ASSERT(reporter, stream3->isAtEnd());
106 char tmp;
107 size_t bytes = stream->read(&tmp, 1);
108 REPORTER_ASSERT(reporter, 0 == bytes);
109 stream3->rewind();
110 test_loop_stream(reporter, stream3.get(), s, 26, 100);
111 }
112
113 for (i = 0; i < 100; i++) {
114 REPORTER_ASSERT(reporter, ds.write(s, 26));
115 }
116 REPORTER_ASSERT(reporter, ds.getOffset() == 100 * 26);
117
118 {
119 SkAutoTUnref<SkData> data(ds.copyToData());
reed@google.com70442a62011-06-23 21:48:04 +0000120 REPORTER_ASSERT(reporter, 100 * 26 == data->size());
121 REPORTER_ASSERT(reporter, memcmp(dst, data->data(), data->size()) == 0);
bungeman@google.com88682b72013-07-19 13:55:41 +0000122 }
123
124 {
125 // Test that this works after a copyToData.
bungeman@google.comc29f3d82013-07-19 22:32:11 +0000126 SkAutoTUnref<SkStreamAsset> stream(ds.detachAsStream());
bungeman@google.com88682b72013-07-19 13:55:41 +0000127 REPORTER_ASSERT(reporter, ds.getOffset() == 0);
128 test_loop_stream(reporter, stream.get(), s, 26, 100);
129
130 SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate());
131 test_loop_stream(reporter, stream2.get(), s, 26, 100);
reed@google.com70442a62011-06-23 21:48:04 +0000132 }
reed@android.com80e39a72009-04-02 16:59:40 +0000133 delete[] dst;
reed@google.com789c6f22013-02-25 20:24:24 +0000134
scroggo@google.comc76218d2013-06-06 14:59:56 +0000135 SkString tmpDir = skiatest::Test::GetTmpDir();
136 if (!tmpDir.isEmpty()) {
137 test_filestreams(reporter, tmpDir.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +0000138 }
reed@android.com5e5adfd2009-03-07 03:39:23 +0000139}
140
reed@google.com19f286b2011-10-18 11:49:52 +0000141static void TestPackedUInt(skiatest::Reporter* reporter) {
142 // we know that packeduint tries to write 1, 2 or 4 bytes for the length,
143 // so we test values around each of those transitions (and a few others)
144 const size_t sizes[] = {
145 0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769,
146 0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001,
147 0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001,
148 0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF
149 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000150
151
reed@google.com19f286b2011-10-18 11:49:52 +0000152 size_t i;
153 char buffer[sizeof(sizes) * 4];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000154
reed@google.com19f286b2011-10-18 11:49:52 +0000155 SkMemoryWStream wstream(buffer, sizeof(buffer));
156 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
157 bool success = wstream.writePackedUInt(sizes[i]);
158 REPORTER_ASSERT(reporter, success);
159 }
160 wstream.flush();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000161
reed@google.com19f286b2011-10-18 11:49:52 +0000162 SkMemoryStream rstream(buffer, sizeof(buffer));
163 for (i = 0; i < SK_ARRAY_COUNT(sizes); ++i) {
164 size_t n = rstream.readPackedUInt();
165 if (sizes[i] != n) {
166 SkDebugf("-- %d: sizes:%x n:%x\n", i, sizes[i], n);
167 }
168 REPORTER_ASSERT(reporter, sizes[i] == n);
169 }
170}
171
scroggo@google.come4904202013-01-09 22:02:58 +0000172// Test that setting an SkMemoryStream to a NULL data does not result in a crash when calling
173// methods that access fData.
174static void TestDereferencingData(SkMemoryStream* memStream) {
175 memStream->read(NULL, 0);
176 memStream->getMemoryBase();
177 SkAutoDataUnref data(memStream->copyToData());
178}
179
180static void TestNullData() {
181 SkData* nullData = NULL;
182 SkMemoryStream memStream(nullData);
183 TestDereferencingData(&memStream);
184
185 memStream.setData(nullData);
186 TestDereferencingData(&memStream);
187
188}
189
reed@android.com5e5adfd2009-03-07 03:39:23 +0000190static void TestStreams(skiatest::Reporter* reporter) {
reed@android.com5e5adfd2009-03-07 03:39:23 +0000191 TestWStream(reporter);
reed@google.com19f286b2011-10-18 11:49:52 +0000192 TestPackedUInt(reporter);
scroggo@google.come4904202013-01-09 22:02:58 +0000193 TestNullData();
reed@android.com5e5adfd2009-03-07 03:39:23 +0000194}
195
196#include "TestClassDef.h"
197DEFINE_TESTCLASS("Stream", StreamTestClass, TestStreams)