/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkStream.h"

#include "include/core/SkData.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/SkFixed.h"
#include "include/private/SkTFitsIn.h"
#include "include/private/SkTPin.h"
#include "include/private/SkTo.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkSafeMath.h"
#include "src/core/SkStreamPriv.h"

#include <limits>

///////////////////////////////////////////////////////////////////////////////

bool SkStream::readS8(int8_t* i) {
    return this->read(i, sizeof(*i)) == sizeof(*i);
}

bool SkStream::readS16(int16_t* i) {
    return this->read(i, sizeof(*i)) == sizeof(*i);
}

bool SkStream::readS32(int32_t* i) {
    return this->read(i, sizeof(*i)) == sizeof(*i);
}

bool SkStream::readScalar(SkScalar* i) {
    return this->read(i, sizeof(*i)) == sizeof(*i);
}

#define SK_MAX_BYTE_FOR_U8          0xFD
#define SK_BYTE_SENTINEL_FOR_U16    0xFE
#define SK_BYTE_SENTINEL_FOR_U32    0xFF

bool SkStream::readPackedUInt(size_t* i) {
    uint8_t byte;
    if (!this->read(&byte, 1)) {
        return false;
    }
    if (SK_BYTE_SENTINEL_FOR_U16 == byte) {
        uint16_t i16;
        if (!this->readU16(&i16)) { return false; }
        *i = i16;
    } else if (SK_BYTE_SENTINEL_FOR_U32 == byte) {
        uint32_t i32;
        if (!this->readU32(&i32)) { return false; }
        *i = i32;
    } else {
        *i = byte;
    }
    return true;
}

//////////////////////////////////////////////////////////////////////////////////////

SkWStream::~SkWStream()
{
}

void SkWStream::flush()
{
}

bool SkWStream::writeDecAsText(int32_t dec)
{
    char buffer[kSkStrAppendS32_MaxSize];
    char* stop = SkStrAppendS32(buffer, dec);
    return this->write(buffer, stop - buffer);
}

bool SkWStream::writeBigDecAsText(int64_t dec, int minDigits)
{
    char buffer[kSkStrAppendU64_MaxSize];
    char* stop = SkStrAppendU64(buffer, dec, minDigits);
    return this->write(buffer, stop - buffer);
}

bool SkWStream::writeHexAsText(uint32_t hex, int digits)
{
    SkString    tmp;
    tmp.appendHex(hex, digits);
    return this->write(tmp.c_str(), tmp.size());
}

bool SkWStream::writeScalarAsText(SkScalar value)
{
    char buffer[kSkStrAppendScalar_MaxSize];
    char* stop = SkStrAppendScalar(buffer, value);
    return this->write(buffer, stop - buffer);
}

bool SkWStream::writeScalar(SkScalar value) {
    return this->write(&value, sizeof(value));
}

int SkWStream::SizeOfPackedUInt(size_t value) {
    if (value <= SK_MAX_BYTE_FOR_U8) {
        return 1;
    } else if (value <= 0xFFFF) {
        return 3;
    }
    return 5;
}

bool SkWStream::writePackedUInt(size_t value) {
    uint8_t data[5];
    size_t len = 1;
    if (value <= SK_MAX_BYTE_FOR_U8) {
        data[0] = value;
        len = 1;
    } else if (value <= 0xFFFF) {
        uint16_t value16 = value;
        data[0] = SK_BYTE_SENTINEL_FOR_U16;
        memcpy(&data[1], &value16, 2);
        len = 3;
    } else {
        uint32_t value32 = SkToU32(value);
        data[0] = SK_BYTE_SENTINEL_FOR_U32;
        memcpy(&data[1], &value32, 4);
        len = 5;
    }
    return this->write(data, len);
}

