grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
new file mode 100644
index 0000000..26ef43f
--- /dev/null
+++ b/include/core/SkStream.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkStream_DEFINED
+#define SkStream_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkScalar.h"
+
+class SkStream : public SkRefCnt {
+public:
+ virtual ~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
+ */
+ 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();
+
+ 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();
+
+ static void UnitTest();
+};
+
+class SkWStream : SkNoncopyable {
+public:
+ 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 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);
+
+ static void UnitTest();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkString.h"
+
+struct SkFILE;
+
+/** A stream that reads from a FILE*, which is opened in the constructor and
+ closed in the destructor
+ */
+class SkFILEStream : public SkStream {
+public:
+ /** Initialize the stream by calling fopen on the specified path. Will be
+ closed in the destructor.
+ */
+ explicit SkFILEStream(const char path[] = NULL);
+ 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 bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const char* getFileName();
+
+private:
+ SkFILE* fFILE;
+ SkString fName;
+};
+
+/** A stream that reads from a file descriptor
+ */
+class SkFDStream : public SkStream {
+public:
+ /** 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();
+
+ /** Returns true if the current path could be opened.
+ */
+ bool isValid() const { return fFD >= 0; }
+
+ virtual bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const char* getFileName() { return NULL; }
+
+private:
+ int fFD;
+ bool fCloseWhenDone;
+};
+
+class SkMemoryStream : public SkStream {
+public:
+ 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);
+ 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);
+ void skipToAlign4();
+ virtual bool rewind();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const void* getMemoryBase();
+ const void* getAtPos();
+ size_t seek(size_t offset);
+ size_t peek() const { return fOffset; }
+
+private:
+ const void* fSrc;
+ size_t fSize, fOffset;
+ SkBool8 fWeOwnTheData;
+};
+
+/** \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 SkBufferStream : public SkStream {
+public:
+ /** 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 bool rewind();
+ virtual const char* getFileName();
+ virtual size_t read(void* buffer, size_t size);
+ virtual const void* getMemoryBase();
+
+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);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkFILEWStream : public SkWStream {
+public:
+ 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);
+ virtual void flush();
+private:
+ SkFILE* fFILE;
+};
+
+class SkMemoryWStream : public SkWStream {
+public:
+ SkMemoryWStream(void* buffer, size_t size);
+ virtual bool write(const void* buffer, size_t size);
+
+private:
+ char* fBuffer;
+ size_t fMaxLength;
+ size_t fBytesWritten;
+};
+
+class SkDynamicMemoryWStream : public SkWStream {
+public:
+ SkDynamicMemoryWStream();
+ virtual ~SkDynamicMemoryWStream();
+ virtual bool write(const void* buffer, size_t size);
+ // 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() { return fBytesWritten; }
+
+ // copy what has been written to the stream into dst
+ void copyTo(void* dst) const;
+ /* return a cache of the flattened data returned by copyTo().
+ This copy is only valid until the next call to write().
+ The memory is managed by the stream class.
+ */
+ const char* getStream() const;
+
+ // same as getStream, but additionally detach the flattened datat
+ const char* detach();
+
+ // reset the stream to its original state
+ void reset();
+ void padToAlign4();
+private:
+ struct Block;
+ Block* fHead;
+ Block* fTail;
+ size_t fBytesWritten;
+ mutable char* fCopyToCache;
+};
+
+
+class SkDebugWStream : public SkWStream {
+public:
+ // overrides
+ virtual bool write(const void* buffer, size_t size);
+ virtual void newline();
+};
+
+// for now
+typedef SkFILEStream SkURLStream;
+
+#endif
+