| Index: tests/StreamTest.cpp
|
| diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp
|
| index ff22ecf5548799cdf7c09a2ee0129167417e4224..1570e2fd2986fe2d63bc82d45844224af2824e8e 100644
|
| --- a/tests/StreamTest.cpp
|
| +++ b/tests/StreamTest.cpp
|
| @@ -5,7 +5,9 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| +#include "Resources.h"
|
| #include "SkData.h"
|
| +#include "SkFrontBufferedStream.h"
|
| #include "SkOSFile.h"
|
| #include "SkRandom.h"
|
| #include "SkStream.h"
|
| @@ -190,3 +192,88 @@ DEF_TEST(Stream, reporter) {
|
| TestPackedUInt(reporter);
|
| TestNullData();
|
| }
|
| +
|
| +/**
|
| + * Tests peeking and then reading the same amount. The two should provide the
|
| + * same results.
|
| + * Returns the amount successfully read minus the amount successfully peeked.
|
| + */
|
| +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);
|
| + SkAutoMalloc readStorage(bytesToPeek);
|
| + void* peekPtr = peekStorage.get();
|
| + void* readPtr = peekStorage.get();
|
| +
|
| + 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
|
| + // end.
|
| + REPORTER_ASSERT(reporter, bytesRead == bytesToPeek || stream->isAtEnd());
|
| +
|
| + if (0 == bytesPeeked) {
|
| + // The mem compare will not be very interesting here.
|
| + return bytesRead;
|
| + }
|
| +
|
| + // 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, bytesPeeked));
|
| +
|
| + // A stream should never be able to peek less than it can read.
|
| + REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked);
|
| + return bytesRead - bytesPeeked;
|
| +}
|
| +
|
| +// Test peeking on a stream for which peeking is always supported.
|
| +static void test_fully_peekable_stream(skiatest::Reporter* r,
|
| + SkStream* stream) {
|
| + for (size_t i = 1; !stream->isAtEnd(); i++) {
|
| + // We can always peek as many bytes as we can read.
|
| + REPORTER_ASSERT(r, compare_peek_to_read(r, stream, i) == 0);
|
| + }
|
| +}
|
| +
|
| +static void test_peeking_front_buffered_stream(skiatest::Reporter* r,
|
| + const SkStream& original,
|
| + size_t bufferSize) {
|
| + SkStream* dupe = original.duplicate();
|
| + REPORTER_ASSERT(r, dupe != NULL);
|
| + SkAutoTDelete<SkStream> bufferedStream(SkFrontBufferedStream::Create(dupe, bufferSize));
|
| + REPORTER_ASSERT(r, bufferedStream != NULL);
|
| + size_t peeked = 0;
|
| + for (size_t i = 0; !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;
|
| + }
|
| +}
|
| +
|
| +DEF_TEST(StreamPeek, reporter) {
|
| + // Test a memory stream.
|
| + const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz";
|
| + SkMemoryStream memStream(gAbcs, strlen(gAbcs), false);
|
| + test_fully_peekable_stream(reporter, &memStream);
|
| +
|
| + // Test an arbitrary file stream.
|
| + SkFILEStream fileStream(GetResourcePath("baby_tux.webp").c_str());
|
| + REPORTER_ASSERT(reporter, fileStream.isValid());
|
| + test_fully_peekable_stream(reporter, &fileStream);
|
| +
|
| + // Now test some FrontBufferedStreams
|
| + for (size_t i = 1; i < memStream.getLength(); i++) {
|
| + test_peeking_front_buffered_stream(reporter, memStream, i);
|
| + }
|
| +}
|
|
|