Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkStream_DEFINED
      9 #define SkStream_DEFINED
     10 
     11 #include "SkRefCnt.h"
     12 #include "SkScalar.h"
     13 
     14 class SkData;
     15 
     16 class SkStream;
     17 class SkStreamRewindable;
     18 class SkStreamSeekable;
     19 class SkStreamAsset;
     20 class SkStreamMemory;
     21 
     22 /**
     23  *  SkStream -- abstraction for a source of bytes. Subclasses can be backed by
     24  *  memory, or a file, or something else.
     25  *
     26  *  NOTE:
     27  *
     28  *  Classic "streams" APIs are sort of async, in that on a request for N
     29  *  bytes, they may return fewer than N bytes on a given call, in which case
     30  *  the caller can "try again" to get more bytes, eventually (modulo an error)
     31  *  receiving their total N bytes.
     32  *
     33  *  Skia streams behave differently. They are effectively synchronous, and will
     34  *  always return all N bytes of the request if possible. If they return fewer
     35  *  (the read() call returns the number of bytes read) then that means there is
     36  *  no more data (at EOF or hit an error). The caller should *not* call again
     37  *  in hopes of fulfilling more of the request.
     38  */
     39 class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt
     40 public:
     41     /**
     42      *  Attempts to open the specified file, and return a stream to it (using
     43      *  mmap if available). On success, the caller must call unref() on the
     44      *  returned object. On failure, returns NULL.
     45      */
     46     static SkStreamAsset* NewFromFile(const char path[]);
     47 
     48     SK_DECLARE_INST_COUNT(SkStream)
     49 
     50     /** Reads or skips size number of bytes.
     51      *  If buffer == NULL, skip size bytes, return how many were skipped.
     52      *  If buffer != NULL, copy size bytes into buffer, return how many were copied.
     53      *  @param buffer when NULL skip size bytes, otherwise copy size bytes into buffer
     54      *  @param size the number of bytes to skip or copy
     55      *  @return the number of bytes actually read.
     56      */
     57     virtual size_t read(void* buffer, size_t size) = 0;
     58 
     59     /** Skip size number of bytes.
     60      *  @return the actual number bytes that could be skipped.
     61      */
     62     size_t skip(size_t size) {
     63         //return this->read(NULL, size);
     64         //TODO: remove this old logic after updating existing implementations
     65         return 0 == size ? 0 : this->read(NULL, size);
     66     }
     67 
     68     /** Returns true when all the bytes in the stream have been read.
     69      *  This may return true early (when there are no more bytes to be read)
     70      *  or late (after the first unsuccessful read).
     71      *
     72      *  In Progress: do not use until all implementations are updated.
     73      *  TODO: after this is implemented everywhere, make pure virtual.
     74      */
     75     virtual bool isAtEnd() const {
     76         SkASSERT(false);
     77         return true;
     78     }
     79 
     80     int8_t   readS8();
     81     int16_t  readS16();
     82     int32_t  readS32();
     83 
     84     uint8_t  readU8() { return (uint8_t)this->readS8(); }
     85     uint16_t readU16() { return (uint16_t)this->readS16(); }
     86     uint32_t readU32() { return (uint32_t)this->readS32(); }
     87 
     88     bool     readBool() { return this->readU8() != 0; }
     89     SkScalar readScalar();
     90     size_t   readPackedUInt();
     91 
     92     /**
     93      *  Reconstitute an SkData object that was written to the stream
     94      *  using SkWStream::writeData().
     95      */
     96     SkData* readData();
     97 
     98 //SkStreamRewindable
     99     /** Rewinds to the beginning of the stream. If this cannot be done, return false. */
    100     virtual bool rewind() { return false; }
    101 
    102     /** Duplicates this stream. If this cannot be done, returns NULL.
    103      *  The returned stream will be positioned at the beginning of its data.
    104      */
    105     virtual SkStreamRewindable* duplicate() const { return NULL; }
    106 
    107 //SkStreamSeekable
    108     /** Returns true if this stream can report it's current position. */
    109     virtual bool hasPosition() const { return false; }
    110     /** Returns the current position in the stream. If this cannot be done, returns 0. */
    111     virtual size_t getPosition() const { return 0; }
    112 
    113     /** Seeks to an absolute position in the stream. If this cannot be done, returns false.
    114      *  If an attempt is made to seek past the end of the stream, the position will be set
    115      *  to the end of the stream.
    116      */
    117     virtual bool seek(size_t position) { return false; }
    118 
    119     /** Seeks to an relative offset in the stream. If this cannot be done, returns false.
    120      *  If an attempt is made to move to a position outside the stream, the position will be set
    121      *  to the closest point within the stream (beginning or end).
    122      */
    123     virtual bool move(long offset) { return false; }
    124 
    125     /** Duplicates this stream. If this cannot be done, returns NULL.
    126      *  The returned stream will be positioned the same as this stream.
    127      */
    128     virtual SkStreamSeekable* fork() const { return NULL; }
    129 
    130 //SkStreamAsset
    131     /** Returns true if this stream can report it's total length. */
    132     virtual bool hasLength() const { return false; }
    133     /** Returns the total length of the stream. If this cannot be done, returns 0. */
    134     virtual size_t getLength() const {
    135         //return 0;
    136         //TODO: remove the following after everyone is updated.
    137         return ((SkStream*)this)->read(NULL, 0);
    138     }
    139 
    140 //SkStreamMemory
    141     /** Returns the starting address for the data. If this cannot be done, returns NULL. */
    142     //TODO: replace with virtual const SkData* getData()
    143     virtual const void* getMemoryBase() { return NULL; }
    144 
    145 private:
    146     typedef SkRefCnt INHERITED;
    147 };
    148 
    149 /** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */
    150 class SK_API SkStreamRewindable : public SkStream {
    151 public:
    152     //TODO: remove the following after everyone is updated (ensures new behavior on new classes).
    153     virtual bool isAtEnd() const SK_OVERRIDE = 0;
    154     //TODO: remove the following after everyone is updated (ensures new behavior on new classes).
    155     virtual size_t getLength() const SK_OVERRIDE { return 0; }
    156 
    157     virtual bool rewind() SK_OVERRIDE = 0;
    158     virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0;
    159 };
    160 
    161 /** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */
    162 class SK_API SkStreamSeekable : public SkStreamRewindable {
    163 public:
    164     virtual SkStreamSeekable* duplicate() const SK_OVERRIDE = 0;
    165 
    166     virtual bool hasPosition() const SK_OVERRIDE { return true; }
    167     virtual size_t getPosition() const SK_OVERRIDE = 0;
    168     virtual bool seek(size_t position) SK_OVERRIDE = 0;
    169     virtual bool move(long offset) SK_OVERRIDE = 0;
    170     virtual SkStreamSeekable* fork() const SK_OVERRIDE = 0;
    171 };
    172 
    173 /** SkStreamAsset is a SkStreamSeekable for which getLength is required. */
    174 class SK_API SkStreamAsset : public SkStreamSeekable {
    175 public:
    176     virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0;
    177     virtual SkStreamAsset* fork() const SK_OVERRIDE = 0;
    178 
    179     virtual bool hasLength() const SK_OVERRIDE { return true; }
    180     virtual size_t getLength() const SK_OVERRIDE = 0;
    181 };
    182 
    183 /** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */
    184 class SK_API SkStreamMemory : public SkStreamAsset {
    185 public:
    186     virtual SkStreamMemory* duplicate() const SK_OVERRIDE = 0;
    187     virtual SkStreamMemory* fork() const SK_OVERRIDE = 0;
    188 
    189     virtual const void* getMemoryBase() SK_OVERRIDE = 0;
    190 };
    191 
    192 class SK_API SkWStream : SkNoncopyable {
    193 public:
    194     SK_DECLARE_INST_COUNT_ROOT(SkWStream)
    195 
    196     virtual ~SkWStream();
    197 
    198     /** Called to write bytes to a SkWStream. Returns true on success
    199         @param buffer the address of at least size bytes to be written to the stream
    200         @param size The number of bytes in buffer to write to the stream
    201         @return true on success
    202     */
    203     virtual bool write(const void* buffer, size_t size) = 0;
    204     virtual void newline();
    205     virtual void flush();
    206 
    207     // helpers
    208 
    209     bool    write8(U8CPU);
    210     bool    write16(U16CPU);
    211     bool    write32(uint32_t);
    212 
    213     bool    writeText(const char text[]);
    214     bool    writeDecAsText(int32_t);
    215     bool    writeBigDecAsText(int64_t, int minDigits = 0);
    216     bool    writeHexAsText(uint32_t, int minDigits = 0);
    217     bool    writeScalarAsText(SkScalar);
    218 
    219     bool    writeBool(bool v) { return this->write8(v); }
    220     bool    writeScalar(SkScalar);
    221     bool    writePackedUInt(size_t);
    222 
    223     bool writeStream(SkStream* input, size_t length);
    224 
    225     /**
    226      * Append an SkData object to the stream, such that it can be read
    227      * out of the stream using SkStream::readData().
    228      *
    229      * Note that the encoding method used to write the SkData object
    230      * to the stream may change over time.  This method DOES NOT
    231      * just write the raw content of the SkData object to the stream.
    232      */
    233     bool writeData(const SkData*);
    234 };
    235 
    236 ////////////////////////////////////////////////////////////////////////////////////////
    237 
    238 #include "SkString.h"
    239 
    240 struct SkFILE;
    241 
    242 /** A stream that wraps a C FILE* file stream. */
    243 class SK_API SkFILEStream : public SkStreamAsset {
    244 public:
    245     SK_DECLARE_INST_COUNT(SkFILEStream)
    246 
    247     /** Initialize the stream by calling sk_fopen on the specified path.
    248      *  This internal stream will be closed in the destructor.
    249      */
    250     explicit SkFILEStream(const char path[] = NULL);
    251 
    252     enum Ownership {
    253         kCallerPasses_Ownership,
    254         kCallerRetains_Ownership
    255     };
    256     /** Initialize the stream with an existing C file stream.
    257      *  While this stream exists, it assumes exclusive access to the C file stream.
    258      *  The C file stream will be closed in the destructor unless the caller specifies
    259      *  kCallerRetains_Ownership.
    260      */
    261     explicit SkFILEStream(FILE* file, Ownership ownership = kCallerPasses_Ownership);
    262 
    263     virtual ~SkFILEStream();
    264 
    265     /** Returns true if the current path could be opened. */
    266     bool isValid() const { return fFILE != NULL; }
    267 
    268     /** Close the current file, and open a new file with the specified path.
    269      *  If path is NULL, just close the current file.
    270      */
    271     void setPath(const char path[]);
    272 
    273     virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    274     virtual bool isAtEnd() const SK_OVERRIDE;
    275 
    276     virtual bool rewind() SK_OVERRIDE;
    277     virtual SkStreamAsset* duplicate() const SK_OVERRIDE;
    278 
    279     virtual size_t getPosition() const SK_OVERRIDE;
    280     virtual bool seek(size_t position) SK_OVERRIDE;
    281     virtual bool move(long offset) SK_OVERRIDE;
    282     virtual SkStreamAsset* fork() const SK_OVERRIDE;
    283 
    284     virtual size_t getLength() const SK_OVERRIDE;
    285 
    286     virtual const void* getMemoryBase() SK_OVERRIDE;
    287 
    288 private:
    289     SkFILE*     fFILE;
    290     SkString    fName;
    291     Ownership   fOwnership;
    292     // fData is lazilly initialized when needed.
    293     mutable SkAutoTUnref<SkData> fData;
    294 
    295     typedef SkStreamAsset INHERITED;
    296 };
    297 
    298 class SK_API SkMemoryStream : public SkStreamMemory {
    299 public:
    300     SK_DECLARE_INST_COUNT(SkMemoryStream)
    301 
    302     SkMemoryStream();
    303 
    304     /** We allocate (and free) the memory. Write to it via getMemoryBase() */
    305     SkMemoryStream(size_t length);
    306 
    307     /** If copyData is true, the stream makes a private copy of the data. */
    308     SkMemoryStream(const void* data, size_t length, bool copyData = false);
    309 
    310     /** Use the specified data as the memory for this stream.
    311      *  The stream will call ref() on the data (assuming it is not NULL).
    312      */
    313     SkMemoryStream(SkData*);
    314 
    315     virtual ~SkMemoryStream();
    316 
    317     /** Resets the stream to the specified data and length,
    318         just like the constructor.
    319         if copyData is true, the stream makes a private copy of the data
    320     */
    321     virtual void setMemory(const void* data, size_t length,
    322                            bool copyData = false);
    323     /** Replace any memory buffer with the specified buffer. The caller
    324         must have allocated data with sk_malloc or sk_realloc, since it
    325         will be freed with sk_free.
    326     */
    327     void setMemoryOwned(const void* data, size_t length);
    328 
    329     /** Return the stream's data in a SkData.
    330      *  The caller must call unref() when it is finished using the data.
    331      */
    332     SkData* copyToData() const;
    333 
    334     /**
    335      *  Use the specified data as the memory for this stream.
    336      *  The stream will call ref() on the data (assuming it is not NULL).
    337      *  The function returns the data parameter as a convenience.
    338      */
    339     SkData* setData(SkData*);
    340 
    341     void skipToAlign4();
    342     const void* getAtPos();
    343     size_t peek() const { return fOffset; }
    344 
    345     virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    346     virtual bool isAtEnd() const SK_OVERRIDE;
    347 
    348     virtual bool rewind() SK_OVERRIDE;
    349     virtual SkMemoryStream* duplicate() const SK_OVERRIDE;
    350 
    351     virtual size_t getPosition() const SK_OVERRIDE;
    352     virtual bool seek(size_t position) SK_OVERRIDE;
    353     virtual bool move(long offset) SK_OVERRIDE;
    354     virtual SkMemoryStream* fork() const SK_OVERRIDE;
    355 
    356     virtual size_t getLength() const SK_OVERRIDE;
    357 
    358     virtual const void* getMemoryBase() SK_OVERRIDE;
    359 
    360 private:
    361     SkData* fData;
    362     size_t  fOffset;
    363 
    364     typedef SkStreamMemory INHERITED;
    365 };
    366 
    367 /////////////////////////////////////////////////////////////////////////////////////////////
    368 
    369 class SK_API SkFILEWStream : public SkWStream {
    370 public:
    371     SK_DECLARE_INST_COUNT(SkFILEWStream)
    372 
    373     SkFILEWStream(const char path[]);
    374     virtual ~SkFILEWStream();
    375 
    376     /** Returns true if the current path could be opened.
    377     */
    378     bool isValid() const { return fFILE != NULL; }
    379 
    380     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    381     virtual void flush() SK_OVERRIDE;
    382 
    383 private:
    384     SkFILE* fFILE;
    385 
    386     typedef SkWStream INHERITED;
    387 };
    388 
    389 class SkMemoryWStream : public SkWStream {
    390 public:
    391     SK_DECLARE_INST_COUNT(SkMemoryWStream)
    392 
    393     SkMemoryWStream(void* buffer, size_t size);
    394     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    395     size_t bytesWritten() const { return fBytesWritten; }
    396 
    397 private:
    398     char*   fBuffer;
    399     size_t  fMaxLength;
    400     size_t  fBytesWritten;
    401 
    402     typedef SkWStream INHERITED;
    403 };
    404 
    405 class SK_API SkDynamicMemoryWStream : public SkWStream {
    406 public:
    407     SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream)
    408 
    409     SkDynamicMemoryWStream();
    410     virtual ~SkDynamicMemoryWStream();
    411 
    412     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    413     // random access write
    414     // modifies stream and returns true if offset + size is less than or equal to getOffset()
    415     bool write(const void* buffer, size_t offset, size_t size);
    416     bool read(void* buffer, size_t offset, size_t size);
    417     size_t getOffset() const { return fBytesWritten; }
    418     size_t bytesWritten() const { return fBytesWritten; }
    419 
    420     // copy what has been written to the stream into dst
    421     void copyTo(void* dst) const;
    422 
    423     /**
    424      *  Return a copy of the data written so far. This call is responsible for
    425      *  calling unref() when they are finished with the data.
    426      */
    427     SkData* copyToData() const;
    428 
    429     /** Reset, returning a reader stream with the current content. */
    430     SkStreamAsset* detachAsStream();
    431 
    432     /** Reset the stream to its original, empty, state. */
    433     void reset();
    434     void padToAlign4();
    435 private:
    436     struct Block;
    437     Block*  fHead;
    438     Block*  fTail;
    439     size_t  fBytesWritten;
    440     mutable SkData* fCopy;  // is invalidated if we write after it is created
    441 
    442     void invalidateCopy();
    443 
    444     // For access to the Block type.
    445     friend class SkBlockMemoryStream;
    446     friend class SkBlockMemoryRefCnt;
    447 
    448     typedef SkWStream INHERITED;
    449 };
    450 
    451 
    452 class SK_API SkDebugWStream : public SkWStream {
    453 public:
    454     SK_DECLARE_INST_COUNT(SkDebugWStream)
    455 
    456     // overrides
    457     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    458     virtual void newline() SK_OVERRIDE;
    459 
    460 private:
    461     typedef SkWStream INHERITED;
    462 };
    463 
    464 // for now
    465 typedef SkFILEStream SkURLStream;
    466 
    467 #endif
    468