/*
 * 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.
 */

#ifndef SkStream_DEFINED
#define SkStream_DEFINED

#include "SkRefCnt.h"
#include "SkScalar.h"

class SkData;

class SkStream;
class SkStreamRewindable;
class SkStreamSeekable;
class SkStreamAsset;
class SkStreamMemory;

/**
 *  SkStream -- abstraction for a source of bytes. Subclasses can be backed by
 *  memory, or a file, or something else.
 *
 *  NOTE:
 *
 *  Classic "streams" APIs are sort of async, in that on a request for N
 *  bytes, they may return fewer than N bytes on a given call, in which case
 *  the caller can "try again" to get more bytes, eventually (modulo an error)
 *  receiving their total N bytes.
 *
 *  Skia streams behave differently. They are effectively synchronous, and will
 *  always return all N bytes of the request if possible. If they return fewer
 *  (the read() call returns the number of bytes read) then that means there is
 *  no more data (at EOF or hit an error). The caller should *not* call again
 *  in hopes of fulfilling more of the request.
 */
class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt
public:
    /**
     *  Attempts to open the specified file, and return a stream to it (using
     *  mmap if available). On success, the caller must call unref() on the
     *  returned object. On failure, returns NULL.
     */
    static SkStreamAsset* NewFromFile(const char path[]);

    SK_DECLARE_INST_COUNT(SkStream)

    /** Reads or skips size number of bytes.
     *  If buffer == NULL, skip size bytes, return how many were skipped.
     *  If buffer != NULL, copy size bytes into buffer, return how many were copied.
     *  @param buffer when NULL skip size bytes, otherwise copy size bytes into buffer
     *  @param size the number of bytes to skip or copy
     *  @return the number of bytes actually read.
     */
    virtual size_t read(void* buffer, size_t size) = 0;

    /** Skip size number of bytes.
     *  @return the actual number bytes that could be skipped.
     */
    size_t skip(size_t size) {
        //return this->read(NULL, size);
        //TODO: remove this old logic after updating existing implementations
        return 0 == size ? 0 : this->read(NULL, size);
    }

    /** Returns true when all the bytes in the stream have been read.
     *  This may return true early (when there are no more bytes to be read)
     *  or late (after the first unsuccessful read).
     *
     *  In Progress: do not use until all implementations are updated.
     *  TODO: after this is implemented everywhere, make pure virtual.
     */
    virtual bool isAtEnd() const {
        SkASSERT(false);
        return true;
    }

    int8_t   readS8();
    int16_t  readS16();
    int32_t  readS32();

    uint8_t  readU8() { return (uint8_t)this->readS8(); }
    uint16_t readU16() { return (uint16_t)this->readS16(); }
    uint32_t readU32() { return (uint32_t)this->readS32(); }

    bool     readBool() { return this->readU8() != 0; }
    SkScalar readScalar();
    size_t   readPackedUInt();

    /**
     *  Reconstitute an SkData object that was written to the stream
     *  using SkWStream::writeData().
     */
    SkData* readData();

//SkStreamRewindable
    /** Rewinds to the beginning of the stream. If this cannot be done, return false. */
    virtual bool rewind() { return false; }

    /** Duplicates this stream. If this cannot be done, returns NULL.
     *  The returned stream will be positioned at the beginning of its data.
     */
    virtual SkStreamRewindable* duplicate() const { return NULL; }

//SkStreamSeekable
    /** Returns true if this stream can report it's current position. */
    virtual bool hasPosition() const { return false; }
    /** Returns the current position in the stream. If this cannot be done, returns 0. */
    virtual size_t getPosition() const { return 0; }

    /** Seeks to an absolute position in the stream. If this cannot be done, returns false.
     *  If an attempt is made to seek past the end of the stream, the position will be set
     *  to the end of the stream.
     */
    virtual bool seek(size_t position) { return false; }

    /** Seeks to an relative offset in the stream. If this cannot be done, returns false.
     *  If an attempt is made to move to a position outside the stream, the position will be set
     *  to the closest point within the stream (beginning or end).
     */
    virtual bool move(long offset) { return false; }

    /** Duplicates this stream. If this cannot be done, returns NULL.
     *  The returned stream will be positioned the same as this stream.
     */
    virtual SkStreamSeekable* fork() const { return NULL; }

//SkStreamAsset
    /** Returns true if this stream can report it's total length. */
    virtual bool hasLength() const { return false; }
    /** Returns the total length of the stream. If this cannot be done, returns 0. */
    virtual size_t getLength() const {
        //return 0;
        //TODO: remove the following after everyone is updated.
        return ((SkStream*)this)->read(NULL, 0);
    }

//SkStreamMemory
    /** Returns the starting address for the data. If this cannot be done, returns NULL. */
    //TODO: replace with virtual const SkData* getData()
    virtual const void* getMemoryBase() { return NULL; }

private:
    typedef SkRefCnt INHERITED;
};

/** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */
class SK_API SkStreamRewindable : public SkStream {
public:
    //TODO: remove the following after everyone is updated (ensures new behavior on new classes).
    virtual bool isAtEnd() const SK_OVERRIDE = 0;
    //TODO: remove the following after everyone is updated (ensures new behavior on new classes).
    virtual size_t getLength() const SK_OVERRIDE { return 0; }

    virtual bool rewind() SK_OVERRIDE = 0;
    virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0;
};

/** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */
class SK_API SkStreamSeekable : public SkStreamRewindable {
public:
    virtual SkStreamSeekable* duplicate() const SK_OVERRIDE = 0;

    virtual bool hasPosition() const SK_OVERRIDE { return true; }
    virtual size_t getPosition() const SK_OVERRIDE = 0;
    virtual bool seek(size_t position) SK_OVERRIDE = 0;
    virtual bool move(long offset) SK_OVERRIDE = 0;
    virtual SkStreamSeekable* fork() const SK_OVERRIDE = 0;
};

/** SkStreamAsset is a SkStreamSeekable for which getLength is required. */
class SK_API SkStreamAsset : public SkStreamSeekable {
public:
    virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0;
    virtual SkStreamAsset* fork() const SK_OVERRIDE = 0;

    virtual bool hasLength() const SK_OVERRIDE { return true; }
    virtual size_t getLength() const SK_OVERRIDE = 0;
};

/** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */
class SK_API SkStreamMemory : public SkStreamAsset {
public:
    virtual SkStreamMemory* duplicate() const SK_OVERRIDE = 0;
    virtual SkStreamMemory* fork() const SK_OVERRIDE = 0;

    virtual const void* getMemoryBase() SK_OVERRIDE = 0;
};

class SK_API SkWStream : SkNoncopyable {
public:
    SK_DECLARE_INST_COUNT_ROOT(SkWStream)

    virtual ~SkWStream();

    /** Called to write bytes to a SkWStream. Returns true on success
        @param buffer the address of at least size bytes to be written to the stream
        @param size The number of bytes in buffer to write to the stream
        @return true on success
    */
    virtual bool write(const void* buffer, size_t size) = 0;
    virtual void newline();
    virtual void flush();

    // helpers

    bool    write8(U8CPU);
    bool    write16(U16CPU);
    bool    write32(uint32_t);

    bool    writeText(const char text[]);
    bool    writeDecAsText(int32_t);
    bool    writeBigDecAsText(int64_t, int minDigits = 0);
    bool    writeHexAsText(uint32_t, int minDigits = 0);
    bool    writeScalarAsText(SkScalar);

    bool    writeBool(bool v) { return this->write8(v); }
    bool    writeScalar(SkScalar);
    bool    writePackedUInt(size_t);

    bool writeStream(SkStream* input, size_t length);

    /**
     * Append an SkData object to the stream, such that it can be read
     * out of the stream using SkStream::readData().
     *
     * Note that the encoding method used to write the SkData object
     * to the stream may change over time.  This method DOES NOT
     * just write the raw content of the SkData object to the stream.
     */
    bool writeData(const SkData*);
};

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

#include "SkString.h"

struct SkFILE;

/** A stream that wraps a C FILE* file stream. */
class SK_API SkFILEStream : public SkStreamAsset {
public:
    SK_DECLARE_INST_COUNT(SkFILEStream)

    /** Initialize the stream by calling sk_fopen on the specified path.
     *  This internal stream will be closed in the destructor.
     */
    explicit SkFILEStream(const char path[] = NULL);

    enum Ownership {
        kCallerPasses_Ownership,
        kCallerRetains_Ownership
    };
    /** Initialize the stream with an existing C file stream.
     *  While this stream exists, it assumes exclusive access to the C file stream.
     *  The C file stream will be closed in the destructor unless the caller specifies
     *  kCallerRetains_Ownership.
     */
    explicit SkFILEStream(FILE* file, Ownership ownership = kCallerPasses_Ownership);

    virtual ~SkFILEStream();

    /** Returns true if the current path could be opened. */
    bool isValid() const { return fFILE != NULL; }

    /** Close the current file, and open a new file with the specified path.
     *  If path is NULL, just close the current file.
     */
    void setPath(const char path[]);

    virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    virtual bool isAtEnd() const SK_OVERRIDE;

    virtual bool rewind() SK_OVERRIDE;
    virtual SkStreamAsset* duplicate() const SK_OVERRIDE;

    virtual size_t getPosition() const SK_OVERRIDE;
    virtual bool seek(size_t position) SK_OVERRIDE;
    virtual bool move(long offset) SK_OVERRIDE;
    virtual SkStreamAsset* fork() const SK_OVERRIDE;

    virtual size_t getLength() const SK_OVERRIDE;

