1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkStream.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,465 @@ 1.4 +/* 1.5 + * Copyright 2006 The Android Open Source Project 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkStream_DEFINED 1.12 +#define SkStream_DEFINED 1.13 + 1.14 +#include "SkRefCnt.h" 1.15 +#include "SkScalar.h" 1.16 + 1.17 +class SkData; 1.18 + 1.19 +class SkStream; 1.20 +class SkStreamRewindable; 1.21 +class SkStreamSeekable; 1.22 +class SkStreamAsset; 1.23 +class SkStreamMemory; 1.24 + 1.25 +/** 1.26 + * SkStream -- abstraction for a source of bytes. Subclasses can be backed by 1.27 + * memory, or a file, or something else. 1.28 + * 1.29 + * NOTE: 1.30 + * 1.31 + * Classic "streams" APIs are sort of async, in that on a request for N 1.32 + * bytes, they may return fewer than N bytes on a given call, in which case 1.33 + * the caller can "try again" to get more bytes, eventually (modulo an error) 1.34 + * receiving their total N bytes. 1.35 + * 1.36 + * Skia streams behave differently. They are effectively synchronous, and will 1.37 + * always return all N bytes of the request if possible. If they return fewer 1.38 + * (the read() call returns the number of bytes read) then that means there is 1.39 + * no more data (at EOF or hit an error). The caller should *not* call again 1.40 + * in hopes of fulfilling more of the request. 1.41 + */ 1.42 +class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt 1.43 +public: 1.44 + /** 1.45 + * Attempts to open the specified file, and return a stream to it (using 1.46 + * mmap if available). On success, the caller must call unref() on the 1.47 + * returned object. On failure, returns NULL. 1.48 + */ 1.49 + static SkStreamAsset* NewFromFile(const char path[]); 1.50 + 1.51 + SK_DECLARE_INST_COUNT(SkStream) 1.52 + 1.53 + /** Reads or skips size number of bytes. 1.54 + * If buffer == NULL, skip size bytes, return how many were skipped. 1.55 + * If buffer != NULL, copy size bytes into buffer, return how many were copied. 1.56 + * @param buffer when NULL skip size bytes, otherwise copy size bytes into buffer 1.57 + * @param size the number of bytes to skip or copy 1.58 + * @return the number of bytes actually read. 1.59 + */ 1.60 + virtual size_t read(void* buffer, size_t size) = 0; 1.61 + 1.62 + /** Skip size number of bytes. 1.63 + * @return the actual number bytes that could be skipped. 1.64 + */ 1.65 + size_t skip(size_t size) { 1.66 + return this->read(NULL, size); 1.67 + } 1.68 + 1.69 + /** Returns true when all the bytes in the stream have been read. 1.70 + * This may return true early (when there are no more bytes to be read) 1.71 + * or late (after the first unsuccessful read). 1.72 + */ 1.73 + virtual bool isAtEnd() const = 0; 1.74 + 1.75 + int8_t readS8(); 1.76 + int16_t readS16(); 1.77 + int32_t readS32(); 1.78 + 1.79 + uint8_t readU8() { return (uint8_t)this->readS8(); } 1.80 + uint16_t readU16() { return (uint16_t)this->readS16(); } 1.81 + uint32_t readU32() { return (uint32_t)this->readS32(); } 1.82 + 1.83 + bool readBool() { return this->readU8() != 0; } 1.84 + SkScalar readScalar(); 1.85 + size_t readPackedUInt(); 1.86 + 1.87 + /** 1.88 + * Reconstitute an SkData object that was written to the stream 1.89 + * using SkWStream::writeData(). 1.90 + */ 1.91 + SkData* readData(); 1.92 + 1.93 +//SkStreamRewindable 1.94 + /** Rewinds to the beginning of the stream. Returns true if the stream is known 1.95 + * to be at the beginning after this call returns. 1.96 + */ 1.97 + virtual bool rewind() { return false; } 1.98 + 1.99 + /** Duplicates this stream. If this cannot be done, returns NULL. 1.100 + * The returned stream will be positioned at the beginning of its data. 1.101 + */ 1.102 + virtual SkStreamRewindable* duplicate() const { return NULL; } 1.103 + 1.104 +//SkStreamSeekable 1.105 + /** Returns true if this stream can report it's current position. */ 1.106 + virtual bool hasPosition() const { return false; } 1.107 + /** Returns the current position in the stream. If this cannot be done, returns 0. */ 1.108 + virtual size_t getPosition() const { return 0; } 1.109 + 1.110 + /** Seeks to an absolute position in the stream. If this cannot be done, returns false. 1.111 + * If an attempt is made to seek past the end of the stream, the position will be set 1.112 + * to the end of the stream. 1.113 + */ 1.114 + virtual bool seek(size_t position) { return false; } 1.115 + 1.116 + /** Seeks to an relative offset in the stream. If this cannot be done, returns false. 1.117 + * If an attempt is made to move to a position outside the stream, the position will be set 1.118 + * to the closest point within the stream (beginning or end). 1.119 + */ 1.120 + virtual bool move(long offset) { return false; } 1.121 + 1.122 + /** Duplicates this stream. If this cannot be done, returns NULL. 1.123 + * The returned stream will be positioned the same as this stream. 1.124 + */ 1.125 + virtual SkStreamSeekable* fork() const { return NULL; } 1.126 + 1.127 +//SkStreamAsset 1.128 + /** Returns true if this stream can report it's total length. */ 1.129 + virtual bool hasLength() const { return false; } 1.130 + /** Returns the total length of the stream. If this cannot be done, returns 0. */ 1.131 + virtual size_t getLength() const { return 0; } 1.132 + 1.133 +//SkStreamMemory 1.134 + /** Returns the starting address for the data. If this cannot be done, returns NULL. */ 1.135 + //TODO: replace with virtual const SkData* getData() 1.136 + virtual const void* getMemoryBase() { return NULL; } 1.137 + 1.138 +private: 1.139 + typedef SkRefCnt INHERITED; 1.140 +}; 1.141 + 1.142 +/** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */ 1.143 +class SK_API SkStreamRewindable : public SkStream { 1.144 +public: 1.145 + virtual bool rewind() SK_OVERRIDE = 0; 1.146 + virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0; 1.147 +}; 1.148 + 1.149 +/** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */ 1.150 +class SK_API SkStreamSeekable : public SkStreamRewindable { 1.151 +public: 1.152 + virtual SkStreamSeekable* duplicate() const SK_OVERRIDE = 0; 1.153 + 1.154 + virtual bool hasPosition() const SK_OVERRIDE { return true; } 1.155 + virtual size_t getPosition() const SK_OVERRIDE = 0; 1.156 + virtual bool seek(size_t position) SK_OVERRIDE = 0; 1.157 + virtual bool move(long offset) SK_OVERRIDE = 0; 1.158 + virtual SkStreamSeekable* fork() const SK_OVERRIDE = 0; 1.159 +}; 1.160 + 1.161 +/** SkStreamAsset is a SkStreamSeekable for which getLength is required. */ 1.162 +class SK_API SkStreamAsset : public SkStreamSeekable { 1.163 +public: 1.164 + virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0; 1.165 + virtual SkStreamAsset* fork() const SK_OVERRIDE = 0; 1.166 + 1.167 + virtual bool hasLength() const SK_OVERRIDE { return true; } 1.168 + virtual size_t getLength() const SK_OVERRIDE = 0; 1.169 +}; 1.170 + 1.171 +/** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */ 1.172 +class SK_API SkStreamMemory : public SkStreamAsset { 1.173 +public: 1.174 + virtual SkStreamMemory* duplicate() const SK_OVERRIDE = 0; 1.175 + virtual SkStreamMemory* fork() const SK_OVERRIDE = 0; 1.176 + 1.177 + virtual const void* getMemoryBase() SK_OVERRIDE = 0; 1.178 +}; 1.179 + 1.180 +class SK_API SkWStream : SkNoncopyable { 1.181 +public: 1.182 + SK_DECLARE_INST_COUNT_ROOT(SkWStream) 1.183 + 1.184 + virtual ~SkWStream(); 1.185 + 1.186 + /** Called to write bytes to a SkWStream. Returns true on success 1.187 + @param buffer the address of at least size bytes to be written to the stream 1.188 + @param size The number of bytes in buffer to write to the stream 1.189 + @return true on success 1.190 + */ 1.191 + virtual bool write(const void* buffer, size_t size) = 0; 1.192 + virtual void newline(); 1.193 + virtual void flush(); 1.194 + 1.195 + virtual size_t bytesWritten() const = 0; 1.196 + 1.197 + // helpers 1.198 + 1.199 + bool write8(U8CPU); 1.200 + bool write16(U16CPU); 1.201 + bool write32(uint32_t); 1.202 + 1.203 + bool writeText(const char text[]); 1.204 + bool writeDecAsText(int32_t); 1.205 + bool writeBigDecAsText(int64_t, int minDigits = 0); 1.206 + bool writeHexAsText(uint32_t, int minDigits = 0); 1.207 + bool writeScalarAsText(SkScalar); 1.208 + 1.209 + bool writeBool(bool v) { return this->write8(v); } 1.210 + bool writeScalar(SkScalar); 1.211 + bool writePackedUInt(size_t); 1.212 + 1.213 + bool writeStream(SkStream* input, size_t length); 1.214 + 1.215 + /** 1.216 + * Append an SkData object to the stream, such that it can be read 1.217 + * out of the stream using SkStream::readData(). 1.218 + * 1.219 + * Note that the encoding method used to write the SkData object 1.220 + * to the stream may change over time. This method DOES NOT 1.221 + * just write the raw content of the SkData object to the stream. 1.222 + */ 1.223 + bool writeData(const SkData*); 1.224 + 1.225 + /** 1.226 + * This returns the number of bytes in the stream required to store 1.227 + * 'value'. 1.228 + */ 1.229 + static int SizeOfPackedUInt(size_t value); 1.230 +}; 1.231 + 1.232 +//////////////////////////////////////////////////////////////////////////////////////// 1.233 + 1.234 +#include "SkString.h" 1.235 +#include <stdio.h> 1.236 + 1.237 +struct SkFILE; 1.238 + 1.239 +/** A stream that wraps a C FILE* file stream. */ 1.240 +class SK_API SkFILEStream : public SkStreamAsset { 1.241 +public: 1.242 + SK_DECLARE_INST_COUNT(SkFILEStream) 1.243 + 1.244 + /** Initialize the stream by calling sk_fopen on the specified path. 1.245 + * This internal stream will be closed in the destructor. 1.246 + */ 1.247 + explicit SkFILEStream(const char path[] = NULL); 1.248 + 1.249 + enum Ownership { 1.250 + kCallerPasses_Ownership, 1.251 + kCallerRetains_Ownership 1.252 + }; 1.253 + /** Initialize the stream with an existing C file stream. 1.254 + * While this stream exists, it assumes exclusive access to the C file stream. 1.255 + * The C file stream will be closed in the destructor unless the caller specifies 1.256 + * kCallerRetains_Ownership. 1.257 + */ 1.258 + explicit SkFILEStream(FILE* file, Ownership ownership = kCallerPasses_Ownership); 1.259 + 1.260 + virtual ~SkFILEStream(); 1.261 + 1.262 + /** Returns true if the current path could be opened. */ 1.263 + bool isValid() const { return fFILE != NULL; } 1.264 + 1.265 + /** Close the current file, and open a new file with the specified path. 1.266 + * If path is NULL, just close the current file. 1.267 + */ 1.268 + void setPath(const char path[]); 1.269 + 1.270 + virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; 1.271 + virtual bool isAtEnd() const SK_OVERRIDE; 1.272 + 1.273 + virtual bool rewind() SK_OVERRIDE; 1.274 + virtual SkStreamAsset* duplicate() const SK_OVERRIDE; 1.275 + 1.276 + virtual size_t getPosition() const SK_OVERRIDE; 1.277 + virtual bool seek(size_t position) SK_OVERRIDE; 1.278 + virtual bool move(long offset) SK_OVERRIDE; 1.279 + virtual SkStreamAsset* fork() const SK_OVERRIDE; 1.280 + 1.281 + virtual size_t getLength() const SK_OVERRIDE; 1.282 + 1.283 + virtual const void* getMemoryBase() SK_OVERRIDE; 1.284 + 1.285 +private: 1.286 + SkFILE* fFILE; 1.287 + SkString fName; 1.288 + Ownership fOwnership; 1.289 + // fData is lazilly initialized when needed. 1.290 + mutable SkAutoTUnref<SkData> fData; 1.291 + 1.292 + typedef SkStreamAsset INHERITED; 1.293 +}; 1.294 + 1.295 +class SK_API SkMemoryStream : public SkStreamMemory { 1.296 +public: 1.297 + SK_DECLARE_INST_COUNT(SkMemoryStream) 1.298 + 1.299 + SkMemoryStream(); 1.300 + 1.301 + /** We allocate (and free) the memory. Write to it via getMemoryBase() */ 1.302 + SkMemoryStream(size_t length); 1.303 + 1.304 + /** If copyData is true, the stream makes a private copy of the data. */ 1.305 + SkMemoryStream(const void* data, size_t length, bool copyData = false); 1.306 + 1.307 + /** Use the specified data as the memory for this stream. 1.308 + * The stream will call ref() on the data (assuming it is not NULL). 1.309 + */ 1.310 + SkMemoryStream(SkData*); 1.311 + 1.312 + virtual ~SkMemoryStream(); 1.313 + 1.314 + /** Resets the stream to the specified data and length, 1.315 + just like the constructor. 1.316 + if copyData is true, the stream makes a private copy of the data 1.317 + */ 1.318 + virtual void setMemory(const void* data, size_t length, 1.319 + bool copyData = false); 1.320 + /** Replace any memory buffer with the specified buffer. The caller 1.321 + must have allocated data with sk_malloc or sk_realloc, since it 1.322 + will be freed with sk_free. 1.323 + */ 1.324 + void setMemoryOwned(const void* data, size_t length); 1.325 + 1.326 + /** Return the stream's data in a SkData. 1.327 + * The caller must call unref() when it is finished using the data. 1.328 + */ 1.329 + SkData* copyToData() const; 1.330 + 1.331 + /** 1.332 + * Use the specified data as the memory for this stream. 1.333 + * The stream will call ref() on the data (assuming it is not NULL). 1.334 + * The function returns the data parameter as a convenience. 1.335 + */ 1.336 + SkData* setData(SkData*); 1.337 + 1.338 + void skipToAlign4(); 1.339 + const void* getAtPos(); 1.340 + size_t peek() const { return fOffset; } 1.341 + 1.342 + virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; 1.343 + virtual bool isAtEnd() const SK_OVERRIDE; 1.344 + 1.345 + virtual bool rewind() SK_OVERRIDE; 1.346 + virtual SkMemoryStream* duplicate() const SK_OVERRIDE; 1.347 + 1.348 + virtual size_t getPosition() const SK_OVERRIDE; 1.349 + virtual bool seek(size_t position) SK_OVERRIDE; 1.350 + virtual bool move(long offset) SK_OVERRIDE; 1.351 + virtual SkMemoryStream* fork() const SK_OVERRIDE; 1.352 + 1.353 + virtual size_t getLength() const SK_OVERRIDE; 1.354 + 1.355 + virtual const void* getMemoryBase() SK_OVERRIDE; 1.356 + 1.357 +private: 1.358 + SkData* fData; 1.359 + size_t fOffset; 1.360 + 1.361 + typedef SkStreamMemory INHERITED; 1.362 +}; 1.363 + 1.364 +///////////////////////////////////////////////////////////////////////////////////////////// 1.365 + 1.366 +class SK_API SkFILEWStream : public SkWStream { 1.367 +public: 1.368 + SK_DECLARE_INST_COUNT(SkFILEWStream) 1.369 + 1.370 + SkFILEWStream(const char path[]); 1.371 + virtual ~SkFILEWStream(); 1.372 + 1.373 + /** Returns true if the current path could be opened. 1.374 + */ 1.375 + bool isValid() const { return fFILE != NULL; } 1.376 + 1.377 + virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; 1.378 + virtual void flush() SK_OVERRIDE; 1.379 + virtual size_t bytesWritten() const SK_OVERRIDE; 1.380 + 1.381 +private: 1.382 + SkFILE* fFILE; 1.383 + 1.384 + typedef SkWStream INHERITED; 1.385 +}; 1.386 + 1.387 +class SkMemoryWStream : public SkWStream { 1.388 +public: 1.389 + SK_DECLARE_INST_COUNT(SkMemoryWStream) 1.390 + 1.391 + SkMemoryWStream(void* buffer, size_t size); 1.392 + virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; 1.393 + virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } 1.394 + 1.395 +private: 1.396 + char* fBuffer; 1.397 + size_t fMaxLength; 1.398 + size_t fBytesWritten; 1.399 + 1.400 + typedef SkWStream INHERITED; 1.401 +}; 1.402 + 1.403 +class SK_API SkDynamicMemoryWStream : public SkWStream { 1.404 +public: 1.405 + SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream) 1.406 + 1.407 + SkDynamicMemoryWStream(); 1.408 + virtual ~SkDynamicMemoryWStream(); 1.409 + 1.410 + virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; 1.411 + virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } 1.412 + // random access write 1.413 + // modifies stream and returns true if offset + size is less than or equal to getOffset() 1.414 + bool write(const void* buffer, size_t offset, size_t size); 1.415 + bool read(void* buffer, size_t offset, size_t size); 1.416 + size_t getOffset() const { return fBytesWritten; } 1.417 + 1.418 + // copy what has been written to the stream into dst 1.419 + void copyTo(void* dst) const; 1.420 + 1.421 + /** 1.422 + * Return a copy of the data written so far. This call is responsible for 1.423 + * calling unref() when they are finished with the data. 1.424 + */ 1.425 + SkData* copyToData() const; 1.426 + 1.427 + /** Reset, returning a reader stream with the current content. */ 1.428 + SkStreamAsset* detachAsStream(); 1.429 + 1.430 + /** Reset the stream to its original, empty, state. */ 1.431 + void reset(); 1.432 + void padToAlign4(); 1.433 +private: 1.434 + struct Block; 1.435 + Block* fHead; 1.436 + Block* fTail; 1.437 + size_t fBytesWritten; 1.438 + mutable SkData* fCopy; // is invalidated if we write after it is created 1.439 + 1.440 + void invalidateCopy(); 1.441 + 1.442 + // For access to the Block type. 1.443 + friend class SkBlockMemoryStream; 1.444 + friend class SkBlockMemoryRefCnt; 1.445 + 1.446 + typedef SkWStream INHERITED; 1.447 +}; 1.448 + 1.449 + 1.450 +class SK_API SkDebugWStream : public SkWStream { 1.451 +public: 1.452 + SkDebugWStream() : fBytesWritten(0) {} 1.453 + SK_DECLARE_INST_COUNT(SkDebugWStream) 1.454 + 1.455 + // overrides 1.456 + virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; 1.457 + virtual void newline() SK_OVERRIDE; 1.458 + virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } 1.459 + 1.460 +private: 1.461 + size_t fBytesWritten; 1.462 + typedef SkWStream INHERITED; 1.463 +}; 1.464 + 1.465 +// for now 1.466 +typedef SkFILEStream SkURLStream; 1.467 + 1.468 +#endif