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 SkBuffer_DEFINED
     11 #define SkBuffer_DEFINED
     12 
     13 #include "SkScalar.h"
     14 #include "SkTypes.h"
     15 
     16 /** \class SkRBuffer
     17 
     18     Light weight class for reading data from a memory block.
     19     The RBuffer is given the buffer to read from, with either a specified size
     20     or no size (in which case no range checking is performed). It is iillegal
     21     to attempt to read a value from an empty RBuffer (data == null).
     22 */
     23 class SkRBuffer : SkNoncopyable {
     24 public:
     25     SkRBuffer() : fData(0), fPos(0), fStop(0) {}
     26     /** Initialize RBuffer with a data pointer, but no specified length.
     27         This signals the RBuffer to not perform range checks during reading.
     28     */
     29     SkRBuffer(const void* data) {
     30         fData = (const char*)data;
     31         fPos = (const char*)data;
     32         fStop = 0;  // no bounds checking
     33     }
     34     /** Initialize RBuffer with a data point and length.
     35     */
     36     SkRBuffer(const void* data, size_t size) {
     37         SkASSERT(data != 0 || size == 0);
     38         fData = (const char*)data;
     39         fPos = (const char*)data;
     40         fStop = (const char*)data + size;
     41     }
     42 
     43     virtual ~SkRBuffer() { }
     44 
     45     /** Return the number of bytes that have been read from the beginning
     46         of the data pointer.
     47     */
     48     size_t  pos() const { return fPos - fData; }
     49     /** Return the total size of the data pointer. Only defined if the length was
     50         specified in the constructor or in a call to reset().
     51     */
     52     size_t  size() const { return fStop - fData; }
     53     /** Return true if the buffer has read to the end of the data pointer.
     54         Only defined if the length was specified in the constructor or in a call
     55         to reset(). Always returns true if the length was not specified.
     56     */
     57     bool    eof() const { return fPos >= fStop; }
     58 
     59     /** Read the specified number of bytes from the data pointer. If buffer is not
     60         null, copy those bytes into buffer.
     61     */
     62     virtual bool read(void* buffer, size_t size) {
     63         if (size) {
     64             this->readNoSizeCheck(buffer, size);
     65         }
     66         return true;
     67     }
     68 
     69     const void* skip(size_t size); // return start of skipped data
     70     size_t  skipToAlign4();
     71 
     72     bool readPtr(void** ptr) { return read(ptr, sizeof(void*)); }
     73     bool readScalar(SkScalar* x) { return read(x, 4); }
     74     bool readU32(uint32_t* x) { return read(x, 4); }
     75     bool readS32(int32_t* x) { return read(x, 4); }
     76     bool readU16(uint16_t* x) { return read(x, 2); }
     77     bool readS16(int16_t* x) { return read(x, 2); }
     78     bool readU8(uint8_t* x) { return read(x, 1); }
     79     bool readBool(bool* x) {
     80         uint8_t u8;
     81         if (this->readU8(&u8)) {
     82             *x = (u8 != 0);
     83             return true;
     84         }
     85         return false;
     86     }
     87 
     88 protected:
     89     void    readNoSizeCheck(void* buffer, size_t size);
     90 
     91     const char* fData;
     92     const char* fPos;
     93     const char* fStop;
     94 };
     95 
     96 /** \class SkRBufferWithSizeCheck
     97 
     98     Same as SkRBuffer, except that a size check is performed before the read operation and an
     99     error is set if the read operation is attempting to read past the end of the data.
    100 */
    101 class SkRBufferWithSizeCheck : public SkRBuffer {
    102 public:
    103     SkRBufferWithSizeCheck(const void* data, size_t size) : SkRBuffer(data, size), fError(false) {}
    104 
    105     /** Read the specified number of bytes from the data pointer. If buffer is not
    106         null and the number of bytes to read does not overflow this object's data,
    107         copy those bytes into buffer.
    108     */
    109     bool read(void* buffer, size_t size) override;
    110 
    111     /** Returns whether or not a read operation attempted to read past the end of the data.
    112     */
    113     bool isValid() const { return !fError; }
    114 private:
    115     bool fError;
    116 };
    117 
    118 /** \class SkWBuffer
    119 
    120     Light weight class for writing data to a memory block.
    121     The WBuffer is given the buffer to write into, with either a specified size
    122     or no size, in which case no range checking is performed. An empty WBuffer
    123     is legal, in which case no data is ever written, but the relative pos()
    124     is updated.
    125 */
    126 class SkWBuffer : SkNoncopyable {
    127 public:
    128     SkWBuffer() : fData(0), fPos(0), fStop(0) {}
    129     SkWBuffer(void* data) { reset(data); }
    130     SkWBuffer(void* data, size_t size) { reset(data, size); }
    131 
    132     void reset(void* data) {
    133         fData = (char*)data;
    134         fPos = (char*)data;
    135         fStop = 0;  // no bounds checking
    136     }
    137 
    138     void reset(void* data, size_t size) {
    139         SkASSERT(data != 0 || size == 0);
    140         fData = (char*)data;
    141         fPos = (char*)data;
    142         fStop = (char*)data + size;
    143     }
    144 
    145     size_t  pos() const { return fPos - fData; }
    146     void*   skip(size_t size); // return start of skipped data
    147 
    148     void write(const void* buffer, size_t size) {
    149         if (size) {
    150             this->writeNoSizeCheck(buffer, size);
    151         }
    152     }
    153 
    154     size_t  padToAlign4();
    155 
    156     void    writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
    157     void    writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
    158     void    write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
    159     void    write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
    160     void    write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
    161     void    writeBool(bool x) { this->write8(x); }
    162 
    163 private:
    164     void    writeNoSizeCheck(const void* buffer, size_t size);
    165 
    166     char* fData;
    167     char* fPos;
    168     char* fStop;
    169 };
    170 
    171 #endif
    172