Index: tests/StreamTest.cpp |
diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp |
index 838a8a4d0f1ed285a81be7aa0d12a9a99e373834..15ebfcf07d63bc29345fbcac227fd3e803eb5091 100644 |
--- a/tests/StreamTest.cpp |
+++ b/tests/StreamTest.cpp |
@@ -197,10 +197,10 @@ DEF_TEST(Stream, reporter) { |
/** |
* Tests peeking and then reading the same amount. The two should provide the |
* same results. |
- * Returns whether the stream could peek. |
+ * Returns the amount successfully read minus the amount successfully peeked. |
*/ |
-static bool compare_peek_to_read(skiatest::Reporter* reporter, |
- SkStream* stream, size_t bytesToPeek) { |
+static size_t compare_peek_to_read(skiatest::Reporter* reporter, |
+ SkStream* stream, size_t bytesToPeek) { |
// The rest of our tests won't be very interesting if bytesToPeek is zero. |
REPORTER_ASSERT(reporter, bytesToPeek > 0); |
SkAutoMalloc peekStorage(bytesToPeek); |
@@ -208,9 +208,7 @@ static bool compare_peek_to_read(skiatest::Reporter* reporter, |
void* peekPtr = peekStorage.get(); |
void* readPtr = peekStorage.get(); |
- if (!stream->peek(peekPtr, bytesToPeek)) { |
- return false; |
- } |
+ const size_t bytesPeeked = stream->peek(peekPtr, bytesToPeek); |
const size_t bytesRead = stream->read(readPtr, bytesToPeek); |
// bytesRead should only be less than attempted if the stream is at the |
@@ -219,21 +217,17 @@ static bool compare_peek_to_read(skiatest::Reporter* reporter, |
// peek and read should behave the same, except peek returned to the |
// original position, so they read the same data. |
- REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesRead)); |
+ REPORTER_ASSERT(reporter, !memcmp(peekPtr, readPtr, bytesPeeked)); |
+ |
+ // A stream should never be able to peek more than it can read. |
+ REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked); |
- return true; |
+ return bytesRead - bytesPeeked; |
} |
-static void test_peeking_stream(skiatest::Reporter* r, SkStream* stream, size_t limit) { |
- size_t peeked = 0; |
+static void test_fully_peekable_stream(skiatest::Reporter* r, SkStream* stream, size_t limit) { |
for (size_t i = 1; !stream->isAtEnd(); i++) { |
- const bool couldPeek = compare_peek_to_read(r, stream, i); |
- if (!couldPeek) { |
- REPORTER_ASSERT(r, peeked + i > limit); |
- // No more peeking is supported. |
- break; |
- } |
- peeked += i; |
+ REPORTER_ASSERT(r, compare_peek_to_read(r, stream, i) == 0); |
} |
} |
@@ -244,7 +238,51 @@ static void test_peeking_front_buffered_stream(skiatest::Reporter* r, |
REPORTER_ASSERT(r, dupe != nullptr); |
SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, bufferSize)); |
REPORTER_ASSERT(r, bufferedStream != nullptr); |
- test_peeking_stream(r, bufferedStream, bufferSize); |
+ |
+ size_t peeked = 0; |
+ for (size_t i = 1; !bufferedStream->isAtEnd(); i++) { |
+ const size_t unpeekableBytes = compare_peek_to_read(r, bufferedStream, i); |
+ if (unpeekableBytes > 0) { |
+ // This could not have returned a number greater than i. |
+ REPORTER_ASSERT(r, unpeekableBytes <= i); |
+ |
+ // We have reached the end of the buffer. Verify that it was at least |
+ // bufferSize. |
+ REPORTER_ASSERT(r, peeked + i - unpeekableBytes >= bufferSize); |
+ // No more peeking is supported. |
+ break; |
+ } |
+ peeked += i; |
+ } |
+ |
+ // Test that attempting to peek beyond the length of the buffer does not prevent rewinding. |
+ bufferedStream.reset(SkFrontBufferedStream::Create(original.duplicate(), bufferSize)); |
+ REPORTER_ASSERT(r, bufferedStream != nullptr); |
+ |
+ const size_t bytesToPeek = bufferSize + 1; |
+ SkAutoMalloc peekStorage(bytesToPeek); |
+ SkAutoMalloc readStorage(bytesToPeek); |
+ |
+ for (size_t start = 0; start <= bufferSize; start++) { |
+ // Skip to the starting point |
+ REPORTER_ASSERT(r, bufferedStream->skip(start) == start); |
+ REPORTER_ASSERT(r, bufferedStream->getPosition() == start); |
+ |
+ const size_t bytesPeeked = bufferedStream->peek(peekStorage.get(), bytesToPeek); |
+ if (0 == bytesPeeked) { |
+ // Peeking should only fail completely if we have read beyond the buffer. |
+ REPORTER_ASSERT(r, bufferedStream->getPosition() >= bufferSize); |
+ break; |
+ } |
+ |
+ // Only read the amount that was successfully peeked. |
+ const size_t bytesRead = bufferedStream->read(readStorage.get(), bytesPeeked); |
+ REPORTER_ASSERT(r, bytesRead == bytesPeeked); |
+ REPORTER_ASSERT(r, !memcmp(peekStorage.get(), readStorage.get(), bytesPeeked)); |
+ |
+ // This should be safe to rewind. |
+ REPORTER_ASSERT(r, bufferedStream->rewind()); |
+ } |
} |
// This test uses file system operations that don't work out of the |
@@ -255,7 +293,7 @@ DEF_TEST(StreamPeek, reporter) { |
// Test a memory stream. |
const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz"; |
SkMemoryStream memStream(gAbcs, strlen(gAbcs), false); |
- test_peeking_stream(reporter, &memStream, memStream.getLength()); |
+ test_fully_peekable_stream(reporter, &memStream, memStream.getLength()); |
// Test an arbitrary file stream. file streams do not support peeking. |
SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str()); |
@@ -265,7 +303,7 @@ DEF_TEST(StreamPeek, reporter) { |
} |
SkAutoMalloc storage(fileStream.getLength()); |
for (size_t i = 1; i < fileStream.getLength(); i++) { |
- REPORTER_ASSERT(reporter, !fileStream.peek(storage.get(), i)); |
+ REPORTER_ASSERT(reporter, fileStream.peek(storage.get(), i) == 0); |
} |
// Now test some FrontBufferedStreams |
@@ -293,7 +331,7 @@ static void stream_peek_test(skiatest::Reporter* rep, |
SkASSERT(size >= 1); |
SkASSERT(size <= sizeof(buffer)); |
SkASSERT(size + i <= asset->getLength()); |
- if (!asset->peek(buffer, size)) { |
+ if (asset->peek(buffer, size) < size) { |
ERRORF(rep, "Peek Failed!"); |
return; |
} |