Chromium Code Reviews| Index: include/core/SkStream.h |
| =================================================================== |
| --- include/core/SkStream.h (revision 9180) |
| +++ 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. |
| @@ -32,49 +38,50 @@ |
| */ |
| class SK_API SkStream : public SkRefCnt { |
| public: |
| + class Optimizer { |
| + public: |
| + virtual void operator()(SkStreamMemory& stream) = 0; |
| + virtual void operator()(SkStreamAsset& stream) = 0; |
| + virtual void operator()(SkStreamSeekable& stream) = 0; |
| + virtual void operator()(SkStreamRewindable& stream) = 0; |
| + virtual void operator()(SkStream& stream) = 0; |
| + }; |
| + /** Stream/Optimizer double dispatch entry point. |
| + * |
| + * Users of stream can call this method, which will then call the operator() on optimizer |
| + * which accepts the runtime type of this stream. |
| + * |
| + * All subclasses which wish to support optimization must override this method. |
| + * When overridden the implementation must be 'optimizer(*this);'. |
| + */ |
| + virtual void optimize(Optimizer& optimizer) { optimizer(*this); } |
|
djsollen
2013/05/21 15:41:22
remove the optimizer until we have a demonstrable
bungeman-skia
2013/05/21 23:24:59
Done.
|
| + |
| /** |
| * 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 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 |
| - */ |
| +//SkStream |
|
djsollen
2013/05/21 15:41:22
remove this
bungeman-skia
2013/05/21 23:24:59
Done.
|
| + /** Reads or skips size number of bytes. |
| + * If buffer == NULL, skip size bytes, returning how many were skipped. |
| + * If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied. |
| + * @param buffer when 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 |
| + */ |
| 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); |
| + } |
| - /** Skip the specified number of bytes, returning the actual number |
| - of bytes that could be skipped. |
| - */ |
| - size_t skip(size_t bytes); |
| - |
| - /** 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 +100,92 @@ |
| */ |
| 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 |
| + /** 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 the total length of the stream. If this cannot be done, returns zero. */ |
| + virtual size_t getLength() const { |
| + //return 0; |
| + // Until we can update all implementations, keep legacy behavior. |
| + 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: |
| + virtual void optimize(Optimizer& optimizer) SK_OVERRIDE { optimizer(*this); } |
| + |
| + virtual bool rewind() SK_OVERRIDE = 0; |
| + virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0; |
| +}; |
| + |
| +/** SkStreamSeekable is a SkStreamRewindable for which seek, move, and fork are required. */ |
| +class SK_API SkStreamSeekable : public SkStreamRewindable { |
| +public: |
| + virtual void optimize(Optimizer& optimizer) SK_OVERRIDE { optimizer(*this); } |
| + |
| + virtual SkStreamSeekable* duplicate() 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 void optimize(Optimizer& optimizer) SK_OVERRIDE { optimizer(*this); } |
| + |
| + virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0; |
| + virtual SkStreamAsset* fork() const SK_OVERRIDE = 0; |
| + |
| + 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 void optimize(Optimizer& optimizer) SK_OVERRIDE { optimizer(*this); } |
| + |
| + 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 +236,74 @@ |
| 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; |
| -private: |
| - SkFILE* fFILE; |
| - SkString fName; |
| + virtual bool rewind() SK_OVERRIDE; |
| + virtual SkStreamAsset* duplicate() const SK_OVERRIDE; |
| - typedef SkStream INHERITED; |
| -}; |
| + 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 +321,40 @@ |
| */ |
| 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; |
| - 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 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; |
| }; |
| ///////////////////////////////////////////////////////////////////////////////////////////// |