SkStream.h revision d877fdbb6e64692285c3e6532d88b9458f65b3cd
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef SkStream_DEFINED 18#define SkStream_DEFINED 19 20#include "SkRefCnt.h" 21#include "SkScalar.h" 22 23class SkStream : public SkRefCnt { 24public: 25 virtual ~SkStream(); 26 /** Called to rewind to the beginning of the stream. If this cannot be 27 done, return false. 28 */ 29 virtual bool rewind() = 0; 30 /** If this stream represents a file, this method returns the file's name. 31 If it does not, it returns NULL (the default behavior). 32 */ 33 virtual const char* getFileName(); 34 /** Called to read or skip size number of bytes. 35 If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped. 36 If buffer is NULL and size == 0, return the total length of the stream. 37 If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied. 38 @param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer 39 @param size The number of bytes to skip or copy 40 @return bytes read on success 41 */ 42 virtual size_t read(void* buffer, size_t size) = 0; 43 44 /** Return the total length of the stream. 45 */ 46 size_t getLength() { return this->read(NULL, 0); } 47 48 /** Skip the specified number of bytes, returning the actual number 49 of bytes that could be skipped. 50 */ 51 size_t skip(size_t bytes); 52 53 /** If the stream is backed by RAM, this method returns the starting 54 address for the data. If not (i.e. it is backed by a file or other 55 structure), this method returns NULL. 56 The default implementation returns NULL. 57 */ 58 virtual const void* getMemoryBase(); 59 60 int8_t readS8(); 61 int16_t readS16(); 62 int32_t readS32(); 63 64 uint8_t readU8() { return (uint8_t)this->readS8(); } 65 uint16_t readU16() { return (uint16_t)this->readS16(); } 66 uint32_t readU32() { return (uint32_t)this->readS32(); } 67 68 bool readBool() { return this->readU8() != 0; } 69 SkScalar readScalar(); 70 size_t readPackedUInt(); 71}; 72 73class SkWStream : SkNoncopyable { 74public: 75 virtual ~SkWStream(); 76 77 /** Called to write bytes to a SkWStream. Returns true on success 78 @param buffer the address of at least size bytes to be written to the stream 79 @param size The number of bytes in buffer to write to the stream 80 @return true on success 81 */ 82 virtual bool write(const void* buffer, size_t size) = 0; 83 virtual void newline(); 84 virtual void flush(); 85 86 // helpers 87 88 bool write8(U8CPU); 89 bool write16(U16CPU); 90 bool write32(uint32_t); 91 92 bool writeText(const char text[]); 93 bool writeDecAsText(int32_t); 94 bool writeBigDecAsText(int64_t, int minDigits = 0); 95 bool writeHexAsText(uint32_t, int minDigits = 0); 96 bool writeScalarAsText(SkScalar); 97 98 bool writeBool(bool v) { return this->write8(v); } 99 bool writeScalar(SkScalar); 100 bool writePackedUInt(size_t); 101 102 bool writeStream(SkStream* input, size_t length); 103}; 104 105//////////////////////////////////////////////////////////////////////////////////////// 106 107#include "SkString.h" 108 109struct SkFILE; 110 111/** A stream that reads from a FILE*, which is opened in the constructor and 112 closed in the destructor 113 */ 114class SkFILEStream : public SkStream { 115public: 116 /** Initialize the stream by calling fopen on the specified path. Will be 117 closed in the destructor. 118 */ 119 explicit SkFILEStream(const char path[] = NULL); 120 virtual ~SkFILEStream(); 121 122 /** Returns true if the current path could be opened. 123 */ 124 bool isValid() const { return fFILE != NULL; } 125 /** Close the current file, and open a new file with the specified 126 path. If path is NULL, just close the current file. 127 */ 128 void setPath(const char path[]); 129 130 virtual bool rewind(); 131 virtual size_t read(void* buffer, size_t size); 132 virtual const char* getFileName(); 133 134private: 135 SkFILE* fFILE; 136 SkString fName; 137}; 138 139/** A stream that reads from a file descriptor 140 */ 141class SkFDStream : public SkStream { 142public: 143 /** Initialize the stream with a dup() of the specified file descriptor. 144 If closeWhenDone is true, then the descriptor will be closed in the 145 destructor. 146 */ 147 SkFDStream(int fileDesc, bool closeWhenDone); 148 virtual ~SkFDStream(); 149 150 /** Returns true if the current path could be opened. 151 */ 152 bool isValid() const { return fFD >= 0; } 153 154 virtual bool rewind(); 155 virtual size_t read(void* buffer, size_t size); 156 virtual const char* getFileName() { return NULL; } 157 158private: 159 int fFD; 160 bool fCloseWhenDone; 161}; 162 163class SkMemoryStream : public SkStream { 164public: 165 SkMemoryStream(); 166 /** We allocate (and free) the memory. Write to it via getMemoryBase() 167 */ 168 SkMemoryStream(size_t length); 169 /** if copyData is true, the stream makes a private copy of the data 170 */ 171 SkMemoryStream(const void* data, size_t length, bool copyData = false); 172 virtual ~SkMemoryStream(); 173 174 /** Resets the stream to the specified data and length, 175 just like the constructor. 176 if copyData is true, the stream makes a private copy of the data 177 */ 178 virtual void setMemory(const void* data, size_t length, 179 bool copyData = false); 180 void skipToAlign4(); 181 virtual bool rewind(); 182 virtual size_t read(void* buffer, size_t size); 183 virtual const void* getMemoryBase(); 184 const void* getAtPos(); 185 size_t seek(size_t offset); 186 size_t peek() const { return fOffset; } 187 188private: 189 const void* fSrc; 190 size_t fSize, fOffset; 191 SkBool8 fWeOwnTheData; 192}; 193 194/** \class SkBufferStream 195 This is a wrapper class that adds buffering to another stream. 196 The caller can provide the buffer, or ask SkBufferStream to allocated/free 197 it automatically. 198*/ 199class SkBufferStream : public SkStream { 200public: 201 /** Provide the stream to be buffered (proxy), and the size of the buffer that 202 should be used. This will be allocated and freed automatically. If bufferSize is 0, 203 a default buffer size will be used. 204 The proxy stream is referenced, and will be unreferenced in when the 205 bufferstream is destroyed. 206 */ 207 SkBufferStream(SkStream* proxy, size_t bufferSize = 0); 208 /** Provide the stream to be buffered (proxy), and a buffer and size to be used. 209 This buffer is owned by the caller, and must be at least bufferSize bytes big. 210 Passing NULL for buffer will cause the buffer to be allocated/freed automatically. 211 If buffer is not NULL, it is an error for bufferSize to be 0. 212 The proxy stream is referenced, and will be unreferenced in when the 213 bufferstream is destroyed. 214 */ 215 SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize); 216 virtual ~SkBufferStream(); 217 218 virtual bool rewind(); 219 virtual const char* getFileName(); 220 virtual size_t read(void* buffer, size_t size); 221 virtual const void* getMemoryBase(); 222 223private: 224 enum { 225 kDefaultBufferSize = 128 226 }; 227 // illegal 228 SkBufferStream(const SkBufferStream&); 229 SkBufferStream& operator=(const SkBufferStream&); 230 231 SkStream* fProxy; 232 char* fBuffer; 233 size_t fOrigBufferSize, fBufferSize, fBufferOffset; 234 bool fWeOwnTheBuffer; 235 236 void init(void*, size_t); 237}; 238 239///////////////////////////////////////////////////////////////////////////////////////////// 240 241class SkFILEWStream : public SkWStream { 242public: 243 SkFILEWStream(const char path[]); 244 virtual ~SkFILEWStream(); 245 246 /** Returns true if the current path could be opened. 247 */ 248 bool isValid() const { return fFILE != NULL; } 249 250 virtual bool write(const void* buffer, size_t size); 251 virtual void flush(); 252private: 253 SkFILE* fFILE; 254}; 255 256class SkMemoryWStream : public SkWStream { 257public: 258 SkMemoryWStream(void* buffer, size_t size); 259 virtual bool write(const void* buffer, size_t size); 260 261private: 262 char* fBuffer; 263 size_t fMaxLength; 264 size_t fBytesWritten; 265}; 266 267class SkDynamicMemoryWStream : public SkWStream { 268public: 269 SkDynamicMemoryWStream(); 270 virtual ~SkDynamicMemoryWStream(); 271 virtual bool write(const void* buffer, size_t size); 272 // random access write 273 // modifies stream and returns true if offset + size is less than or equal to getOffset() 274 bool write(const void* buffer, size_t offset, size_t size); 275 bool read(void* buffer, size_t offset, size_t size); 276 size_t getOffset() { return fBytesWritten; } 277 278 // copy what has been written to the stream into dst 279 void copyTo(void* dst) const; 280 /* return a cache of the flattened data returned by copyTo(). 281 This copy is only valid until the next call to write(). 282 The memory is managed by the stream class. 283 */ 284 const char* getStream() const; 285 286 // same as getStream, but additionally detach the flattened datat 287 const char* detach(); 288 289 // reset the stream to its original state 290 void reset(); 291 void padToAlign4(); 292private: 293 struct Block; 294 Block* fHead; 295 Block* fTail; 296 size_t fBytesWritten; 297 mutable char* fCopyToCache; 298}; 299 300 301class SkDebugWStream : public SkWStream { 302public: 303 // overrides 304 virtual bool write(const void* buffer, size_t size); 305 virtual void newline(); 306}; 307 308// for now 309typedef SkFILEStream SkURLStream; 310 311#endif 312