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