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