/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkTo.h"
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkBuffer.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkRandom.h"
#include "src/core/SkStreamPriv.h"
#include "src/utils/SkOSPath.h"
#include "tests/Test.h"
#include "tools/Resources.h"

#include <algorithm>
#include <climits>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <functional>
#include <limits>
#include <memory>
#include <string>

using namespace skia_private;

#ifdef SK_ENABLE_ANDROID_UTILS
#include "client_utils/android/FrontBufferedStream.h"
#endif

#ifndef SK_BUILD_FOR_WIN
#include <fcntl.h>
#endif

static void test_loop_stream(skiatest::Reporter* reporter, SkStream* stream,
                             const void* src, size_t len, int repeat) {
    SkAutoSMalloc<256> storage(len);
    void* tmp = storage.get();

    for (int i = 0; i < repeat; ++i) {
        size_t bytes = stream->read(tmp, len);
        REPORTER_ASSERT(reporter, bytes == len);
        REPORTER_ASSERT(reporter, !memcmp(tmp, src, len));
    }

    // expect EOF
    size_t bytes = stream->read(tmp, 1);
    REPORTER_ASSERT(reporter, 0 == bytes);
    // isAtEnd might not return true until after the first failing read.
    REPORTER_ASSERT(reporter, stream->isAtEnd());
}

static void test_filestreams(skiatest::Reporter* reporter, const char* tmpDir) {
    SkString path = SkOSPath::Join(tmpDir, "wstream_test");

    const char s[] = "abcdefghijklmnopqrstuvwxyz";

    {
        SkFILEWStream writer(path.c_str());
        if (!writer.isValid()) {
            ERRORF(reporter, "Failed to create tmp file %s\n", path.c_str());
            return;
        }

        for (int i = 0; i < 100; ++i) {
            writer.write(s, 26);
        }
    }

    {
        SkFILEStream stream(path.c_str());
        REPORTER_ASSERT(reporter, stream.isValid());
        test_loop_stream(reporter, &stream, s, 26, 100);

        std::unique_ptr<SkStreamAsset> stream2(stream.duplicate());
        test_loop_stream(reporter, stream2.get(), s, 26, 100);
    }

    {
        FILE* file = ::fopen(path.c_str(), "rb");
        SkFILEStream stream(file);
        REPORTER_ASSERT(reporter, stream.isValid());
        test_loop_stream(reporter, &stream, s, 26, 100);

        std::unique_ptr<SkStreamAsset> stream2(stream.duplicate());
        test_loop_stream(reporter, stream2.get(), s, 26, 100);
    }
}

static void TestWStream(skiatest::Reporter* reporter) {
    SkDynamicMemoryWStream  ds;
    const char s[] = "abcdefghijklmnopqrstuvwxyz";
    int i;
    for (i = 0; i < 100; i++) {
        REPORTER_ASSERT(reporter, ds.write(s, 26));
    }
    REPORTER_ASSERT(reporter, ds.bytesWritten() == 100 * 26);

    char* dst = new char[100 * 26 + 1];
    dst[100*26] = '*';
    ds.copyTo(dst);
    REPORTER_ASSERT(reporter, dst[100*26] == '*');
    for (i = 0; i < 100; i++) {
        REPORTER_ASSERT(reporter, memcmp(&dst[i * 26], s, 26) == 0);
    }

    {
        std::unique_ptr<SkStreamAsset> stream(ds.detachAsStream());
        REPORTER_ASSERT(reporter, 100 * 26 == stream->getLength());
        REPORTER_ASSERT(reporter, ds.bytesWritten() == 0);
        test_loop_stream(reporter, stream.get(), s, 26, 100);

        std::unique_ptr<SkStreamAsset> stream2(stream->duplicate());
        test_loop_stream(reporter, stream2.get(), s, 26, 100);

        std::unique_ptr<SkStreamAsset> stream3(stream->fork());
        REPORTER_ASSERT(reporter, stream3->isAtEnd());
        char tmp;
        size_t bytes = stream->read(&tmp, 1);
        REPORTER_ASSERT(reporter, 0 == bytes);
        stream3->rewind();
        test_loop_stream(reporter, stream3.get(), s, 26, 100);
    }

    for (i = 0; i < 100; i++) {
        REPORTER_ASSERT(reporter, ds.write(s, 26));
    }
    REPORTER_ASSERT(reporter, ds.bytesWritten() == 100 * 26);

    {
        // Test that this works after a snapshot.
        std::unique_ptr<SkStreamAsset> stream(ds.detachAsStream());
        REPORTER_ASSERT(reporter, ds.bytesWritten() == 0);
        test_loop_stream(reporter, stream.get(), s, 26, 100);

        std::unique_ptr<SkStreamAsset> stream2(stream->duplicate());
        test_loop_stream(reporter, stream2.get(), s, 26, 100);
    }
    delete[] dst;

    SkString tmpDir = skiatest::GetTmpDir();
    if (!tmpDir.isEmpty()) {
        test_filestreams(reporter, tmpDir.c_str());
    }
}

