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 23 class SkStream : public SkRefCnt { 24 public: 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 */ getLength()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 readU8()64 uint8_t readU8() { return (uint8_t)this->readS8(); } readU16()65 uint16_t readU16() { return (uint16_t)this->readS16(); } readU32()66 uint32_t readU32() { return (uint32_t)this->readS32(); } 67 readBool()68 bool readBool() { return this->readU8() != 0; } 69 SkScalar readScalar(); 70 size_t readPackedUInt(); 71 }; 72 73 class SkWStream : SkNoncopyable { 74 public: 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 writeHexAsText(uint32_t, int minDigits = 0); 95 bool writeScalarAsText(SkScalar); 96 writeBool(bool v)97 bool writeBool(bool v) { return this->write8(v); } 98 bool writeScalar(SkScalar); 99 bool writePackedUInt(size_t); 100 101 bool writeStream(SkStream* input, size_t length); 102 }; 103 104 //////////////////////////////////////////////////////////////////////////////////////// 105 106 #include "SkString.h" 107 108 struct SkFILE; 109 110 /** A stream that reads from a FILE*, which is opened in the constructor and 111 closed in the destructor 112 */ 113 class SkFILEStream : public SkStream { 114 public: 115 /** Initialize the stream by calling fopen on the specified path. Will be 116 closed in the destructor. 117 */ 118 explicit SkFILEStream(const char path[] = NULL); 119 virtual ~SkFILEStream(); 120 121 /** Returns true if the current path could be opened. 122 */ isValid()123 bool isValid() const { return fFILE != NULL; } 124 /** Close the current file, and open a new file with the specified 125 path. If path is NULL, just close the current file. 126 */ 127 void setPath(const char path[]); 128 129 virtual bool rewind(); 130 virtual size_t read(void* buffer, size_t size); 131 virtual const char* getFileName(); 132 133 private: 134 SkFILE* fFILE; 135 SkString fName; 136 }; 137 138 /** A stream that reads from a file descriptor 139 */ 140 class SkFDStream : public SkStream { 141 public: 142 /** Initialize the stream with a dup() of the specified file descriptor. 143 If closeWhenDone is true, then the descriptor will be closed in the 144 destructor. 145 */ 146 SkFDStream(int fileDesc, bool closeWhenDone); 147 virtual ~SkFDStream(); 148 149 /** Returns true if the current path could be opened. 150 */ isValid()151 bool isValid() const { return fFD >= 0; } 152 153 virtual bool rewind(); 154 virtual size_t read(void* buffer, size_t size); getFileName()155 virtual const char* getFileName() { return NULL; } 156 157 private: 158 int fFD; 159 bool fCloseWhenDone; 160 }; 161 162 class SkMemoryStream : public SkStream { 163 public: 164 SkMemoryStream(); 165 /** We allocate (and free) the memory. Write to it via getMemoryBase() 166 */ 167 SkMemoryStream(size_t length); 168 /** if copyData is true, the stream makes a private copy of the data 169 */ 170 SkMemoryStream(const void* data, size_t length, bool copyData = false); 171 virtual ~SkMemoryStream(); 172 173 /** Resets the stream to the specified data and length, 174 just like the constructor. 175 if copyData is true, the stream makes a private copy of the data 176 */ 177 virtual void setMemory(const void* data, size_t length, 178 bool copyData = false); 179 virtual void setMemoryOwned(const void* src, size_t size); 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); peek()186 size_t peek() const { return fOffset; } 187 188 private: 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 */ 199 class SkBufferStream : public SkStream { 200 public: 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 223 private: 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 241 class SkFILEWStream : public SkWStream { 242 public: 243 SkFILEWStream(const char path[]); 244 virtual ~SkFILEWStream(); 245 246 /** Returns true if the current path could be opened. 247 */ isValid()248 bool isValid() const { return fFILE != NULL; } 249 250 virtual bool write(const void* buffer, size_t size); 251 virtual void flush(); 252 private: 253 SkFILE* fFILE; 254 }; 255 256 class SkMemoryWStream : public SkWStream { 257 public: 258 SkMemoryWStream(void* buffer, size_t size); 259 virtual bool write(const void* buffer, size_t size); 260 261 private: 262 char* fBuffer; 263 size_t fMaxLength; 264 size_t fBytesWritten; 265 }; 266 267 class SkDynamicMemoryWStream : public SkWStream { 268 public: 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); getOffset()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(); 292 private: 293 struct Block; 294 Block* fHead; 295 Block* fTail; 296 size_t fBytesWritten; 297 mutable char* fCopyToCache; 298 }; 299 300 301 class SkDebugWStream : public SkWStream { 302 public: 303 // overrides 304 virtual bool write(const void* buffer, size_t size); 305 virtual void newline(); 306 }; 307 308 // for now 309 typedef SkFILEStream SkURLStream; 310 311 #endif 312 313