diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/CodecPartialTest.cpp | 41 | ||||
-rw-r--r-- | tests/CodecTest.cpp | 30 | ||||
-rw-r--r-- | tests/FakeStreams.h | 86 | ||||
-rw-r--r-- | tests/StreamBufferTest.cpp | 135 |
4 files changed, 223 insertions, 69 deletions
diff --git a/tests/CodecPartialTest.cpp b/tests/CodecPartialTest.cpp index 93e5d63f22..62f9d8570e 100644 --- a/tests/CodecPartialTest.cpp +++ b/tests/CodecPartialTest.cpp @@ -12,6 +12,7 @@ #include "SkRWBuffer.h" #include "SkString.h" +#include "FakeStreams.h" #include "Resources.h" #include "Test.h" @@ -50,46 +51,6 @@ static void compare_bitmaps(skiatest::Reporter* r, const SkBitmap& bm1, const Sk } } -/* - * Represents a stream without all of its data. - */ -class HaltingStream : public SkStream { -public: - HaltingStream(sk_sp<SkData> data, size_t initialLimit) - : fTotalSize(data->size()) - , fLimit(initialLimit) - , fStream(std::move(data)) - {} - - void addNewData(size_t extra) { - fLimit = SkTMin(fTotalSize, fLimit + extra); - } - - size_t read(void* buffer, size_t size) override { - if (fStream.getPosition() + size > fLimit) { - size = fLimit - fStream.getPosition(); - } - - return fStream.read(buffer, size); - } - - bool isAtEnd() const override { - return fStream.isAtEnd(); - } - - bool hasPosition() const override { return true; } - size_t getPosition() const override { return fStream.getPosition(); } - bool rewind() override { return fStream.rewind(); } - bool move(long offset) override { return fStream.move(offset); } - - bool isAllDataReceived() const { return fLimit == fTotalSize; } - -private: - const size_t fTotalSize; - size_t fLimit; - SkMemoryStream fStream; -}; - static void test_partial(skiatest::Reporter* r, const char* name, size_t minBytes = 0) { sk_sp<SkData> file = make_from_resource(name); if (!file) { diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index 05859a95b3..19494b280d 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -5,6 +5,7 @@ * found in the LICENSE file. */ +#include "FakeStreams.h" #include "Resources.h" #include "SkAndroidCodec.h" #include "SkBitmap.h" @@ -891,35 +892,6 @@ private: const size_t fLimit; }; -// Stream that is not an asset stream (!hasPosition() or !hasLength()) -class NotAssetMemStream : public SkStream { -public: - NotAssetMemStream(sk_sp<SkData> data) : fStream(std::move(data)) {} - - bool hasPosition() const override { - return false; - } - - bool hasLength() const override { - return false; - } - - size_t peek(void* buf, size_t bytes) const override { - return fStream.peek(buf, bytes); - } - size_t read(void* buf, size_t bytes) override { - return fStream.read(buf, bytes); - } - bool rewind() override { - return fStream.rewind(); - } - bool isAtEnd() const override { - return fStream.isAtEnd(); - } -private: - SkMemoryStream fStream; -}; - // Disable RAW tests for Win32. #if defined(SK_CODEC_DECODES_RAW) && (!defined(_WIN32)) // Test that the RawCodec works also for not asset stream. This will test the code path using diff --git a/tests/FakeStreams.h b/tests/FakeStreams.h new file mode 100644 index 0000000000..6b510b8970 --- /dev/null +++ b/tests/FakeStreams.h @@ -0,0 +1,86 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkData.h" +#include "SkStream.h" + +#ifndef FakeStreams_DEFINED +#define FakeStreams_DEFINED + +// Stream that is not an asset stream (!hasPosition() or !hasLength()) +class NotAssetMemStream : public SkStream { +public: + NotAssetMemStream(sk_sp<SkData> data) : fStream(std::move(data)) {} + + bool hasPosition() const override { + return false; + } + + bool hasLength() const override { + return false; + } + + size_t peek(void* buf, size_t bytes) const override { + return fStream.peek(buf, bytes); + } + size_t read(void* buf, size_t bytes) override { + return fStream.read(buf, bytes); + } + bool rewind() override { + return fStream.rewind(); + } + bool isAtEnd() const override { + return fStream.isAtEnd(); + } +private: + SkMemoryStream fStream; +}; + +/* + * Represents a stream without all of its data. + */ +class HaltingStream : public SkStream { +public: + HaltingStream(sk_sp<SkData> data, size_t initialLimit) + : fTotalSize(data->size()) + , fLimit(initialLimit) + , fStream(std::move(data)) + {} + + void addNewData(size_t extra) { + fLimit = SkTMin(fTotalSize, fLimit + extra); + } + + size_t read(void* buffer, size_t size) override { + if (fStream.getPosition() + size > fLimit) { + size = fLimit - fStream.getPosition(); + } + + return fStream.read(buffer, size); + } + + bool isAtEnd() const override { + return fStream.isAtEnd(); + } + + bool hasLength() const override { return true; } + size_t getLength() const override { return fLimit; } + + bool hasPosition() const override { return true; } + size_t getPosition() const override { return fStream.getPosition(); } + bool rewind() override { return fStream.rewind(); } + bool move(long offset) override { return fStream.move(offset); } + bool seek(size_t position) override { return fStream.seek(position); } + + bool isAllDataReceived() const { return fLimit == fTotalSize; } + +private: + const size_t fTotalSize; + size_t fLimit; + SkMemoryStream fStream; +}; +#endif // FakeStreams_DEFINED diff --git a/tests/StreamBufferTest.cpp b/tests/StreamBufferTest.cpp new file mode 100644 index 0000000000..96bca35c92 --- /dev/null +++ b/tests/StreamBufferTest.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkData.h" +#include "SkOSPath.h" +#include "SkStream.h" +#include "SkStreamBuffer.h" + +#include "FakeStreams.h" +#include "Test.h" + +static const char* gText = "Four score and seven years ago"; + +static void test_get_data_at_position(skiatest::Reporter* r, SkStreamBuffer* buffer, size_t position, + size_t length) { + sk_sp<SkData> data = buffer->getDataAtPosition(position, length); + REPORTER_ASSERT(r, data); + if (data) { + REPORTER_ASSERT(r, !memcmp(data->data(), gText + position, length)); + } +} + +// Test buffering from the beginning, by different amounts. +static void test_buffer_from_beginning(skiatest::Reporter* r, SkStream* stream, size_t length) { + SkStreamBuffer buffer(stream); + + // Buffer an arbitrary amount: + size_t buffered = length / 2; + REPORTER_ASSERT(r, buffer.buffer(buffered)); + REPORTER_ASSERT(r, !memcmp(buffer.get(), gText, buffered)); + + // Buffering less is free: + REPORTER_ASSERT(r, buffer.buffer(buffered / 2)); + + // Buffer more should succeed: + REPORTER_ASSERT(r, buffer.buffer(length)); + REPORTER_ASSERT(r, !memcmp(buffer.get(), gText, length)); +} + +// Test flushing the stream as we read. +static void test_flushing(skiatest::Reporter* r, SkStream* stream, size_t length, + bool getDataAtPosition) { + SkStreamBuffer buffer(stream); + const size_t step = 5; + for (size_t position = 0; position + step <= length; position += step) { + REPORTER_ASSERT(r, buffer.buffer(step)); + REPORTER_ASSERT(r, buffer.markPosition() == position); + + if (!getDataAtPosition) { + REPORTER_ASSERT(r, !memcmp(buffer.get(), gText + position, step)); + } + buffer.flush(); + } + + REPORTER_ASSERT(r, !buffer.buffer(step)); + + if (getDataAtPosition) { + for (size_t position = 0; position + step <= length; position += step) { + test_get_data_at_position(r, &buffer, position, step); + } + } +} + +DEF_TEST(StreamBuffer, r) { + const size_t size = strlen(gText); + sk_sp<SkData> data(SkData::MakeWithoutCopy(gText, size)); + + SkString tmpDir = skiatest::GetTmpDir(); + const char* subdir = "streamBuffer.txt"; + SkString path; + + if (!tmpDir.isEmpty()) { + path = SkOSPath::Join(tmpDir.c_str(), subdir); + SkFILEWStream writer(path.c_str()); + writer.write(gText, size); + } + + struct { + std::function<SkStream*()> createStream; + bool skipIfNoTmpDir; + } factories[] = { + { [&data]() { return new SkMemoryStream(data); }, false }, + { [&data]() { return new NotAssetMemStream(data); }, false }, + { [&path]() { return new SkFILEStream(path.c_str()); }, true }, + }; + + for (auto f : factories) { + if (tmpDir.isEmpty() && f.skipIfNoTmpDir) { + continue; + } + test_buffer_from_beginning(r, f.createStream(), size); + test_flushing(r, f.createStream(), size, false); + test_flushing(r, f.createStream(), size, true); + } + + // Stream that will receive more data. Will be owned by the SkStreamBuffer. + HaltingStream* stream = new HaltingStream(data, 6); + SkStreamBuffer buffer(stream); + + // Can only buffer less than what's available (6). + REPORTER_ASSERT(r, !buffer.buffer(7)); + REPORTER_ASSERT(r, buffer.buffer(5)); + REPORTER_ASSERT(r, !memcmp(buffer.get(), gText, 5)); + + // Add some more data. We can buffer and read all of it. + stream->addNewData(8); + REPORTER_ASSERT(r, buffer.buffer(14)); + REPORTER_ASSERT(r, !memcmp(buffer.get(), gText, 14)); + + // Flush the buffer, which moves the position. + buffer.flush(); + + // Add some data, and try to read more. Can only read what is + // available. + stream->addNewData(9); + REPORTER_ASSERT(r, !buffer.buffer(13)); + stream->addNewData(4); + REPORTER_ASSERT(r, buffer.buffer(13)); + + // Do not call get on this data. We'll come back to this data after adding + // more. + buffer.flush(); + const size_t remaining = size - 27; + REPORTER_ASSERT(r, remaining > 0); + stream->addNewData(remaining); + REPORTER_ASSERT(r, buffer.buffer(remaining)); + REPORTER_ASSERT(r, !memcmp(buffer.get(), gText + 27, remaining)); + + // Now go back to the data we skipped. + test_get_data_at_position(r, &buffer, 14, 13); +} |