static void TestPackedUInt(skiatest::Reporter* reporter) {
    // we know that packeduint tries to write 1, 2 or 4 bytes for the length,
    // so we test values around each of those transitions (and a few others)
    const size_t sizes[] = {
        0, 1, 2, 0xFC, 0xFD, 0xFE, 0xFF, 0x100, 0x101, 32767, 32768, 32769,
        0xFFFD, 0xFFFE, 0xFFFF, 0x10000, 0x10001,
        0xFFFFFD, 0xFFFFFE, 0xFFFFFF, 0x1000000, 0x1000001,
        0x7FFFFFFE, 0x7FFFFFFF, 0x80000000, 0x80000001, 0xFFFFFFFE, 0xFFFFFFFF
    };


    size_t i;
    SkDynamicMemoryWStream wstream;

    for (i = 0; i < std::size(sizes); ++i) {
        bool success = wstream.writePackedUInt(sizes[i]);
        REPORTER_ASSERT(reporter, success);
    }

    std::unique_ptr<SkStreamAsset> rstream(wstream.detachAsStream());
    for (i = 0; i < std::size(sizes); ++i) {
        size_t n;
        if (!rstream->readPackedUInt(&n)) {
            ERRORF(reporter, "[%zu] sizes:%zx could not be read\n", i, sizes[i]);
        }
        if (sizes[i] != n) {
            ERRORF(reporter, "[%zu] sizes:%zx != n:%zx\n", i, sizes[i], n);
        }
    }
}

// Test that setting an SkMemoryStream to a nullptr data does not result in a crash when calling
// methods that access fData.
static void TestDereferencingData(skiatest::Reporter* reporter, SkMemoryStream* memStream) {
    REPORTER_ASSERT(reporter, memStream->read(nullptr, 0) == 0);
    // Reading non-zero bytes from an empty stream should cleanly read zero bytes.
    char buf[1];
    REPORTER_ASSERT(reporter, memStream->read(buf, sizeof(buf)) == 0);
    memStream->getMemoryBase();
    (void)memStream->getData();
}

static void TestNullData(skiatest::Reporter* reporter) {
    SkMemoryStream memStream(nullptr);
    TestDereferencingData(reporter, &memStream);

    memStream.setData(nullptr);
    TestDereferencingData(reporter, &memStream);

}

DEF_TEST(Stream, reporter) {
    TestWStream(reporter);
    TestPackedUInt(reporter);
    TestNullData(reporter);
}