bool SkWStream::writeStream(SkStream* stream, size_t length) {
    char scratch[1024];
    const size_t MAX = sizeof(scratch);

    while (length != 0) {
        size_t n = length;
        if (n > MAX) {
            n = MAX;
        }
        stream->read(scratch, n);
        if (!this->write(scratch, n)) {
            return false;
        }
        length -= n;
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////

SkFILEStream::SkFILEStream(std::shared_ptr<FILE> file, size_t end, size_t start, size_t current)
    : fFILE(std::move(file))
    , fEnd(end)
    , fStart(std::min(start, fEnd))
    , fCurrent(SkTPin(current, fStart, fEnd))
{
    SkASSERT(fStart == start);
    SkASSERT(fCurrent == current);
}

SkFILEStream::SkFILEStream(std::shared_ptr<FILE> file, size_t end, size_t start)
    : SkFILEStream(std::move(file), end, start, start)
{ }

SkFILEStream::SkFILEStream(FILE* file, size_t size, size_t start)
    : SkFILEStream(std::shared_ptr<FILE>(file, sk_fclose), SkSafeMath::Add(start, size), start)
{ }

SkFILEStream::SkFILEStream(FILE* file, size_t size)
    : SkFILEStream(file, size, file ? sk_ftell(file) : 0)
{ }

SkFILEStream::SkFILEStream(FILE* file)
    : SkFILEStream(std::shared_ptr<FILE>(file, sk_fclose),
                   file ? sk_fgetsize(file) : 0,
                   file ? sk_ftell(file) : 0)
{ }

SkFILEStream::SkFILEStream(const char path[])
    : SkFILEStream(path ? sk_fopen(path, kRead_SkFILE_Flag) : nullptr)
{ }

SkFILEStream::~SkFILEStream() {
    this->close();
}

void SkFILEStream::close() {
    fFILE.reset();
    fEnd = 0;
    fStart = 0;
    fCurrent = 0;
}

size_t SkFILEStream::read(void* buffer, size_t size) {
    if (size > fEnd - fCurrent) {
        size = fEnd - fCurrent;
    }
    size_t bytesRead = size;
    if (buffer) {
        bytesRead = sk_qread(fFILE.get(), buffer, size, fCurrent);
    }
    if (bytesRead == SIZE_MAX) {
        return 0;
    }
    fCurrent += bytesRead;
    return bytesRead;
}

bool SkFILEStream::isAtEnd() const {
    if (fCurrent == fEnd) {
        return true;
    }
    return fCurrent >= sk_fgetsize(fFILE.get());
}

bool SkFILEStream::rewind() {
    fCurrent = fStart;
    return true;
}

SkStreamAsset* SkFILEStream::onDuplicate() const {
    return new SkFILEStream(fFILE, fEnd, fStart, fStart);
}

size_t SkFILEStream::getPosition() const {
    SkASSERT(fCurrent >= fStart);
    return fCurrent - fStart;
}

bool SkFILEStream::seek(size_t position) {
    fCurrent = std::min(SkSafeMath::Add(position, fStart), fEnd);
    return true;
}

bool SkFILEStream::move(long offset) {
    if (offset < 0) {
        if (offset == std::numeric_limits<long>::min() ||
            !SkTFitsIn<size_t>(-offset) ||
            (size_t) (-offset) >= this->getPosition())
        {
            fCurrent = fStart;
        } else {
            fCurrent += offset;
        }
    } else if (!SkTFitsIn<size_t>(offset)) {
        fCurrent = fEnd;
    } else {
        fCurrent = std::min(SkSafeMath::Add(fCurrent, (size_t) offset), fEnd);
    }

    SkASSERT(fCurrent >= fStart && fCurrent <= fEnd);
    return true;
}

SkStreamAsset* SkFILEStream::onFork() const {
    return new SkFILEStream(fFILE, fEnd, fStart, fCurrent);
}

size_t SkFILEStream::getLength() const {
    return fEnd - fStart;
}

///////////////////////////////////////////////////////////////////////////////

static sk_sp<SkData> newFromParams(const void* src, size_t size, bool copyData) {
    if (copyData) {
        return SkData::MakeWithCopy(src, size);
    } else {
        return SkData::MakeWithoutCopy(src, size);
    }
}

SkMemoryStream::SkMemoryStream() {
    fData = SkData::MakeEmpty();
    fOffset = 0;
}

SkMemoryStream::SkMemoryStream(size_t size) {
    fData = SkData::MakeUninitialized(size);
    fOffset = 0;
}

SkMemoryStream::SkMemoryStream(const void* src, size_t size, bool copyData) {
    fData = newFromParams(src, size, copyData);
    fOffset = 0;
}

SkMemoryStream::SkMemoryStream(sk_sp<SkData> data) : fData(std::move(data)) {
    if (nullptr == fData) {
        fData = SkData::MakeEmpty();
    }
    fOffset = 0;
}

std::unique_ptr<SkMemoryStream> SkMemoryStream::MakeCopy(const void* data, size_t length) {
    return std::make_unique<SkMemoryStream>(data, length, true);
}

std::unique_ptr<SkMemoryStream> SkMemoryStream::MakeDirect(const void* data, size_t length) {
    return std::make_unique<SkMemoryStream>(data, length, false);
}

std::unique_ptr<SkMemoryStream> SkMemoryStream::Make(sk_sp<SkData> data) {
    return std::make_unique<SkMemoryStream>(std::move(data));
}

void SkMemoryStream::setMemoryOwned(const void* src, size_t size) {
    fData = SkData::MakeFromMalloc(src, size);
    fOffset = 0;
}

void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData) {
    fData = newFromParams(src, size, copyData);
    fOffset = 0;
}

void SkMemoryStream::setData(sk_sp<SkData> data) {
    if (nullptr == data) {
        fData = SkData::MakeEmpty();
    } else {
        fData = data;
    }
    fOffset = 0;
}

void SkMemoryStream::skipToAlign4() {
    // cast to remove unary-minus warning
    fOffset += -(int)fOffset & 0x03;
}

size_t SkMemoryStream::read(void* buffer, size_t size) {
    size_t dataSize = fData->size();

    if (size > dataSize - fOffset) {
        size = dataSize - fOffset;
    }
    if (buffer) {
        memcpy(buffer, fData->bytes() + fOffset, size);
    }
    fOffset += size;
    return size;
}

size_t SkMemoryStream::peek(void* buffer, size_t size) const {
    SkASSERT(buffer != nullptr);

    const size_t currentOffset = fOffset;
    SkMemoryStream* nonConstThis = const_cast<SkMemoryStream*>(this);
    const size_t bytesRead = nonConstThis->read(buffer, size);
    nonConstThis->fOffset = currentOffset;
    return bytesRead;
}

bool SkMemoryStream::isAtEnd() const {
    return fOffset == fData->size();
}

bool SkMemoryStream::rewind() {
    fOffset = 0;
    return true;
}

SkMemoryStream* SkMemoryStream::onDuplicate() const {
    return new SkMemoryStream(fData);
}

size_t SkMemoryStream::getPosition() const {
    return fOffset;
}

bool SkMemoryStream::seek(size_t position) {
    fOffset = position > fData->size()
            ? fData->size()
            : position;
    return true;
}

bool SkMemoryStream::move(long offset) {
    return this->seek(fOffset + offset);
}

SkMemoryStream* SkMemoryStream::onFork() const {
    std::unique_ptr<SkMemoryStream> that(this->duplicate());
    that->seek(fOffset);
    return that.release();
}

size_t SkMemoryStream::getLength() const {
    return fData->size();
}

const void* SkMemoryStream::getMemoryBase() {
    return fData->data();
}

const void* SkMemoryStream::getAtPos() {
    return fData->bytes() + fOffset;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////

SkFILEWStream::SkFILEWStream(const char path[])
{
    fFILE = sk_fopen(path, kWrite_SkFILE_Flag);
}

SkFILEWStream::~SkFILEWStream()
{
    if (fFILE) {
        sk_fclose(fFILE);
    }
}

size_t SkFILEWStream::bytesWritten() const {
    return sk_ftell(fFILE);
}

bool SkFILEWStream::write(const void* buffer, size_t size)
{
    if (fFILE == nullptr) {
        return false;
    }

    if (sk_fwrite(buffer, size, fFILE) != size)
    {
        SkDEBUGCODE(SkDebugf("SkFILEWStream failed writing %d bytes\n", size);)
        sk_fclose(fFILE);
        fFILE = nullptr;
        return false;
    }
    return true;
}

void SkFILEWStream::flush()
{
    if (fFILE) {
        sk_fflush(fFILE);
    }
}

void SkFILEWStream::fsync()
{
    flush();
    if (fFILE) {
        sk_fsync(fFILE);
    }
}

////////////////////////////////////////////////////////////////////////

static inline void sk_memcpy_4bytes(void* dst, const void* src, size_t size) {
    if (size == 4) {
        memcpy(dst, src, 4);
    } else {
        memcpy(dst, src, size);
    }
}

#define SkDynamicMemoryWStream_MinBlockSize   4096

struct SkDynamicMemoryWStream::Block {
    Block*  fNext;
    char*   fCurr;
    char*   fStop;

    const char* start() const { return (const char*)(this + 1); }
    char*   start() { return (char*)(this + 1); }
    size_t  avail() const { return fStop - fCurr; }
    size_t  written() const { return fCurr - this->start(); }

    void init(size_t size) {
        fNext = nullptr;
        fCurr = this->start();
        fStop = this->start() + size;
    }

    const void* append(const void* data, size_t size) {
        SkASSERT((size_t)(fStop - fCurr) >= size);
        sk_memcpy_4bytes(fCurr, data, size);
        fCurr += size;
        return (const void*)((const char*)data + size);
    }
};

SkDynamicMemoryWStream::SkDynamicMemoryWStream(SkDynamicMemoryWStream&& other)
    : fHead(other.fHead)
    , fTail(other.fTail)
    , fBytesWrittenBeforeTail(other.fBytesWrittenBeforeTail)
{
    other.fHead = nullptr;
    other.fTail = nullptr;
    other.fBytesWrittenBeforeTail = 0;
}

SkDynamicMemoryWStream& SkDynamicMemoryWStream::operator=(SkDynamicMemoryWStream&& other) {
    if (this != &other) {
        this->~SkDynamicMemoryWStream();
        new (this) SkDynamicMemoryWStream(std::move(other));
    }
    return *this;
}

SkDynamicMemoryWStream::~SkDynamicMemoryWStream() {
    this->reset();
}

void SkDynamicMemoryWStream::reset() {
    Block* block = fHead;
    while (block != nullptr) {
        Block* next = block->fNext;
        sk_free(block);
        block = next;
    }
    fHead = fTail = nullptr;
    fBytesWrittenBeforeTail = 0;
}

size_t SkDynamicMemoryWStream::bytesWritten() const {
    this->validate();

    if (fTail) {
        return fBytesWrittenBeforeTail + fTail->written();
    }
    return 0;
}

bool SkDynamicMemoryWStream::write(const void* buffer, size_t count) {
    if (count > 0) {
        SkASSERT(buffer);
        size_t size;

        if (fTail) {
            if (fTail->avail() > 0) {
                size = std::min(fTail->avail(), count);
                buffer = fTail->append(buffer, size);
                SkASSERT(count >= size);
                count -= size;
                if (count == 0) {
                    return true;
                }
            }
            // If we get here, we've just exhausted fTail, so update our tracker
            fBytesWrittenBeforeTail += fTail->written();
        }

        size = std::max<size_t>(count, SkDynamicMemoryWStream_MinBlockSize - sizeof(Block));
        size = SkAlign4(size);  // ensure we're always a multiple of 4 (see padToAlign4())

        Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size);
        block->init(size);
        block->append(buffer, count);

        if (fTail != nullptr) {
            fTail->fNext = block;
        } else {
            fHead = fTail = block;
        }
        fTail = block;
        this->validate();
    }
    return true;
}

bool SkDynamicMemoryWStream::writeToAndReset(SkDynamicMemoryWStream* dst) {
    SkASSERT(dst);
    SkASSERT(dst != this);
    if (0 == this->bytesWritten()) {
        return true;
    }
    if (0 == dst->bytesWritten()) {
        *dst = std::move(*this);
        return true;
    }
    dst->fTail->fNext = fHead;
    dst->fBytesWrittenBeforeTail += fBytesWrittenBeforeTail + dst->fTail->written();
    dst->fTail = fTail;
    fHead = fTail = nullptr;
    fBytesWrittenBeforeTail = 0;
    return true;
}

void SkDynamicMemoryWStream::prependToAndReset(SkDynamicMemoryWStream* dst) {
    SkASSERT(dst);
    SkASSERT(dst != this);
    if (0 == this->bytesWritten()) {
        return;
    }
    if (0 == dst->bytesWritten()) {
        *dst = std::move(*this);
        return;
    }
    fTail->fNext = dst->fHead;
    dst->fHead = fHead;
    dst->fBytesWrittenBeforeTail += fBytesWrittenBeforeTail + fTail->written();
    fHead = fTail = nullptr;
    fBytesWrittenBeforeTail = 0;
    return;
}


bool SkDynamicMemoryWStream::read(void* buffer, size_t offset, size_t count) {
    if (offset + count > this->bytesWritten()) {
        return false; // test does not partially modify
    }
    Block* block = fHead;
    while (block != nullptr) {
        size_t size = block->written();
        if (offset < size) {
            size_t part = offset + count > size ? size - offset : count;
            memcpy(buffer, block->start() + offset, part);
            if (count <= part) {
                return true;
            }
            count -= part;
            buffer = (void*) ((char* ) buffer + part);
        }
        offset = offset > size ? offset - size : 0;
        block = block->fNext;
    }
    return false;
}

void SkDynamicMemoryWStream::copyTo(void* dst) const {
    SkASSERT(dst);
    Block* block = fHead;
    while (block != nullptr) {
        size_t size = block->written();
        memcpy(dst, block->start(), size);
        dst = (void*)((char*)dst + size);
        block = block->fNext;
    }
}

bool SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
    SkASSERT(dst);
    for (Block* block = fHead; block != nullptr; block = block->fNext) {
        if (!dst->write(block->start(), block->written())) {
            return false;
        }
    }
    return true;
}

