aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/StreamTest.cpp
diff options
context:
space:
mode:
authorGravatar scroggo <scroggo@google.com>2015-12-07 11:37:13 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-07 11:37:13 -0800
commitd61c384342aaf7facf31b948db98acc32d81d21b (patch)
tree76ed2ef565c4786b83b368974f77b695d99376ea /tests/StreamTest.cpp
parent3660d534516e4687546a43ac80d0ae40bc68dae7 (diff)
Allow SkStream::peek() to partially succeed
If the stream can peek less than requested, peek that amount. Return the number of bytes peeked. This simplifies crrev.com/1472123002. For a stream that is smaller than 14 bytes, it can successfully peek, meaning the client will not need to fall back to read() + rewind(), which may fail if the stream can peek but not rewind. This CL revives code from patch set 3 of crrev.com/1044953002, where I initially introduced peek() (including tests). Add a test for SkFrontBufferedStream that verifies that peeking does not make rewind() fail (i.e. by reading past the internal buffer). BUG=skia:3257 Review URL: https://codereview.chromium.org/1490923005
Diffstat (limited to 'tests/StreamTest.cpp')
-rw-r--r--tests/StreamTest.cpp80
1 files changed, 59 insertions, 21 deletions
diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp
index 838a8a4d0f..15ebfcf07d 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;
}