Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: tests/StreamTest.cpp

Issue 1490923005: Allow SkStream::peek() to partially succeed (Closed) Base URL: https://skia.googlesource.com/skia.git@wbmp
Patch Set: Use the correct return type Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/utils/SkFrontBufferedStream.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "Resources.h" 8 #include "Resources.h"
9 #include "SkData.h" 9 #include "SkData.h"
10 #include "SkFrontBufferedStream.h" 10 #include "SkFrontBufferedStream.h"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 190
191 DEF_TEST(Stream, reporter) { 191 DEF_TEST(Stream, reporter) {
192 TestWStream(reporter); 192 TestWStream(reporter);
193 TestPackedUInt(reporter); 193 TestPackedUInt(reporter);
194 TestNullData(); 194 TestNullData();
195 } 195 }
196 196
197 /** 197 /**
198 * Tests peeking and then reading the same amount. The two should provide the 198 * Tests peeking and then reading the same amount. The two should provide the
199 * same results. 199 * same results.
200 * Returns whether the stream could peek. 200 * Returns the amount successfully read minus the amount successfully peeked.
201 */ 201 */
202 static bool compare_peek_to_read(skiatest::Reporter* reporter, 202 static size_t compare_peek_to_read(skiatest::Reporter* reporter,
203 SkStream* stream, size_t bytesToPeek) { 203 SkStream* stream, size_t bytesToPeek) {
204 // The rest of our tests won't be very interesting if bytesToPeek is zero. 204 // The rest of our tests won't be very interesting if bytesToPeek is zero.
205 REPORTER_ASSERT(reporter, bytesToPeek > 0); 205 REPORTER_ASSERT(reporter, bytesToPeek > 0);
206 SkAutoMalloc peekStorage(bytesToPeek); 206 SkAutoMalloc peekStorage(bytesToPeek);
207 SkAutoMalloc readStorage(bytesToPeek); 207 SkAutoMalloc readStorage(bytesToPeek);
208 void* peekPtr = peekStorage.get(); 208 void* peekPtr = peekStorage.get();
209 void* readPtr = peekStorage.get(); 209 void* readPtr = peekStorage.get();
210 210
211 if (!stream->peek(peekPtr, bytesToPeek)) { 211 const size_t bytesPeeked = stream->peek(peekPtr, bytesToPeek);
212 return false;
213 }
214 const size_t bytesRead = stream->read(readPtr, bytesToPeek); 212 const size_t bytesRead = stream->read(readPtr, bytesToPeek);
215 213
216 // bytesRead should only be less than attempted if the stream is at the 214 // bytesRead should only be less than attempted if the stream is at the
217 // end. 215 // end.
218 REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd()); 216 REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd());
219 217
220 // peek and read should behave the same, except peek returned to the 218 // peek and read should behave the same, except peek returned to the
221 // original position, so they read the same data. 219 // original position, so they read the same data.
222 REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesRead)); 220 REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesPeeked));
223 221
224 return true; 222 // A stream should never be able to peek more than it can read.
223 REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked);
224
225 return bytesRead - bytesPeeked;
225 } 226 }
226 227
227 static void test_peeking_stream(skiatest::Reporter* r, SkStream* stream, size_t limit) { 228 static void test_fully_peekable_stream(skiatest::Reporter* r, SkStream* stream, size_t limit) {
228 size_t peeked = 0;
229 for (size_t i = 1; !stream->isAtEnd(); i++) { 229 for (size_t i = 1; !stream->isAtEnd(); i++) {
230 const bool couldPeek = compare_peek_to_read(r, stream, i); 230 REPORTER_ASSERT(r, compare_peek_to_read(r, stream, i) == 0);
231 if (!couldPeek) {
232 REPORTER_ASSERT(r, peeked + i > limit);
233 // No more peeking is supported.
234 break;
235 }
236 peeked += i;
237 } 231 }
238 } 232 }
239 233
240 static void test_peeking_front_buffered_stream(skiatest::Reporter* r, 234 static void test_peeking_front_buffered_stream(skiatest::Reporter* r,
241 const SkStream& original, 235 const SkStream& original,
242 size_t bufferSize) { 236 size_t bufferSize) {
243 SkStream* dupe = original.duplicate(); 237 SkStream* dupe = original.duplicate();
244 REPORTER_ASSERT(r, dupe != nullptr); 238 REPORTER_ASSERT(r, dupe != nullptr);
245 SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, b ufferSize)); 239 SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, b ufferSize));
246 REPORTER_ASSERT(r, bufferedStream != nullptr); 240 REPORTER_ASSERT(r, bufferedStream != nullptr);
247 test_peeking_stream(r, bufferedStream, bufferSize); 241
242 size_t peeked = 0;
243 for (size_t i = 1; !bufferedStream->isAtEnd(); i++) {
244 const size_t unpeekableBytes = compare_peek_to_read(r, bufferedStream, i );
245 if (unpeekableBytes > 0) {
246 // This could not have returned a number greater than i.
247 REPORTER_ASSERT(r, unpeekableBytes <= i);
248
249 // We have reached the end of the buffer. Verify that it was at leas t
250 // bufferSize.
251 REPORTER_ASSERT(r, peeked + i - unpeekableBytes >= bufferSize);
252 // No more peeking is supported.
253 break;
254 }
255 peeked += i;
256 }
257
258 // Test that attempting to peek beyond the length of the buffer does not pre vent rewinding.
259 bufferedStream.reset(SkFrontBufferedStream::Create(original.duplicate(), buf ferSize));
260 REPORTER_ASSERT(r, bufferedStream != nullptr);
261
262 const size_t bytesToPeek = bufferSize + 1;
263 SkAutoMalloc peekStorage(bytesToPeek);
264 SkAutoMalloc readStorage(bytesToPeek);
265
266 for (size_t start = 0; start <= bufferSize; start++) {
267 // Skip to the starting point
268 REPORTER_ASSERT(r, bufferedStream->skip(start) == start);
269 REPORTER_ASSERT(r, bufferedStream->getPosition() == start);
270
271 const size_t bytesPeeked = bufferedStream->peek(peekStorage.get(), bytes ToPeek);
272 if (0 == bytesPeeked) {
273 // Peeking should only fail completely if we have read beyond the bu ffer.
274 REPORTER_ASSERT(r, bufferedStream->getPosition() >= bufferSize);
275 break;
276 }
277
278 // Only read the amount that was successfully peeked.
279 const size_t bytesRead = bufferedStream->read(readStorage.get(), bytesPe eked);
280 REPORTER_ASSERT(r, bytesRead == bytesPeeked);
281 REPORTER_ASSERT(r, !memcmp(peekStorage.get(), readStorage.get(), bytesPe eked));
282
283 // This should be safe to rewind.
284 REPORTER_ASSERT(r, bufferedStream->rewind());
285 }
248 } 286 }
249 287
250 // This test uses file system operations that don't work out of the 288 // This test uses file system operations that don't work out of the
251 // box on iOS. It's likely that we don't need them on iOS. Ignoring for now. 289 // box on iOS. It's likely that we don't need them on iOS. Ignoring for now.
252 // TODO(stephana): Re-evaluate if we need this in the future. 290 // TODO(stephana): Re-evaluate if we need this in the future.
253 #ifndef SK_BUILD_FOR_IOS 291 #ifndef SK_BUILD_FOR_IOS
254 DEF_TEST(StreamPeek, reporter) { 292 DEF_TEST(StreamPeek, reporter) {
255 // Test a memory stream. 293 // Test a memory stream.
256 const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz"; 294 const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz";
257 SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); 295 SkMemoryStream memStream(gAbcs, strlen(gAbcs), false);
258 test_peeking_stream(reporter, &memStream, memStream.getLength()); 296 test_fully_peekable_stream(reporter, &memStream, memStream.getLength());
259 297
260 // Test an arbitrary file stream. file streams do not support peeking. 298 // Test an arbitrary file stream. file streams do not support peeking.
261 SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str()); 299 SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str());
262 REPORTER_ASSERT(reporter, fileStream.isValid()); 300 REPORTER_ASSERT(reporter, fileStream.isValid());
263 if (!fileStream.isValid()) { 301 if (!fileStream.isValid()) {
264 return; 302 return;
265 } 303 }
266 SkAutoMalloc storage(fileStream.getLength()); 304 SkAutoMalloc storage(fileStream.getLength());
267 for (size_t i = 1; i < fileStream.getLength(); i++) { 305 for (size_t i = 1; i < fileStream.getLength(); i++) {
268 REPORTER_ASSERT(reporter, !fileStream.peek(storage.get(), i)); 306 REPORTER_ASSERT(reporter, fileStream.peek(storage.get(), i) == 0);
269 } 307 }
270 308
271 // Now test some FrontBufferedStreams 309 // Now test some FrontBufferedStreams
272 for (size_t i = 1; i < memStream.getLength(); i++) { 310 for (size_t i = 1; i < memStream.getLength(); i++) {
273 test_peeking_front_buffered_stream(reporter, memStream, i); 311 test_peeking_front_buffered_stream(reporter, memStream, i);
274 } 312 }
275 } 313 }
276 #endif 314 #endif
277 315
278 // Asserts that asset == expected and is peekable. 316 // Asserts that asset == expected and is peekable.
279 static void stream_peek_test(skiatest::Reporter* rep, 317 static void stream_peek_test(skiatest::Reporter* rep,
280 SkStreamAsset* asset, 318 SkStreamAsset* asset,
281 const SkData* expected) { 319 const SkData* expected) {
282 if (asset->getLength() != expected->size()) { 320 if (asset->getLength() != expected->size()) {
283 ERRORF(rep, "Unexpected length."); 321 ERRORF(rep, "Unexpected length.");
284 return; 322 return;
285 } 323 }
286 SkRandom rand; 324 SkRandom rand;
287 uint8_t buffer[4096]; 325 uint8_t buffer[4096];
288 const uint8_t* expect = expected->bytes(); 326 const uint8_t* expect = expected->bytes();
289 for (size_t i = 0; i < asset->getLength(); ++i) { 327 for (size_t i = 0; i < asset->getLength(); ++i) {
290 uint32_t maxSize = 328 uint32_t maxSize =
291 SkToU32(SkTMin(sizeof(buffer), asset->getLength() - i)); 329 SkToU32(SkTMin(sizeof(buffer), asset->getLength() - i));
292 size_t size = rand.nextRangeU(1, maxSize); 330 size_t size = rand.nextRangeU(1, maxSize);
293 SkASSERT(size >= 1); 331 SkASSERT(size >= 1);
294 SkASSERT(size <= sizeof(buffer)); 332 SkASSERT(size <= sizeof(buffer));
295 SkASSERT(size + i <= asset->getLength()); 333 SkASSERT(size + i <= asset->getLength());
296 if (!asset->peek(buffer, size)) { 334 if (asset->peek(buffer, size) < size) {
297 ERRORF(rep, "Peek Failed!"); 335 ERRORF(rep, "Peek Failed!");
298 return; 336 return;
299 } 337 }
300 if (0 != memcmp(buffer, &expect[i], size)) { 338 if (0 != memcmp(buffer, &expect[i], size)) {
301 ERRORF(rep, "Peek returned wrong bytes!"); 339 ERRORF(rep, "Peek returned wrong bytes!");
302 return; 340 return;
303 } 341 }
304 uint8_t value; 342 uint8_t value;
305 REPORTER_ASSERT(rep, 1 == asset->read(&value, 1)); 343 REPORTER_ASSERT(rep, 1 == asset->read(&value, 1));
306 if (value != expect[i]) { 344 if (value != expect[i]) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 SkMemoryStream smartStream(src.get(), (size_t)N); 430 SkMemoryStream smartStream(src.get(), (size_t)N);
393 stream_copy_test(reporter, src, N, &smartStream); 431 stream_copy_test(reporter, src, N, &smartStream);
394 } 432 }
395 433
396 DEF_TEST(StreamEmptyStreamMemoryBase, r) { 434 DEF_TEST(StreamEmptyStreamMemoryBase, r) {
397 SkDynamicMemoryWStream tmp; 435 SkDynamicMemoryWStream tmp;
398 SkAutoTDelete<SkStreamAsset> asset(tmp.detachAsStream()); 436 SkAutoTDelete<SkStreamAsset> asset(tmp.detachAsStream());
399 REPORTER_ASSERT(r, nullptr == asset->getMemoryBase()); 437 REPORTER_ASSERT(r, nullptr == asset->getMemoryBase());
400 } 438 }
401 439
OLDNEW
« no previous file with comments | « src/utils/SkFrontBufferedStream.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698