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