diff options
author | 2013-05-29 13:43:31 +0000 | |
---|---|---|
committer | 2013-05-29 13:43:31 +0000 | |
commit | 6cab1a4b6a68aa81237731308ff37a646d48f51c (patch) | |
tree | 9fbab394aea93cd4a8a828e48ed325366d8f79e0 /include | |
parent | 6320e8f393539b7a536b32b5a072a474709da5ff (diff) |
Change SkStream.
https://codereview.chromium.org/15298009/
git-svn-id: http://skia.googlecode.com/svn/trunk@9312 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include')
-rw-r--r-- | include/core/SkOSFile.h | 16 | ||||
-rw-r--r-- | include/core/SkStream.h | 319 |
2 files changed, 197 insertions, 138 deletions
diff --git a/include/core/SkOSFile.h b/include/core/SkOSFile.h index 8564d43027..11330a03b1 100644 --- a/include/core/SkOSFile.h +++ b/include/core/SkOSFile.h @@ -48,9 +48,23 @@ char* sk_fgets(char* str, int size, SkFILE* f); void sk_fflush(SkFILE*); -int sk_fseek(SkFILE*, size_t, int); +bool sk_fseek(SkFILE*, size_t); +bool sk_fmove(SkFILE*, long); size_t sk_ftell(SkFILE*); +/** Maps a file into memory. Returns the address and length on success, NULL otherwise. + * The mapping is read only. + */ +void* sk_fmmap(SkFILE* f, size_t* length); + +/** Unmaps a file previously mapped by sk_fmmap. + * The length parameter must be the same as returned from sk_fmmap. + */ +void sk_fmunmap(const void* addr, size_t length); + +/** Returns true if the two point at the exact same filesystem object. */ +bool sk_fidentical(SkFILE* a, SkFILE* b); + // Returns true if something (file, directory, ???) exists at this path. bool sk_exists(const char *path); diff --git a/include/core/SkStream.h b/include/core/SkStream.h index 310f939439..31ed7bc6d4 100644 --- a/include/core/SkStream.h +++ b/include/core/SkStream.h @@ -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. @@ -30,50 +36,43 @@ class SkData; * 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 { +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 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 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(); + /** 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 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 isAtEnd() const { + SkASSERT(false); + return true; + } int8_t readS8(); int16_t readS16(); @@ -93,10 +92,100 @@ public: */ 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) @@ -147,81 +236,76 @@ public: 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; - - typedef SkStream INHERITED; -}; + virtual bool isAtEnd() const SK_OVERRIDE; -/** A stream that reads from a file descriptor - */ -class SK_API SkFDStream : public SkStream { -public: - SK_DECLARE_INST_COUNT(SkFDStream) + virtual bool rewind() SK_OVERRIDE; + virtual SkStreamAsset* duplicate() 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(); + 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; - /** Returns true if the current path could be opened. - */ - bool isValid() const { return fFD >= 0; } + virtual size_t getLength() const SK_OVERRIDE; - virtual bool rewind() SK_OVERRIDE; - virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; - virtual const char* getFileName() SK_OVERRIDE { return NULL; } + const void* getMemoryBase() SK_OVERRIDE; 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 +323,42 @@ public: */ 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 isAtEnd() 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&); - - SkStream* fProxy; - char* fBuffer; - size_t fOrigBufferSize, fBufferSize, fBufferOffset; - bool fWeOwnTheBuffer; - - void init(void*, size_t); + SkData* fData; + size_t fOffset; - typedef SkStream INHERITED; + typedef SkStreamMemory INHERITED; }; ///////////////////////////////////////////////////////////////////////////////////////////// |