    virtual const void* getMemoryBase() SK_OVERRIDE;

private:
    SkFILE*     fFILE;
    SkString    fName;
    Ownership   fOwnership;
    // fData is lazilly initialized when needed.
    mutable SkAutoTUnref<SkData> fData;

    typedef SkStreamAsset INHERITED;
};

class SK_API SkMemoryStream : public SkStreamMemory {
public:
    SK_DECLARE_INST_COUNT(SkMemoryStream)

    SkMemoryStream();

    /** We allocate (and free) the memory. Write to it via getMemoryBase() */
    SkMemoryStream(size_t length);

    /** If copyData is true, the stream makes a private copy of the data. */
    SkMemoryStream(const void* data, size_t length, bool copyData = false);

    /** Use the specified data as the memory for this stream.
     *  The stream will call ref() on the data (assuming it is not NULL).
     */
    SkMemoryStream(SkData*);

    virtual ~SkMemoryStream();

    /** Resets the stream to the specified data and length,
        just like the constructor.
        if copyData is true, the stream makes a private copy of the data
    */
    virtual void setMemory(const void* data, size_t length,
                           bool copyData = false);
    /** Replace any memory buffer with the specified buffer. The caller
        must have allocated data with sk_malloc or sk_realloc, since it
        will be freed with sk_free.
    */
    void setMemoryOwned(const void* data, size_t length);

    /** Return the stream's data in a SkData.
     *  The caller must call unref() when it is finished using the data.
     */
    SkData* copyToData() const;

    /**
     *  Use the specified data as the memory for this stream.
     *  The stream will call ref() on the data (assuming it is not NULL).
     *  The function returns the data parameter as a convenience.
     */
    SkData* setData(SkData*);

    void skipToAlign4();
    const void* getAtPos();
    size_t peek() const { return fOffset; }

    virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    virtual bool isAtEnd() const SK_OVERRIDE;

    virtual bool rewind() SK_OVERRIDE;
    virtual SkMemoryStream* duplicate() const SK_OVERRIDE;

    virtual size_t getPosition() const SK_OVERRIDE;
    virtual bool seek(size_t position) SK_OVERRIDE;
    virtual bool move(long offset) SK_OVERRIDE;
    virtual SkMemoryStream* fork() const SK_OVERRIDE;

    virtual size_t getLength() const SK_OVERRIDE;

    virtual const void* getMemoryBase() SK_OVERRIDE;

private:
    SkData* fData;
    size_t  fOffset;

    typedef SkStreamMemory INHERITED;
};

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

class SK_API SkFILEWStream : public SkWStream {
public:
    SK_DECLARE_INST_COUNT(SkFILEWStream)

    SkFILEWStream(const char path[]);
    virtual ~SkFILEWStream();

    /** Returns true if the current path could be opened.
    */
    bool isValid() const { return fFILE != NULL; }

    virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    virtual void flush() SK_OVERRIDE;

private:
    SkFILE* fFILE;

    typedef SkWStream INHERITED;
};

class SkMemoryWStream : public SkWStream {
public:
    SK_DECLARE_INST_COUNT(SkMemoryWStream)

    SkMemoryWStream(void* buffer, size_t size);
    virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    size_t bytesWritten() const { return fBytesWritten; }

private:
    char*   fBuffer;
    size_t  fMaxLength;
    size_t  fBytesWritten;

    typedef SkWStream INHERITED;
};

class SK_API SkDynamicMemoryWStream : public SkWStream {
public:
    SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream)

    SkDynamicMemoryWStream();
    virtual ~SkDynamicMemoryWStream();

    virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    // random access write
    // modifies stream and returns true if offset + size is less than or equal to getOffset()
    bool write(const void* buffer, size_t offset, size_t size);
    bool read(void* buffer, size_t offset, size_t size);
    size_t getOffset() const { return fBytesWritten; }
    size_t bytesWritten() const { return fBytesWritten; }

    // copy what has been written to the stream into dst
    void copyTo(void* dst) const;

    /**
     *  Return a copy of the data written so far. This call is responsible for
     *  calling unref() when they are finished with the data.
     */
    SkData* copyToData() const;

    /** Reset, returning a reader stream with the current content. */
    SkStreamAsset* detachAsStream();

    /** Reset the stream to its original, empty, state. */
    void reset();
    void padToAlign4();
private:
    struct Block;
    Block*  fHead;
    Block*  fTail;
    size_t  fBytesWritten;
    mutable SkData* fCopy;  // is invalidated if we write after it is created

    void invalidateCopy();

    // For access to the Block type.
    friend class SkBlockMemoryStream;
    friend class SkBlockMemoryRefCnt;

    typedef SkWStream INHERITED;
};


class SK_API SkDebugWStream : public SkWStream {
public:
    SK_DECLARE_INST_COUNT(SkDebugWStream)

    // overrides
    virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    virtual void newline() SK_OVERRIDE;

private:
    typedef SkWStream INHERITED;
};

// for now
typedef SkFILEStream SkURLStream;

#endif