void SkDynamicMemoryWStream::padToAlign4() {
    // The contract is to write zeros until the entire stream has written a multiple of 4 bytes.
    // Our Blocks are guaranteed always be (a) full (except the tail) and (b) a multiple of 4
    // so it is sufficient to just examine the tail (if present).

    if (fTail) {
        // cast to remove unary-minus warning
        int padBytes = -(int)fTail->written() & 0x03;
        if (padBytes) {
            int zero = 0;
            fTail->append(&zero, padBytes);
        }
    }
}


void SkDynamicMemoryWStream::copyToAndReset(void* ptr) {
    if (!ptr) {
        this->reset();
        return;
    }
    // By looping through the source and freeing as we copy, we
    // can reduce real memory use with large streams.
    char* dst = reinterpret_cast<char*>(ptr);
    Block* block = fHead;
    while (block != nullptr) {
        size_t len = block->written();
        memcpy(dst, block->start(), len);
        dst += len;
        Block* next = block->fNext;
        sk_free(block);
        block = next;
    }
    fHead = fTail = nullptr;
    fBytesWrittenBeforeTail = 0;
}

bool SkDynamicMemoryWStream::writeToAndReset(SkWStream* dst) {
    SkASSERT(dst);
    // By looping through the source and freeing as we copy, we
    // can reduce real memory use with large streams.
    bool dstStreamGood = true;
    for (Block* block = fHead; block != nullptr; ) {
        if (dstStreamGood && !dst->write(block->start(), block->written())) {
            dstStreamGood = false;
        }
        Block* next = block->fNext;
        sk_free(block);
        block = next;
    }
    fHead = fTail = nullptr;
    fBytesWrittenBeforeTail = 0;
    return dstStreamGood;
}

