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 void skipToAlign4(); 180 virtual bool rewind(); 181 virtual size_t read(void* buffer, size_t size); 182 virtual const void* getMemoryBase(); 183 const void* getAtPos(); 184 size_t seek(size_t offset); peek()185 size_t peek() const { return fOffset; } 186 187 private: 188 const void* fSrc; 189 size_t fSize, fOffset; 190 SkBool8 fWeOwnTheData; 191 }; 192 193 /** \class SkBufferStream 194 This is a wrapper class that adds buffering to another stream. 195 The caller can provide the buffer, or ask SkBufferStream to allocated/free 196 it automatically. 197 */ 198 class SkBufferStream : public SkStream { 199 public: 200 /** Provide the stream to be buffered (proxy), and the size of the buffer that 201 should be used. This will be allocated and freed automatically. If bufferSize is 0, 202 a default buffer size will be used. 203 The proxy stream is referenced, and will be unreferenced in when the 204 bufferstream is destroyed. 205 */ 206 SkBufferStream(SkStream* proxy, size_t bufferSize = 0); 207 /** Provide the stream to be buffered (proxy), and a buffer and size to be used. 208 This buffer is owned by the caller, and must be at least bufferSize bytes big. 209 Passing NULL for buffer will cause the buffer to be allocated/freed automatically. 210 If buffer is not NULL, it is an error for bufferSize to be 0. 211 The proxy stream is referenced, and will be unreferenced in when the 212 bufferstream is destroyed. 213 */ 214 SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize); 215 virtual ~SkBufferStream(); 216 217 virtual bool rewind(); 218 virtual const char* getFileName(); 219 virtual size_t read(void* buffer, size_t size); 220 virtual const void* getMemoryBase(); 221 222 private: 223 enum { 224 kDefaultBufferSize = 128 225 }; 226 // illegal 227 SkBufferStream(const SkBufferStream&); 228 SkBufferStream& operator=(const SkBufferStream&); 229 230 SkStream* fProxy; 231 char* fBuffer; 232 size_t fOrigBufferSize, fBufferSize, fBufferOffset; 233 bool fWeOwnTheBuffer; 234 235 void init(void*, size_t); 236 }; 237 238 ///////////////////////////////////////////////////////////////////////////////////////////// 239 240 class SkFILEWStream : public SkWStream { 241 public: 242 SkFILEWStream(const char path[]); 243 virtual ~SkFILEWStream(); 244 245 /** Returns true if the current path could be opened. 246 */ isValid()247 bool isValid() const { return fFILE != NULL; } 248 249 virtual bool write(const void* buffer, size_t size); 250 virtual void flush(); 251 private: 252 SkFILE* fFILE; 253 }; 254 255 class SkMemoryWStream : public SkWStream { 256 public: 257 SkMemoryWStream(void* buffer, size_t size); 258 virtual bool write(const void* buffer, size_t size); 259 260 private: 261 char* fBuffer; 262 size_t fMaxLength; 263 size_t fBytesWritten; 264 }; 265 266 class SkDynamicMemoryWStream : public SkWStream { 267 public: 268 SkDynamicMemoryWStream(); 269 virtual ~SkDynamicMemoryWStream(); 270 virtual bool write(const void* buffer, size_t size); 271 // random access write 272 // modifies stream and returns true if offset + size is less than or equal to getOffset() 273 bool write(const void* buffer, size_t offset, size_t size); 274 bool read(void* buffer, size_t offset, size_t size); getOffset()275 size_t getOffset() { return fBytesWritten; } 276 277 // copy what has been written to the stream into dst 278 void copyTo(void* dst) const; 279 /* return a cache of the flattened data returned by copyTo(). 280 This copy is only valid until the next call to write(). 281 The memory is managed by the stream class. 282 */ 283 const char* getStream() const; 284 285 // same as getStream, but additionally detach the flattened datat 286 const char* detach(); 287 288 // reset the stream to its original state 289 void reset(); 290 void padToAlign4(); 291 private: 292 struct Block; 293 Block* fHead; 294 Block* fTail; 295 size_t fBytesWritten; 296 mutable char* fCopyToCache; 297 }; 298 299 300 class SkDebugWStream : public SkWStream { 301 public: 302 // overrides 303 virtual bool write(const void* buffer, size_t size); 304 virtual void newline(); 305 }; 306 307 // for now 308 typedef SkFILEStream SkURLStream; 309 310 #endif 311 312