#ifndef SK_BUILD_FOR_IOS
/**
 *  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());

    // 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 more than it can read.
    REPORTER_ASSERT(reporter, bytesRead >= bytesPeeked);

    return bytesRead - bytesPeeked;
}

static void test_fully_peekable_stream(skiatest::Reporter* r, SkStream* stream, size_t limit) {
    for (size_t i = 1; !stream->isAtEnd(); i++) {
        REPORTER_ASSERT(r, compare_peek_to_read(r, stream, i) == 0);
    }
}

#ifdef SK_ENABLE_ANDROID_UTILS
static void test_peeking_front_buffered_stream(skiatest::Reporter* r,
                                               const SkStream& original,
                                               size_t bufferSize) {
    std::unique_ptr<SkStream> dupe(original.duplicate());
    REPORTER_ASSERT(r, dupe != nullptr);
    auto bufferedStream = android::skia::FrontBufferedStream::Make(
            std::move(dupe), bufferSize);
    REPORTER_ASSERT(r, bufferedStream != nullptr);

    size_t peeked = 0;
    for (size_t i = 1; !bufferedStream->isAtEnd(); i++) {
        const size_t unpeekableBytes = compare_peek_to_read(r, bufferedStream.get(), 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 = android::skia::FrontBufferedStream::Make(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);

        const size_t bytesPeeked = bufferedStream->peek(peekStorage.get(), bytesToPeek);
        if (0 == bytesPeeked) {
            // Peeking should only fail completely if we have read/skipped beyond the buffer.
            REPORTER_ASSERT(r, start >= 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());
    }
}
#endif

// This test uses file system operations that don't work out of the
// box on iOS. It's likely that we don't need them on iOS. Ignoring for now.
// TODO(stephana): Re-evaluate if we need this in the future.
DEF_TEST(StreamPeek, reporter) {
    // Test a memory stream.
    const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz";
    SkMemoryStream memStream(gAbcs, strlen(gAbcs), false);
    test_fully_peekable_stream(reporter, &memStream, memStream.getLength());

    // Test an arbitrary file stream. file streams do not support peeking.
    auto tmpdir = skiatest::GetTmpDir();
    if (tmpdir.isEmpty()) {
        ERRORF(reporter, "no tmp dir!");
        return;
    }
    auto path = SkOSPath::Join(tmpdir.c_str(), "file");
    {
        SkFILEWStream wStream(path.c_str());
        constexpr char filename[] = "images/baby_tux.webp";
        auto data = GetResourceAsData(filename);
        if (!data || data->size() == 0) {
            ERRORF(reporter, "resource missing: %s\n", filename);
            return;
        }
        if (!wStream.isValid() || !wStream.write(data->data(), data->size())) {
            ERRORF(reporter, "error wrtiting to file %s", path.c_str());
            return;
        }
    }
    SkFILEStream fileStream(path.c_str());
    REPORTER_ASSERT(reporter, fileStream.isValid());
    if (!fileStream.isValid()) {
        return;
    }
    SkAutoMalloc storage(fileStream.getLength());
    for (size_t i = 1; i < fileStream.getLength(); i++) {
        REPORTER_ASSERT(reporter, fileStream.peek(storage.get(), i) == 0);
    }

#ifdef SK_ENABLE_ANDROID_UTILS
    // Now test some FrontBufferedStreams
    for (size_t i = 1; i < memStream.getLength(); i++) {
        test_peeking_front_buffered_stream(reporter, memStream, i);
    }
#endif
}
#endif

// Asserts that asset == expected and is peekable.
static void stream_peek_test(skiatest::Reporter* rep,
                             SkStreamAsset* asset,
                             const SkData* expected) {
    if (asset->getLength() != expected->size()) {
        ERRORF(rep, "Unexpected length.");
        return;
    }
    SkRandom rand;
    uint8_t buffer[4096];
    const uint8_t* expect = expected->bytes();
    for (size_t i = 0; i < asset->getLength(); ++i) {
        uint32_t maxSize =
                SkToU32(std::min(sizeof(buffer), asset->getLength() - i));
        size_t size = rand.nextRangeU(1, maxSize);
        SkASSERT(size >= 1);
        SkASSERT(size <= sizeof(buffer));
        SkASSERT(size + i <= asset->getLength());
        if (asset->peek(buffer, size) < size) {
            ERRORF(rep, "Peek Failed!");
            return;
        }
        if (0 != memcmp(buffer, &expect[i], size)) {
            ERRORF(rep, "Peek returned wrong bytes!");
            return;
        }
        uint8_t value;
        REPORTER_ASSERT(rep, 1 == asset->read(&value, 1));
        if (value != expect[i]) {
            ERRORF(rep, "Read Failed!");
            return;
        }
    }
}

DEF_TEST(StreamPeek_BlockMemoryStream, rep) {
    const static int kSeed = 1234;
    SkRandom valueSource(kSeed);
    SkRandom rand(kSeed << 1);
    uint8_t buffer[4096];
    SkDynamicMemoryWStream dynamicMemoryWStream;
    size_t totalWritten = 0;
    for (int i = 0; i < 32; ++i) {
        // Randomize the length of the blocks.
        size_t size = rand.nextRangeU(1, sizeof(buffer));
        for (size_t j = 0; j < size; ++j) {
            buffer[j] = valueSource.nextU() & 0xFF;
        }
        dynamicMemoryWStream.write(buffer, size);
        totalWritten += size;
        REPORTER_ASSERT(rep, totalWritten == dynamicMemoryWStream.bytesWritten());
    }
    std::unique_ptr<SkStreamAsset> asset(dynamicMemoryWStream.detachAsStream());
    sk_sp<SkData> expected(SkData::MakeUninitialized(asset->getLength()));
    uint8_t* expectedPtr = static_cast<uint8_t*>(expected->writable_data());
    valueSource.setSeed(kSeed);  // reseed.
    // We want the exact same same "random" string of numbers to put
    // in expected. i.e.: don't rely on SkDynamicMemoryStream to work
    // correctly while we are testing SkDynamicMemoryStream.
    for (size_t i = 0; i < asset->getLength(); ++i) {
        expectedPtr[i] = valueSource.nextU() & 0xFF;
    }
    stream_peek_test(rep, asset.get(), expected.get());
}

DEF_TEST(RemainingLengthIsBelow_MemoryStream, rep) {
    SkMemoryStream stream(100);
    REPORTER_ASSERT(rep, !SkStreamPriv::RemainingLengthIsBelow(&stream, 0));
    REPORTER_ASSERT(rep, !SkStreamPriv::RemainingLengthIsBelow(&stream, 90));
    REPORTER_ASSERT(rep, !SkStreamPriv::RemainingLengthIsBelow(&stream, 100));

    REPORTER_ASSERT(rep, SkStreamPriv::RemainingLengthIsBelow(&stream, 101));
    REPORTER_ASSERT(rep, SkStreamPriv::RemainingLengthIsBelow(&stream, ULONG_MAX));

    uint8_t buff[75];
    REPORTER_ASSERT(rep, stream.read(buff, 75) == 75);

    REPORTER_ASSERT(rep, !SkStreamPriv::RemainingLengthIsBelow(&stream, 0));
    REPORTER_ASSERT(rep, !SkStreamPriv::RemainingLengthIsBelow(&stream, 24));
    REPORTER_ASSERT(rep, !SkStreamPriv::RemainingLengthIsBelow(&stream, 25));

    REPORTER_ASSERT(rep, SkStreamPriv::RemainingLengthIsBelow(&stream, 26));
    REPORTER_ASSERT(rep, SkStreamPriv::RemainingLengthIsBelow(&stream, 100));
    REPORTER_ASSERT(rep, SkStreamPriv::RemainingLengthIsBelow(&stream, ULONG_MAX));
}

namespace {
class DumbStream : public SkStream {
public:
    DumbStream(const uint8_t* data, size_t n)
        : fData(data), fCount(n), fIdx(0) {}
    size_t read(void* buffer, size_t size) override {
        size_t copyCount = std::min(fCount - fIdx, size);
        if (copyCount) {
            memcpy(buffer, &fData[fIdx], copyCount);
            fIdx += copyCount;
        }
        return copyCount;
    }
    bool isAtEnd() const override {
        return fCount == fIdx;
    }
 private:
    const uint8_t* fData;
    size_t fCount, fIdx;
};
}  // namespace

static void stream_copy_test(skiatest::Reporter* reporter,
                             const void* srcData,
                             size_t N,
                             SkStream* stream) {
    SkDynamicMemoryWStream tgt;
    if (!SkStreamPriv::Copy(&tgt, stream)) {
        ERRORF(reporter, "SkStreamPriv::Copy failed");
        return;
    }
    sk_sp<SkData> data(tgt.detachAsData());
    if (data->size() != N) {
        ERRORF(reporter, "SkStreamPriv::Copy incorrect size");
        return;
    }
    if (0 != memcmp(data->data(), srcData, N)) {
        ERRORF(reporter, "SkStreamPriv::Copy bad copy");
    }
}

DEF_TEST(DynamicMemoryWStream_detachAsData, r) {
    const char az[] = "abcdefghijklmnopqrstuvwxyz";
    const unsigned N = 40000;
    SkDynamicMemoryWStream dmws;
    for (unsigned i = 0; i < N; ++i) {
        dmws.writeText(az);
    }
    REPORTER_ASSERT(r, dmws.bytesWritten() == N * strlen(az));
    auto data = dmws.detachAsData();
    REPORTER_ASSERT(r, data->size() == N * strlen(az));
    const uint8_t* ptr = data->bytes();
    for (unsigned i = 0; i < N; ++i) {
        if (0 != memcmp(ptr, az, strlen(az))) {
            ERRORF(r, "detachAsData() memcmp failed");
            return;
        }
        ptr += strlen(az);
    }
}

DEF_TEST(DynamicMemoryWStream_detachAsVector, r) {
    const char az[] = "abcdefghijklmnopqrstuvwxyz";
    const unsigned N = 40000;
    SkDynamicMemoryWStream dmws;
    for (unsigned i = 0; i < N; ++i) {
        dmws.writeText(az);
    }
    REPORTER_ASSERT(r, dmws.bytesWritten() == N * strlen(az));
    auto data = dmws.detachAsVector();
    REPORTER_ASSERT(r, data.size() == N * strlen(az));
    for (unsigned i = 0; i < N; ++i) {
        if (0 != memcmp(&data[i * strlen(az)], az, strlen(az))) {
            ERRORF(r, "detachAsVector() memcmp failed");
            return;
        }
    }
}

DEF_TEST(StreamCopy, reporter) {
    SkRandom random(123456);
    static const int N = 10000;
    AutoTMalloc<uint8_t> src((size_t)N);
    for (int j = 0; j < N; ++j) {
        src[j] = random.nextU() & 0xff;
    }
    // SkStreamPriv::Copy had two code paths; this test both.
    DumbStream dumbStream(src.get(), (size_t)N);
    stream_copy_test(reporter, src, N, &dumbStream);
    SkMemoryStream smartStream(src.get(), (size_t)N);
    stream_copy_test(reporter, src, N, &smartStream);
}

DEF_TEST(StreamEmptyStreamMemoryBase, r) {
    SkDynamicMemoryWStream tmp;
    std::unique_ptr<SkStreamAsset> asset(tmp.detachAsStream());
    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 %zu out of %zu", 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 %zu out of %zu", middle, size);
        return;
    }
    SkFILEStream stream2(file);

    const size_t remaining = size - middle;
    AutoTMalloc<uint8_t> expected(remaining);
    REPORTER_ASSERT(r, stream1.read(expected.get(), remaining) == remaining);

    auto test_full_read = [&r, &expected, remaining](SkStream* stream) {
        AutoTMalloc<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);
        AutoTMalloc<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);

        AutoTMalloc<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;
        AutoTMalloc<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);
        AutoTMalloc<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);
}

DEF_TEST(RBuffer, reporter) {
    int32_t value = 0;
    SkRBuffer buffer(&value, 4);
    REPORTER_ASSERT(reporter, buffer.isValid());

    int32_t tmp;
    REPORTER_ASSERT(reporter, buffer.read(&tmp, 4));
    REPORTER_ASSERT(reporter, buffer.isValid());

    REPORTER_ASSERT(reporter, !buffer.read(&tmp, 4));
    REPORTER_ASSERT(reporter, !buffer.isValid());
}