sk_sp<SkData> SkDynamicMemoryWStream::detachAsData() {
    const size_t size = this->bytesWritten();
    if (0 == size) {
        return SkData::MakeEmpty();
    }
    sk_sp<SkData> data = SkData::MakeUninitialized(size);
    this->copyToAndReset(data->writable_data());
    return data;
}

#ifdef SK_DEBUG
void SkDynamicMemoryWStream::validate() const {
    if (!fHead) {
        SkASSERT(!fTail);
        SkASSERT(fBytesWrittenBeforeTail == 0);
        return;
    }
    SkASSERT(fTail);

    size_t bytes = 0;
    const Block* block = fHead;
    while (block) {
        if (block->fNext) {
            bytes += block->written();
        }
        block = block->fNext;
    }
    SkASSERT(bytes == fBytesWrittenBeforeTail);
}
#endif

////////////////////////////////////////////////////////////////////////////////////////////////

class SkBlockMemoryRefCnt : public SkRefCnt {
public:
    explicit SkBlockMemoryRefCnt(SkDynamicMemoryWStream::Block* head) : fHead(head) { }

    ~SkBlockMemoryRefCnt() override {
        SkDynamicMemoryWStream::Block* block = fHead;
        while (block != nullptr) {
            SkDynamicMemoryWStream::Block* next = block->fNext;
            sk_free(block);
            block = next;
        }
    }

