blob: 16978d59cbea158579b8ac9845af12b29a9b7fda [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"
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +00009#include "TestClassDef.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000010#include "SkRandom.h"
bungeman@google.com6cab1a42013-05-29 13:43:31 +000011#include "SkOSFile.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000012#include "SkStream.h"
reed@google.com8d0b5772011-06-24 13:07:31 +000013#include "SkData.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +000014
reed@google.com789c6f22013-02-25 20:24:24 +000015#ifndef SK_BUILD_FOR_WIN
16#include <unistd.h>
17#include <fcntl.h>
18#endif
19
reed@android.com5e5adfd2009-03-07 03:39:23 +000020#define MAX_SIZE (256 * 1024)
21
reed@google.com789c6f22013-02-25 20:24:24 +000022static void test_loop_stream(skiatest::Reporter* reporter, SkStream* stream,
23 const void* src, size_t len, int repeat) {
24 SkAutoSMalloc<256> storage(len);
25 void* tmp = storage.get();
26
27 for (int i = 0; i < repeat; ++i) {
28 size_t bytes = stream->read(tmp, len);
29 REPORTER_ASSERT(reporter, bytes == len);
30 REPORTER_ASSERT(reporter, !memcmp(tmp, src, len));
31 }
32
33 // expect EOF
34 size_t bytes = stream->read(tmp, 1);
35 REPORTER_ASSERT(reporter, 0 == bytes);
bungeman@google.com88682b72013-07-19 13:55:41 +000036 // isAtEnd might not return true until after the first failing read.
37 REPORTER_ASSERT(reporter, stream->isAtEnd());
reed@google.com789c6f22013-02-25 20:24:24 +000038}
39
40static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) {
scroggo@google.comc76218d2013-06-06 14:59:56 +000041 SkString path = SkOSPath::SkPathJoin(tmpDir, "wstream_test");
reed@google.com789c6f22013-02-25 20:24:24 +000042
43 const char s[] = "abcdefghijklmnopqrstuvwxyz";
44
45 {
46 SkFILEWStream writer(path.c_str());
47 if (!writer.isValid()) {
48 SkString msg;
49 msg.printf("Failed to create tmp file %s\n", path.c_str());
commit-bot@chromium.org1f792862013-06-18 20:50:34 +000050 reporter->reportFailed(msg);
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
64 SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate());
65 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
74 SkAutoTUnref<SkStreamAsset> stream2(stream.duplicate());
75 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 {
bungeman@google.comc29f3d82013-07-19 22:32:11 +000097 SkAutoTUnref<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
102 SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate());
103 test_loop_stream(reporter, stream2.get(), s, 26, 100);
104
105 SkAutoTUnref<SkStreamAsset> stream3(stream->fork());
106 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 {
120 SkAutoTUnref<SkData> data(ds.copyToData());
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 {
126 // Test that this works after a copyToData.
bungeman@google.comc29f3d82013-07-19 22:32:11 +0000127 SkAutoTUnref<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
131 SkAutoTUnref<SkStreamAsset> stream2(stream->duplicate());
132 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
scroggo@google.comc76218d2013-06-06 14:59:56 +0000136 SkString tmpDir = skiatest::Test::GetTmpDir();
137 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) {
167 SkDebugf("-- %d: sizes:%x n:%x\n", i, sizes[i], n);
168 }
169 REPORTER_ASSERT(reporter, sizes[i] == n);
170 }
171}
172
scroggo@google.come4904202013-01-09 22:02:58 +0000173// Test that setting an SkMemoryStream to a NULL data does not result in a crash when calling
174// methods that access fData.
175static void TestDereferencingData(SkMemoryStream* memStream) {
176 memStream->read(NULL, 0);
177 memStream->getMemoryBase();
178 SkAutoDataUnref data(memStream->copyToData());
179}
180
181static void TestNullData() {
182 SkData* nullData = NULL;
183 SkMemoryStream memStream(nullData);
184 TestDereferencingData(&memStream);
185
186 memStream.setData(nullData);
187 TestDereferencingData(&memStream);
188
189}
190
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000191DEF_TEST(Stream, reporter) {
reed@android.com5e5adfd2009-03-07 03:39:23 +0000192 TestWStream(reporter);
reed@google.com19f286b2011-10-18 11:49:52 +0000193 TestPackedUInt(reporter);
scroggo@google.come4904202013-01-09 22:02:58 +0000194 TestNullData();
reed@android.com5e5adfd2009-03-07 03:39:23 +0000195}