aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CodecPartialTest.cpp41
-rw-r--r--tests/CodecTest.cpp30
-rw-r--r--tests/FakeStreams.h86
-rw-r--r--tests/StreamBufferTest.cpp135
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);
+}