xref: /third_party/skia/src/core/SkBuffer.h (revision cb93a386)
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 "include/core/SkScalar.h"
12#include "include/core/SkTypes.h"
13#include "include/private/SkNoncopyable.h"
14#include "src/core/SkSafeMath.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*/
25class SkRBuffer : SkNoncopyable {
26public:
27    SkRBuffer() : fData(nullptr), fPos(nullptr), fStop(nullptr) {}
28
29    /** Initialize RBuffer with a data point and length.
30    */
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    */
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    */
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    */
50    bool eof() const { return fPos >= fStop; }
51
52    size_t available() const { return fStop - fPos; }
53
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
62    bool readU8(uint8_t* x)   { return this->read(x, 1); }
63    bool readS32(int32_t* x)  { return this->read(x, 4); }
64    bool readU32(uint32_t* x) { return this->read(x, 4); }
65
66    // returns nullptr on failure
67    const void* skip(size_t bytes);
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
72private:
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*/
87class SkWBuffer : SkNoncopyable {
88public:
89    SkWBuffer() : fData(nullptr), fPos(nullptr), fStop(nullptr) {}
90    SkWBuffer(void* data) { reset(data); }
91    SkWBuffer(void* data, size_t size) { reset(data, size); }
92
93    void reset(void* data) {
94        fData = (char*)data;
95        fPos = (char*)data;
96        fStop = nullptr;  // no bounds checking
97    }
98
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
106    size_t  pos() const { return fPos - fData; }
107    void*   skip(size_t size); // return start of skipped data
108
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
117    void    writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
118    void    writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
119    void    write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
120    void    write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
121    void    write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
122    void    writeBool(bool x) { this->write8(x); }
123
124private:
125    void    writeNoSizeCheck(const void* buffer, size_t size);
126
127    char* fData;
128    char* fPos;
129    char* fStop;
130};
131
132#endif
133