| Index: include/core/SkStream.h | 
| =================================================================== | 
| --- include/core/SkStream.h	(revision 9222) | 
| +++ include/core/SkStream.h	(working copy) | 
| @@ -13,6 +13,12 @@ | 
|  | 
| 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. | 
| @@ -37,44 +43,37 @@ | 
| *  mmap if available). On success, the caller must call unref() on the | 
| *  returned object. On failure, returns NULL. | 
| */ | 
| -    static SkStream* NewFromFile(const char path[]); | 
| +    static SkStreamAsset* NewFromFile(const char path[]); | 
|  | 
| SK_DECLARE_INST_COUNT(SkStream) | 
|  | 
| -    /** Called to rewind to the beginning of the stream. If this cannot be | 
| -        done, return false. | 
| -    */ | 
| -    virtual bool rewind() = 0; | 
| -    /** If this stream represents a file, this method returns the file's name. | 
| -        If it does not, it returns NULL (the default behavior). | 
| -    */ | 
| -    virtual const char* getFileName(); | 
| -    /** Called to read or skip size number of bytes. | 
| -        If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped. | 
| -        If buffer is NULL and size == 0, return the total length of the stream. | 
| -        If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied. | 
| -        @param buffer   If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer | 
| -        @param size The number of bytes to skip or copy | 
| -        @return bytes read on success | 
| -    */ | 
| +    /** 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 bytes read on success | 
| +     */ | 
| virtual size_t read(void* buffer, size_t size) = 0; | 
|  | 
| -    /** Return the total length of the stream. | 
| -    */ | 
| -    size_t getLength() { return this->read(NULL, 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); | 
| +    } | 
|  | 
| -    /** Skip the specified number of bytes, returning the actual number | 
| -        of bytes that could be skipped. | 
| -    */ | 
| -    size_t skip(size_t bytes); | 
| +    /** Returns true if there are no more bytes to be read. | 
| +     *  In Progress: do not use until all implementations are updated. | 
| +     *  TODO: after this is implemented everywhere, make pure virtual. | 
| +     */ | 
| +    virtual bool atEnd() const { | 
| +        SkASSERT(false); | 
| +        return true; | 
| +    } | 
|  | 
| -    /** If the stream is backed by RAM, this method returns the starting | 
| -        address for the data. If not (i.e. it is backed by a file or other | 
| -        structure), this method returns NULL. | 
| -        The default implementation returns NULL. | 
| -    */ | 
| -    virtual const void* getMemoryBase(); | 
| - | 
| int8_t   readS8(); | 
| int16_t  readS16(); | 
| int32_t  readS32(); | 
| @@ -93,10 +92,99 @@ | 
| */ | 
| 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. */ | 
| +    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 atEnd() 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) | 
| @@ -147,81 +235,76 @@ | 
|  | 
| struct SkFILE; | 
|  | 
| -/** A stream that reads from a FILE*, which is opened in the constructor and | 
| -    closed in the destructor | 
| - */ | 
| -class SK_API SkFILEStream : public SkStream { | 
| +/** 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 fopen on the specified path. Will be | 
| -        closed in the destructor. | 
| +    /** 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. | 
| -    */ | 
| +    /** 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. | 
| -    */ | 
| + | 
| +    /** 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 bool rewind() SK_OVERRIDE; | 
| virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; | 
| -    virtual const char* getFileName() SK_OVERRIDE; | 
| +    virtual bool atEnd() const SK_OVERRIDE; | 
|  | 
| -private: | 
| -    SkFILE*     fFILE; | 
| -    SkString    fName; | 
| +    virtual bool rewind() SK_OVERRIDE; | 
| +    virtual SkStreamAsset* duplicate() const SK_OVERRIDE; | 
|  | 
| -    typedef SkStream INHERITED; | 
| -}; | 
| +    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; | 
|  | 
| -/** A stream that reads from a file descriptor | 
| - */ | 
| -class SK_API SkFDStream : public SkStream { | 
| -public: | 
| -    SK_DECLARE_INST_COUNT(SkFDStream) | 
| +    virtual size_t getLength() const SK_OVERRIDE; | 
|  | 
| -    /** Initialize the stream with a dup() of the specified file descriptor. | 
| -        If closeWhenDone is true, then the descriptor will be closed in the | 
| -        destructor. | 
| -     */ | 
| -    SkFDStream(int fileDesc, bool closeWhenDone); | 
| -    virtual ~SkFDStream(); | 
| +    const void* getMemoryBase() SK_OVERRIDE; | 
|  | 
| -    /** Returns true if the current path could be opened. | 
| -     */ | 
| -    bool isValid() const { return fFD >= 0; } | 
| - | 
| -    virtual bool rewind() SK_OVERRIDE; | 
| -    virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; | 
| -    virtual const char* getFileName() SK_OVERRIDE { return NULL; } | 
| - | 
| private: | 
| -    int     fFD; | 
| -    bool    fCloseWhenDone; | 
| +    SkFILE*     fFILE; | 
| +    SkString    fName; | 
| +    Ownership   fOwnership; | 
| +    // fData is lazilly initialized when needed. | 
| +    mutable SkAutoTUnref<SkData> fData; | 
|  | 
| -    typedef SkStream INHERITED; | 
| +    typedef SkStreamAsset INHERITED; | 
| }; | 
|  | 
| -class SK_API SkMemoryStream : public SkStream { | 
| +class SK_API SkMemoryStream : public SkStreamMemory { | 
| public: | 
| SK_DECLARE_INST_COUNT(SkMemoryStream) | 
|  | 
| SkMemoryStream(); | 
| -    /** We allocate (and free) the memory. Write to it via getMemoryBase() | 
| -    */ | 
| + | 
| +    /** 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 | 
| -    */ | 
| + | 
| +    /** 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). | 
| +    /** 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*); | 
|  | 
| @@ -239,81 +322,42 @@ | 
| */ | 
| 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. | 
| +    /** 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. | 
| +     *  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(); | 
| -    virtual bool rewind() SK_OVERRIDE; | 
| -    virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; | 
| -    virtual const void* getMemoryBase() SK_OVERRIDE; | 
| const void* getAtPos(); | 
| -    size_t seek(size_t offset); | 
| size_t peek() const { return fOffset; } | 
|  | 
| -private: | 
| -    SkData* fData; | 
| -    size_t  fOffset; | 
| +    virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; | 
| +    virtual bool atEnd() const SK_OVERRIDE; | 
|  | 
| -    typedef SkStream INHERITED; | 
| -}; | 
| +    virtual bool rewind() SK_OVERRIDE; | 
| +    virtual SkMemoryStream* duplicate() const SK_OVERRIDE; | 
|  | 
| -/** \class SkBufferStream | 
| -    This is a wrapper class that adds buffering to another stream. | 
| -    The caller can provide the buffer, or ask SkBufferStream to allocated/free | 
| -    it automatically. | 
| -*/ | 
| -class SK_API SkBufferStream : public SkStream { | 
| -public: | 
| -    SK_DECLARE_INST_COUNT(SkBufferStream) | 
| +    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; | 
|  | 
| -    /** Provide the stream to be buffered (proxy), and the size of the buffer that | 
| -        should be used. This will be allocated and freed automatically. If bufferSize is 0, | 
| -        a default buffer size will be used. | 
| -        The proxy stream is referenced, and will be unreferenced in when the | 
| -        bufferstream is destroyed. | 
| -    */ | 
| -    SkBufferStream(SkStream* proxy, size_t bufferSize = 0); | 
| -    /** Provide the stream to be buffered (proxy), and a buffer and size to be used. | 
| -        This buffer is owned by the caller, and must be at least bufferSize bytes big. | 
| -        Passing NULL for buffer will cause the buffer to be allocated/freed automatically. | 
| -        If buffer is not NULL, it is an error for bufferSize to be 0. | 
| -     The proxy stream is referenced, and will be unreferenced in when the | 
| -     bufferstream is destroyed. | 
| -    */ | 
| -    SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize); | 
| -    virtual ~SkBufferStream(); | 
| +    virtual size_t getLength() const SK_OVERRIDE; | 
|  | 
| -    virtual bool        rewind() SK_OVERRIDE; | 
| -    virtual const char* getFileName() SK_OVERRIDE; | 
| -    virtual size_t      read(void* buffer, size_t size) SK_OVERRIDE; | 
| virtual const void* getMemoryBase() SK_OVERRIDE; | 
|  | 
| private: | 
| -    enum { | 
| -        kDefaultBufferSize  = 128 | 
| -    }; | 
| -    // illegal | 
| -    SkBufferStream(const SkBufferStream&); | 
| -    SkBufferStream& operator=(const SkBufferStream&); | 
| +    SkData* fData; | 
| +    size_t  fOffset; | 
|  | 
| -    SkStream*   fProxy; | 
| -    char*       fBuffer; | 
| -    size_t      fOrigBufferSize, fBufferSize, fBufferOffset; | 
| -    bool        fWeOwnTheBuffer; | 
| - | 
| -    void    init(void*, size_t); | 
| - | 
| -    typedef SkStream INHERITED; | 
| +    typedef SkStreamMemory INHERITED; | 
| }; | 
|  | 
| ///////////////////////////////////////////////////////////////////////////////////////////// | 
|  |