xref: /aosp_15_r20/external/skia/src/base/SkBuffer.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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