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