    SkDynamicMemoryWStream::Block* const fHead;
};

class SkBlockMemoryStream : public SkStreamAsset {
public:
    SkBlockMemoryStream(sk_sp<SkBlockMemoryRefCnt> headRef, size_t size)
        : fBlockMemory(std::move(headRef)), fCurrent(fBlockMemory->fHead)
        , fSize(size) , fOffset(0), fCurrentOffset(0) { }

    size_t read(void* buffer, size_t rawCount) override {
        size_t count = rawCount;
        if (fOffset + count > fSize) {
            count = fSize - fOffset;
        }
        size_t bytesLeftToRead = count;
        while (fCurrent != nullptr) {
            size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset;
            size_t bytesFromCurrent = std::min(bytesLeftToRead, bytesLeftInCurrent);
            if (buffer) {
                memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent);
                buffer = SkTAddOffset<void>(buffer, bytesFromCurrent);
            }
            if (bytesLeftToRead <= bytesFromCurrent) {
                fCurrentOffset += bytesFromCurrent;
                fOffset += count;
                return count;
            }
            bytesLeftToRead -= bytesFromCurrent;
            fCurrent = fCurrent->fNext;
            fCurrentOffset = 0;
        }
        SkASSERT(false);
        return 0;
    }

    bool isAtEnd() const override {
        return fOffset == fSize;
    }

    size_t peek(void* buff, size_t bytesToPeek) const override {
        SkASSERT(buff != nullptr);

        bytesToPeek = std::min(bytesToPeek, fSize - fOffset);

        size_t bytesLeftToPeek = bytesToPeek;
        char* buffer = static_cast<char*>(buff);
        const SkDynamicMemoryWStream::Block* current = fCurrent;
        size_t currentOffset = fCurrentOffset;
        while (bytesLeftToPeek) {
            SkASSERT(current);
            size_t bytesFromCurrent = std::min(current->written() - currentOffset, bytesLeftToPeek);
            memcpy(buffer, current->start() + currentOffset, bytesFromCurrent);
            bytesLeftToPeek -= bytesFromCurrent;
            buffer += bytesFromCurrent;
            current = current->fNext;
            currentOffset = 0;
        }
        return bytesToPeek;
    }

    bool rewind() override {
        fCurrent = fBlockMemory->fHead;
        fOffset = 0;
        fCurrentOffset = 0;
        return true;
    }

    SkBlockMemoryStream* onDuplicate() const override {
        return new SkBlockMemoryStream(fBlockMemory, fSize);
    }

    size_t getPosition() const override {
        return fOffset;
    }

    bool seek(size_t position) override {
        // If possible, skip forward.
        if (position >= fOffset) {
            size_t skipAmount = position - fOffset;
            return this->skip(skipAmount) == skipAmount;
        }
        // If possible, move backward within the current block.
        size_t moveBackAmount = fOffset - position;
        if (moveBackAmount <= fCurrentOffset) {
            fCurrentOffset -= moveBackAmount;
            fOffset -= moveBackAmount;
            return true;
        }
        // Otherwise rewind and move forward.
        return this->rewind() && this->skip(position) == position;
    }

    bool move(long offset) override {
        return seek(fOffset + offset);
    }

    SkBlockMemoryStream* onFork() const override {
        SkBlockMemoryStream* that = this->onDuplicate();
        that->fCurrent = this->fCurrent;
        that->fOffset = this->fOffset;
        that->fCurrentOffset = this->fCurrentOffset;
        return that;
    }

    size_t getLength() const override {
        return fSize;
    }

    const void* getMemoryBase() override {
        if (fBlockMemory->fHead && !fBlockMemory->fHead->fNext) {
            return fBlockMemory->fHead->start();
        }
        return nullptr;
    }

