1/*
2 * Copyright 2011 Google Inc.
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 SkReadBuffer_DEFINED
9#define SkReadBuffer_DEFINED
10
11#include "include/core/SkDrawLooper.h"
12#include "include/core/SkFont.h"
13#include "include/core/SkImageFilter.h"
14#include "include/core/SkPath.h"
15#include "include/core/SkPathEffect.h"
16#include "include/core/SkPicture.h"
17#include "include/core/SkRefCnt.h"
18#include "include/core/SkScalar.h"
19#include "include/core/SkSerialProcs.h"
20#include "src/core/SkColorFilterBase.h"
21#include "src/core/SkMaskFilterBase.h"
22#include "src/core/SkPaintPriv.h"
23#include "src/core/SkPicturePriv.h"
24#include "src/core/SkWriteBuffer.h"
25#include "src/shaders/SkShaderBase.h"
26
27class SkData;
28class SkImage;
29
30class SkReadBuffer {
31public:
32 SkReadBuffer() = default;
33 SkReadBuffer(const void* data, size_t size) {
34 this->setMemory(data, size);
35 }
36
37 void setMemory(const void*, size_t);
38
39 /**
40 * Returns true IFF the version is older than the specified version.
41 */
42 bool isVersionLT(SkPicturePriv::Version targetVersion) const {
43 SkASSERT(targetVersion > 0);
44 return fVersion > 0 && fVersion < targetVersion;
45 }
46
47 uint32_t getVersion() const { return fVersion; }
48
49 /** This may be called at most once; most clients of SkReadBuffer should not mess with it. */
50 void setVersion(int version) {
51 SkASSERT(0 == fVersion || version == fVersion);
52 fVersion = version;
53 }
54
55 size_t size() const { return fStop - fBase; }
56 size_t offset() const { return fCurr - fBase; }
57 bool eof() { return fCurr >= fStop; }
58 const void* skip(size_t size);
59 const void* skip(size_t count, size_t size); // does safe multiply
60 size_t available() const { return fStop - fCurr; }
61
62 template <typename T> const T* skipT() {
63 return static_cast<const T*>(this->skip(sizeof(T)));
64 }
65 template <typename T> const T* skipT(size_t count) {
66 return static_cast<const T*>(this->skip(count, sizeof(T)));
67 }
68
69 // primitives
70 bool readBool();
71 SkColor readColor();
72 int32_t readInt();
73 SkScalar readScalar();
74 uint32_t readUInt();
75 int32_t read32();
76
77 template <typename T> T read32LE(T max) {
78 uint32_t value = this->readUInt();
79 if (!this->validate(value <= static_cast<uint32_t>(max))) {
80 value = 0;
81 }
82 return static_cast<T>(value);
83 }
84
85 // peek
86 uint8_t peekByte();
87
88 void readString(SkString* string);
89
90 // common data structures
91 void readColor4f(SkColor4f* color);
92 void readPoint(SkPoint* point);
93 SkPoint readPoint() { SkPoint p; this->readPoint(&p); return p; }
94 void readPoint3(SkPoint3* point);
95 void read(SkM44*);
96 void readMatrix(SkMatrix* matrix);
97 void readIRect(SkIRect* rect);
98 void readRect(SkRect* rect);
99 void readRRect(SkRRect* rrect);
100 void readRegion(SkRegion* region);
101
102 void readPath(SkPath* path);
103
104 SkReadPaintResult readPaint(SkPaint* paint, SkFont* font) {
105 return SkPaintPriv::Unflatten(paint, *this, font);
106 }
107
108 SkFlattenable* readFlattenable(SkFlattenable::Type);
109 template <typename T> sk_sp<T> readFlattenable() {
110 return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType()));
111 }
112 sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilterBase>(); }
113 sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); }
114 sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter>(); }
115 sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); }
116 sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); }
117 sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); }
118
119 // Reads SkAlign4(bytes), but will only copy bytes into the buffer.
120 bool readPad32(void* buffer, size_t bytes);
121
122 // binary data and arrays
123 bool readByteArray(void* value, size_t size);
124 bool readColorArray(SkColor* colors, size_t size);
125 bool readColor4fArray(SkColor4f* colors, size_t size);
126 bool readIntArray(int32_t* values, size_t size);
127 bool readPointArray(SkPoint* points, size_t size);
128 bool readScalarArray(SkScalar* values, size_t size);
129
130 const void* skipByteArray(size_t* size);
131
132 sk_sp<SkData> readByteArrayAsData();
133
134 // helpers to get info about arrays and binary data
135 uint32_t getArrayCount();
136
137 // If there is a real error (e.g. data is corrupted) this returns null. If the image cannot
138 // be created (e.g. it was not originally encoded) then this returns an image that doesn't
139 // draw.
140 sk_sp<SkImage> readImage();
141 sk_sp<SkTypeface> readTypeface();
142
143 void setTypefaceArray(sk_sp<SkTypeface> array[], int count) {
144 fTFArray = array;
145 fTFCount = count;
146 }
147
148 /**
149 * Call this with a pre-loaded array of Factories, in the same order as
150 * were created/written by the writer. SkPicture uses this.
151 */
152 void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
153 fFactoryArray = array;
154 fFactoryCount = count;
155 }
156
157 void setDeserialProcs(const SkDeserialProcs& procs);
158 const SkDeserialProcs& getDeserialProcs() const { return fProcs; }
159
160 /**
161 * If isValid is false, sets the buffer to be "invalid". Returns true if the buffer
162 * is still valid.
163 */
164 bool validate(bool isValid) {
165 if (!isValid) {
166 this->setInvalid();
167 }
168 return !fError;
169 }
170
171 /**
172 * Helper function to do a preflight check before a large allocation or read.
173 * Returns true if there is enough bytes in the buffer to read n elements of T.
174 * If not, the buffer will be "invalid" and false will be returned.
175 */
176 template <typename T>
177 bool validateCanReadN(size_t n) {
178 return this->validate(n <= (this->available() / sizeof(T)));
179 }
180
181 bool isValid() const { return !fError; }
182 bool validateIndex(int index, int count) {
183 return this->validate(index >= 0 && index < count);
184 }
185
186 // Utilities that mark the buffer invalid if the requested value is out-of-range
187
188 // If the read value is outside of the range, validate(false) is called, and min
189 // is returned, else the value is returned.
190 int32_t checkInt(int min, int max);
191
192 template <typename T> T checkRange(T min, T max) {
193 return static_cast<T>(this->checkInt(static_cast<int32_t>(min),
194 static_cast<int32_t>(max)));
195 }
196
197 SkFilterQuality checkFilterQuality();
198
199private:
200 const char* readString(size_t* length);
201
202 void setInvalid();
203 bool readArray(void* value, size_t size, size_t elementSize);
204 bool isAvailable(size_t size) const { return size <= this->available(); }
205
206 sk_sp<SkImage> readImage_preV78();
207
208 // These are always 4-byte aligned
209 const char* fCurr = nullptr; // current position within buffer
210 const char* fStop = nullptr; // end of buffer
211 const char* fBase = nullptr; // beginning of buffer
212
213 // Only used if we do not have an fFactoryArray.
214 SkTHashMap<uint32_t, SkFlattenable::Factory> fFlattenableDict;
215
216 int fVersion = 0;
217
218 sk_sp<SkTypeface>* fTFArray = nullptr;
219 int fTFCount = 0;
220
221 SkFlattenable::Factory* fFactoryArray = nullptr;
222 int fFactoryCount = 0;
223
224 SkDeserialProcs fProcs;
225
226 static bool IsPtrAlign4(const void* ptr) {
227 return SkIsAlign4((uintptr_t)ptr);
228 }
229
230 bool fError = false;
231};
232
233#endif // SkReadBuffer_DEFINED
234