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