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