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: SkRBuffer()25 SkRBuffer() : fData(nullptr), fPos(nullptr), fStop(nullptr) {} 26 27 /** Initialize RBuffer with a data point and length. 28 */ SkRBuffer(const void * data,size_t size)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 */ pos()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 */ size()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 */ eof()48 bool eof() const { return fPos >= fStop; } 49 available()50 size_t available() const { return fStop - fPos; } 51 isValid()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 readU8(uint8_t * x)60 bool readU8(uint8_t* x) { return this->read(x, 1); } readS32(int32_t * x)61 bool readS32(int32_t* x) { return this->read(x, 4); } readU32(uint32_t * x)62 bool readU32(uint32_t* x) { return this->read(x, 4); } 63 64 // returns nullptr on failure 65 const void* skip(size_t bytes); skipCount(size_t count)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: SkWBuffer()87 SkWBuffer() : fData(nullptr), fPos(nullptr), fStop(nullptr) {} SkWBuffer(void * data)88 SkWBuffer(void* data) { reset(data); } SkWBuffer(void * data,size_t size)89 SkWBuffer(void* data, size_t size) { reset(data, size); } 90 reset(void * data)91 void reset(void* data) { 92 fData = (char*)data; 93 fPos = (char*)data; 94 fStop = nullptr; // no bounds checking 95 } 96 reset(void * data,size_t size)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 pos()104 size_t pos() const { return fPos - fData; } 105 void* skip(size_t size); // return start of skipped data 106 write(const void * buffer,size_t size)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 writePtr(const void * x)115 void writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); } writeScalar(SkScalar x)116 void writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); } write32(int32_t x)117 void write32(int32_t x) { this->writeNoSizeCheck(&x, 4); } write16(int16_t x)118 void write16(int16_t x) { this->writeNoSizeCheck(&x, 2); } write8(int8_t x)119 void write8(int8_t x) { this->writeNoSizeCheck(&x, 1); } writeBool(bool x)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