private:
    sk_sp<SkBlockMemoryRefCnt> const fBlockMemory;
    SkDynamicMemoryWStream::Block const * fCurrent;
    size_t const fSize;
    size_t fOffset;
    size_t fCurrentOffset;
};

std::unique_ptr<SkStreamAsset> SkDynamicMemoryWStream::detachAsStream() {
    if (nullptr == fHead) {
        // no need to reset.
        return SkMemoryStream::Make(nullptr);
    }
    if (fHead == fTail) {  // one block, may be worth shrinking.
        ptrdiff_t used = fTail->fCurr - (char*)fTail;
        fHead = fTail = (SkDynamicMemoryWStream::Block*)sk_realloc_throw(fTail, SkToSizeT(used));
        fTail->fStop = fTail->fCurr = (char*)fTail + used;  // Update pointers.
        SkASSERT(nullptr == fTail->fNext);
        SkASSERT(0 == fBytesWrittenBeforeTail);
    }
    std::unique_ptr<SkStreamAsset> stream
            = std::make_unique<SkBlockMemoryStream>(sk_make_sp<SkBlockMemoryRefCnt>(fHead),
                                                      this->bytesWritten());
    fHead = nullptr;    // signal reset() to not free anything
    this->reset();
    return stream;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static sk_sp<SkData> mmap_filename(const char path[]) {
    FILE* file = sk_fopen(path, kRead_SkFILE_Flag);
    if (nullptr == file) {
        return nullptr;
    }

    auto data = SkData::MakeFromFILE(file);
    sk_fclose(file);
    return data;
}

std::unique_ptr<SkStreamAsset> SkStream::MakeFromFile(const char path[]) {
    auto data(mmap_filename(path));
    if (data) {
        return std::make_unique<SkMemoryStream>(std::move(data));
    }

    // If we get here, then our attempt at using mmap failed, so try normal file access.
    auto stream = std::make_unique<SkFILEStream>(path);
    if (!stream->isValid()) {
        return nullptr;
    }
    return std::move(stream);
}

// Declared in SkStreamPriv.h:
sk_sp<SkData> SkCopyStreamToData(SkStream* stream) {
    SkASSERT(stream != nullptr);

    if (stream->hasLength()) {
        return SkData::MakeFromStream(stream, stream->getLength());
    }

    SkDynamicMemoryWStream tempStream;
    const size_t bufferSize = 4096;
    char buffer[bufferSize];
    do {
        size_t bytesRead = stream->read(buffer, bufferSize);
        tempStream.write(buffer, bytesRead);
    } while (!stream->isAtEnd());
    return tempStream.detachAsData();
}

bool SkStreamCopy(SkWStream* out, SkStream* input) {
    const char* base = static_cast<const char*>(input->getMemoryBase());
    if (base && input->hasPosition() && input->hasLength()) {
        // Shortcut that avoids the while loop.
        size_t position = input->getPosition();
        size_t length = input->getLength();
        SkASSERT(length >= position);
        return out->write(&base[position], length - position);
    }
    char scratch[4096];
    size_t count;
    while (true) {
        count = input->read(scratch, sizeof(scratch));
        if (0 == count) {
            return true;
        }
        if (!out->write(scratch, count)) {
            return false;
        }
    }
}
