Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkStream_DEFINED
     11 #define SkStream_DEFINED
     12 
     13 #include "SkRefCnt.h"
     14 #include "SkScalar.h"
     15 
     16 class SkData;
     17 
     18 class SK_API SkStream : public SkRefCnt {
     19 public:
     20     SK_DECLARE_INST_COUNT(SkStream)
     21 
     22     /** Called to rewind to the beginning of the stream. If this cannot be
     23         done, return false.
     24     */
     25     virtual bool rewind() = 0;
     26     /** If this stream represents a file, this method returns the file's name.
     27         If it does not, it returns NULL (the default behavior).
     28     */
     29     virtual const char* getFileName();
     30     /** Called to read or skip size number of bytes.
     31         If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
     32         If buffer is NULL and size == 0, return the total length of the stream.
     33         If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
     34         @param buffer   If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
     35         @param size The number of bytes to skip or copy
     36         @return bytes read on success
     37     */
     38     virtual size_t read(void* buffer, size_t size) = 0;
     39 
     40     /** Return the total length of the stream.
     41     */
     42     size_t getLength() { return this->read(NULL, 0); }
     43 
     44     /** Skip the specified number of bytes, returning the actual number
     45         of bytes that could be skipped.
     46     */
     47     size_t skip(size_t bytes);
     48 
     49     /** If the stream is backed by RAM, this method returns the starting
     50         address for the data. If not (i.e. it is backed by a file or other
     51         structure), this method returns NULL.
     52         The default implementation returns NULL.
     53     */
     54     virtual const void* getMemoryBase();
     55 
     56     int8_t   readS8();
     57     int16_t  readS16();
     58     int32_t  readS32();
     59 
     60     uint8_t  readU8() { return (uint8_t)this->readS8(); }
     61     uint16_t readU16() { return (uint16_t)this->readS16(); }
     62     uint32_t readU32() { return (uint32_t)this->readS32(); }
     63 
     64     bool     readBool() { return this->readU8() != 0; }
     65     SkScalar readScalar();
     66     size_t   readPackedUInt();
     67 
     68     /**
     69      *  Create a new SkData from the stream contents. This balances the call
     70      *  SkWStream::writeData().
     71      */
     72     SkData* readData();
     73 
     74 private:
     75     typedef SkRefCnt INHERITED;
     76 };
     77 
     78 class SK_API SkWStream : SkNoncopyable {
     79 public:
     80     SK_DECLARE_INST_COUNT_ROOT(SkWStream)
     81 
     82     virtual ~SkWStream();
     83 
     84     /** Called to write bytes to a SkWStream. Returns true on success
     85         @param buffer the address of at least size bytes to be written to the stream
     86         @param size The number of bytes in buffer to write to the stream
     87         @return true on success
     88     */
     89     virtual bool write(const void* buffer, size_t size) = 0;
     90     virtual void newline();
     91     virtual void flush();
     92 
     93     // helpers
     94 
     95     bool    write8(U8CPU);
     96     bool    write16(U16CPU);
     97     bool    write32(uint32_t);
     98 
     99     bool    writeText(const char text[]);
    100     bool    writeDecAsText(int32_t);
    101     bool    writeBigDecAsText(int64_t, int minDigits = 0);
    102     bool    writeHexAsText(uint32_t, int minDigits = 0);
    103     bool    writeScalarAsText(SkScalar);
    104 
    105     bool    writeBool(bool v) { return this->write8(v); }
    106     bool    writeScalar(SkScalar);
    107     bool    writePackedUInt(size_t);
    108 
    109     bool writeStream(SkStream* input, size_t length);
    110 
    111     bool writeData(const SkData*);
    112 };
    113 
    114 ////////////////////////////////////////////////////////////////////////////////////////
    115 
    116 #include "SkString.h"
    117 
    118 struct SkFILE;
    119 
    120 /** A stream that reads from a FILE*, which is opened in the constructor and
    121     closed in the destructor
    122  */
    123 class SkFILEStream : public SkStream {
    124 public:
    125     SK_DECLARE_INST_COUNT(SkFILEStream)
    126 
    127     /** Initialize the stream by calling fopen on the specified path. Will be
    128         closed in the destructor.
    129      */
    130     explicit SkFILEStream(const char path[] = NULL);
    131     virtual ~SkFILEStream();
    132 
    133     /** Returns true if the current path could be opened.
    134     */
    135     bool isValid() const { return fFILE != NULL; }
    136     /** Close the current file, and open a new file with the specified
    137         path. If path is NULL, just close the current file.
    138     */
    139     void setPath(const char path[]);
    140 
    141     virtual bool rewind() SK_OVERRIDE;
    142     virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    143     virtual const char* getFileName() SK_OVERRIDE;
    144 
    145 private:
    146     SkFILE*     fFILE;
    147     SkString    fName;
    148 
    149     typedef SkStream INHERITED;
    150 };
    151 
    152 /** A stream that reads from a file descriptor
    153  */
    154 class SkFDStream : public SkStream {
    155 public:
    156     SK_DECLARE_INST_COUNT(SkFDStream)
    157 
    158     /** Initialize the stream with a dup() of the specified file descriptor.
    159         If closeWhenDone is true, then the descriptor will be closed in the
    160         destructor.
    161      */
    162     SkFDStream(int fileDesc, bool closeWhenDone);
    163     virtual ~SkFDStream();
    164 
    165     /** Returns true if the current path could be opened.
    166      */
    167     bool isValid() const { return fFD >= 0; }
    168 
    169     virtual bool rewind() SK_OVERRIDE;
    170     virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    171     virtual const char* getFileName() SK_OVERRIDE { return NULL; }
    172 
    173 private:
    174     int     fFD;
    175     bool    fCloseWhenDone;
    176 
    177     typedef SkStream INHERITED;
    178 };
    179 
    180 class SkMemoryStream : public SkStream {
    181 public:
    182     SK_DECLARE_INST_COUNT(SkMemoryStream)
    183 
    184     SkMemoryStream();
    185     /** We allocate (and free) the memory. Write to it via getMemoryBase()
    186     */
    187     SkMemoryStream(size_t length);
    188     /** if copyData is true, the stream makes a private copy of the data
    189     */
    190     SkMemoryStream(const void* data, size_t length, bool copyData = false);
    191 
    192     /**
    193      *  Use the specified data as the memory for this stream. The stream will
    194      *  call ref() on the data (assuming it is not null).
    195      */
    196     SkMemoryStream(SkData*);
    197 
    198     virtual ~SkMemoryStream();
    199 
    200     /** Resets the stream to the specified data and length,
    201         just like the constructor.
    202         if copyData is true, the stream makes a private copy of the data
    203     */
    204     virtual void setMemory(const void* data, size_t length,
    205                            bool copyData = false);
    206     /** Replace any memory buffer with the specified buffer. The caller
    207         must have allocated data with sk_malloc or sk_realloc, since it
    208         will be freed with sk_free.
    209     */
    210     void setMemoryOwned(const void* data, size_t length);
    211 
    212     /**
    213      *  Return the stream's data in a SkData. The caller must call unref() when
    214      *  it is finished using the data.
    215      */
    216     SkData* copyToData() const;
    217 
    218     /**
    219      *  Use the specified data as the memory for this stream. The stream will
    220      *  call ref() on the data (assuming it is not null). The function returns
    221      *  the data parameter as a convenience.
    222      */
    223     SkData* setData(SkData*);
    224 
    225     void skipToAlign4();
    226     virtual bool rewind() SK_OVERRIDE;
    227     virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
    228     virtual const void* getMemoryBase() SK_OVERRIDE;
    229     const void* getAtPos();
    230     size_t seek(size_t offset);
    231     size_t peek() const { return fOffset; }
    232 
    233 private:
    234     SkData* fData;
    235     size_t  fOffset;
    236 
    237     typedef SkStream INHERITED;
    238 };
    239 
    240 /** \class SkBufferStream
    241     This is a wrapper class that adds buffering to another stream.
    242     The caller can provide the buffer, or ask SkBufferStream to allocated/free
    243     it automatically.
    244 */
    245 class SkBufferStream : public SkStream {
    246 public:
    247     SK_DECLARE_INST_COUNT(SkBufferStream)
    248 
    249     /** Provide the stream to be buffered (proxy), and the size of the buffer that
    250         should be used. This will be allocated and freed automatically. If bufferSize is 0,
    251         a default buffer size will be used.
    252         The proxy stream is referenced, and will be unreferenced in when the
    253         bufferstream is destroyed.
    254     */
    255     SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
    256     /** Provide the stream to be buffered (proxy), and a buffer and size to be used.
    257         This buffer is owned by the caller, and must be at least bufferSize bytes big.
    258         Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
    259         If buffer is not NULL, it is an error for bufferSize to be 0.
    260      The proxy stream is referenced, and will be unreferenced in when the
    261      bufferstream is destroyed.
    262     */
    263     SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
    264     virtual ~SkBufferStream();
    265 
    266     virtual bool        rewind() SK_OVERRIDE;
    267     virtual const char* getFileName() SK_OVERRIDE;
    268     virtual size_t      read(void* buffer, size_t size) SK_OVERRIDE;
    269     virtual const void* getMemoryBase() SK_OVERRIDE;
    270 
    271 private:
    272     enum {
    273         kDefaultBufferSize  = 128
    274     };
    275     // illegal
    276     SkBufferStream(const SkBufferStream&);
    277     SkBufferStream& operator=(const SkBufferStream&);
    278 
    279     SkStream*   fProxy;
    280     char*       fBuffer;
    281     size_t      fOrigBufferSize, fBufferSize, fBufferOffset;
    282     bool        fWeOwnTheBuffer;
    283 
    284     void    init(void*, size_t);
    285 
    286     typedef SkStream INHERITED;
    287 };
    288 
    289 /////////////////////////////////////////////////////////////////////////////////////////////
    290 
    291 class SK_API SkFILEWStream : public SkWStream {
    292 public:
    293     SK_DECLARE_INST_COUNT(SkFILEWStream)
    294 
    295     SkFILEWStream(const char path[]);
    296     virtual ~SkFILEWStream();
    297 
    298     /** Returns true if the current path could be opened.
    299     */
    300     bool isValid() const { return fFILE != NULL; }
    301 
    302     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    303     virtual void flush() SK_OVERRIDE;
    304 
    305 private:
    306     SkFILE* fFILE;
    307 
    308     typedef SkWStream INHERITED;
    309 };
    310 
    311 class SkMemoryWStream : public SkWStream {
    312 public:
    313     SK_DECLARE_INST_COUNT(SkMemoryWStream)
    314 
    315     SkMemoryWStream(void* buffer, size_t size);
    316     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    317     size_t bytesWritten() const { return fBytesWritten; }
    318 
    319 private:
    320     char*   fBuffer;
    321     size_t  fMaxLength;
    322     size_t  fBytesWritten;
    323 
    324     typedef SkWStream INHERITED;
    325 };
    326 
    327 class SK_API SkDynamicMemoryWStream : public SkWStream {
    328 public:
    329     SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream)
    330 
    331     SkDynamicMemoryWStream();
    332     virtual ~SkDynamicMemoryWStream();
    333 
    334     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    335     // random access write
    336     // modifies stream and returns true if offset + size is less than or equal to getOffset()
    337     bool write(const void* buffer, size_t offset, size_t size);
    338     bool read(void* buffer, size_t offset, size_t size);
    339     size_t getOffset() const { return fBytesWritten; }
    340     size_t bytesWritten() const { return fBytesWritten; }
    341 
    342     // copy what has been written to the stream into dst
    343     void copyTo(void* dst) const;
    344 
    345     /**
    346      *  Return a copy of the data written so far. This call is responsible for
    347      *  calling unref() when they are finished with the data.
    348      */
    349     SkData* copyToData() const;
    350 
    351     // reset the stream to its original state
    352     void reset();
    353     void padToAlign4();
    354 private:
    355     struct Block;
    356     Block*  fHead;
    357     Block*  fTail;
    358     size_t  fBytesWritten;
    359     mutable SkData* fCopy;  // is invalidated if we write after it is created
    360 
    361     void invalidateCopy();
    362 
    363     typedef SkWStream INHERITED;
    364 };
    365 
    366 
    367 class SkDebugWStream : public SkWStream {
    368 public:
    369     SK_DECLARE_INST_COUNT(SkDebugWStream)
    370 
    371     // overrides
    372     virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
    373     virtual void newline() SK_OVERRIDE;
    374 
    375 private:
    376     typedef SkWStream INHERITED;
    377 };
    378 
    379 // for now
    380 typedef SkFILEStream SkURLStream;
    381 
    382 #endif
    383