aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/StreamTest.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp
index 01967b70b0..49810aedb4 100644
--- a/tests/StreamTest.cpp
+++ b/tests/StreamTest.cpp
@@ -16,6 +16,9 @@
#include "SkStreamPriv.h"
#include "Test.h"
+#include <functional>
+#include <limits>
+
#ifndef SK_BUILD_FOR_WIN
#include <unistd.h>
#include <fcntl.h>
@@ -469,6 +472,167 @@ DEF_TEST(StreamEmptyStreamMemoryBase, r) {
REPORTER_ASSERT(r, nullptr == asset->getMemoryBase());
}
+DEF_TEST(FILEStreamWithOffset, r) {
+ if (GetResourcePath().isEmpty()) {
+ return;
+ }
+
+ SkString filename = GetResourcePath("images/baby_tux.png");
+ SkFILEStream stream1(filename.c_str());
+ if (!stream1.isValid()) {
+ ERRORF(r, "Could not create SkFILEStream from %s", filename.c_str());
+ return;
+ }
+ REPORTER_ASSERT(r, stream1.hasLength());
+ REPORTER_ASSERT(r, stream1.hasPosition());
+
+ // Seek halfway through the file. The second SkFILEStream will be created
+ // with the same filename and offset and therefore will treat that offset as
+ // the beginning.
+ const size_t size = stream1.getLength();
+ const size_t middle = size / 2;
+ if (!stream1.seek(middle)) {
+ ERRORF(r, "Could not seek SkFILEStream to %lu out of %lu", middle, size);
+ return;
+ }
+ REPORTER_ASSERT(r, stream1.getPosition() == middle);
+
+ FILE* file = sk_fopen(filename.c_str(), kRead_SkFILE_Flag);
+ if (!file) {
+ ERRORF(r, "Could not open %s as a FILE", filename.c_str());
+ return;
+ }
+
+ if (fseek(file, (long) middle, SEEK_SET) != 0) {
+ ERRORF(r, "Could not fseek FILE to %lu out of %lu", middle, size);
+ return;
+ }
+ SkFILEStream stream2(file);
+
+ const size_t remaining = size - middle;
+ SkAutoTMalloc<uint8_t> expected(remaining);
+ REPORTER_ASSERT(r, stream1.read(expected.get(), remaining) == remaining);
+
+ auto test_full_read = [&r, &expected, remaining](SkStream* stream) {
+ SkAutoTMalloc<uint8_t> actual(remaining);
+ REPORTER_ASSERT(r, stream->read(actual.get(), remaining) == remaining);
+ REPORTER_ASSERT(r, !memcmp(expected.get(), actual.get(), remaining));
+
+ REPORTER_ASSERT(r, stream->getPosition() == stream->getLength());
+ REPORTER_ASSERT(r, stream->isAtEnd());
+ };
+
+ auto test_rewind = [&r, &expected, remaining](SkStream* stream) {
+ // Rewind goes back to original offset.
+ REPORTER_ASSERT(r, stream->rewind());
+ REPORTER_ASSERT(r, stream->getPosition() == 0);
+ SkAutoTMalloc<uint8_t> actual(remaining);
+ REPORTER_ASSERT(r, stream->read(actual.get(), remaining) == remaining);
+ REPORTER_ASSERT(r, !memcmp(expected.get(), actual.get(), remaining));
+ };
+
+ auto test_move = [&r, &expected, size, remaining](SkStream* stream) {
+ // Cannot move to before the original offset.
+ REPORTER_ASSERT(r, stream->move(- (long) size));
+ REPORTER_ASSERT(r, stream->getPosition() == 0);
+
+ REPORTER_ASSERT(r, stream->move(std::numeric_limits<long>::min()));
+ REPORTER_ASSERT(r, stream->getPosition() == 0);
+
+ SkAutoTMalloc<uint8_t> actual(remaining);
+ REPORTER_ASSERT(r, stream->read(actual.get(), remaining) == remaining);
+ REPORTER_ASSERT(r, !memcmp(expected.get(), actual.get(), remaining));
+
+ REPORTER_ASSERT(r, stream->isAtEnd());
+ REPORTER_ASSERT(r, stream->getPosition() == remaining);
+
+ // Cannot move beyond the end.
+ REPORTER_ASSERT(r, stream->move(1));
+ REPORTER_ASSERT(r, stream->isAtEnd());
+ REPORTER_ASSERT(r, stream->getPosition() == remaining);
+ };
+
+ auto test_seek = [&r, &expected, middle, remaining](SkStream* stream) {
+ // Seek to an arbitrary position.
+ const size_t arbitrary = middle / 2;
+ REPORTER_ASSERT(r, stream->seek(arbitrary));
+ REPORTER_ASSERT(r, stream->getPosition() == arbitrary);
+ const size_t miniRemaining = remaining - arbitrary;
+ SkAutoTMalloc<uint8_t> actual(miniRemaining);
+ REPORTER_ASSERT(r, stream->read(actual.get(), miniRemaining) == miniRemaining);
+ REPORTER_ASSERT(r, !memcmp(expected.get() + arbitrary, actual.get(), miniRemaining));
+ };
+
+ auto test_seek_beginning = [&r, &expected, remaining](SkStream* stream) {
+ // Seek to the beginning.
+ REPORTER_ASSERT(r, stream->seek(0));
+ REPORTER_ASSERT(r, stream->getPosition() == 0);
+ SkAutoTMalloc<uint8_t> actual(remaining);
+ REPORTER_ASSERT(r, stream->read(actual.get(), remaining) == remaining);
+ REPORTER_ASSERT(r, !memcmp(expected.get(), actual.get(), remaining));
+ };
+
+ auto test_seek_end = [&r, remaining](SkStream* stream) {
+ // Cannot seek past the end.
+ REPORTER_ASSERT(r, stream->isAtEnd());
+
+ REPORTER_ASSERT(r, stream->seek(remaining + 1));
+ REPORTER_ASSERT(r, stream->isAtEnd());
+ REPORTER_ASSERT(r, stream->getPosition() == remaining);
+
+ const size_t middle = remaining / 2;
+ REPORTER_ASSERT(r, stream->seek(middle));
+ REPORTER_ASSERT(r, !stream->isAtEnd());
+ REPORTER_ASSERT(r, stream->getPosition() == middle);
+
+ REPORTER_ASSERT(r, stream->seek(remaining * 2));
+ REPORTER_ASSERT(r, stream->isAtEnd());
+ REPORTER_ASSERT(r, stream->getPosition() == remaining);
+
+ REPORTER_ASSERT(r, stream->seek(std::numeric_limits<long>::max()));
+ REPORTER_ASSERT(r, stream->isAtEnd());
+ REPORTER_ASSERT(r, stream->getPosition() == remaining);
+ };
+
+
+ std::function<void (SkStream* stream, bool recurse)> test_all;
+ test_all = [&](SkStream* stream, bool recurse) {
+ REPORTER_ASSERT(r, stream->getLength() == remaining);
+ REPORTER_ASSERT(r, stream->getPosition() == 0);
+
+ test_full_read(stream);
+ test_rewind(stream);
+ test_move(stream);
+ test_seek(stream);
+ test_seek_beginning(stream);
+ test_seek_end(stream);
+
+ if (recurse) {
+ // Duplicate shares the original offset.
+ auto duplicate = stream->duplicate();
+ if (!duplicate) {
+ ERRORF(r, "Failed to duplicate the stream!");
+ } else {
+ test_all(duplicate.get(), false);
+ }
+
+ // Fork shares the original offset, too.
+ auto fork = stream->fork();
+ if (!fork) {
+ ERRORF(r, "Failed to fork the stream!");
+ } else {
+ REPORTER_ASSERT(r, fork->isAtEnd());
+ REPORTER_ASSERT(r, fork->getLength() == remaining);
+ REPORTER_ASSERT(r, fork->rewind());
+
+ test_all(fork.get(), false);
+ }
+ }
+ };
+
+ test_all(&stream2, true);
+}
+
#include "SkBuffer.h"
DEF_TEST(RBuffer, reporter) {