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 | |
27 | class SkData; |
28 | class SkImage; |
29 | |
30 | class SkReadBuffer { |
31 | public: |
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 | |
199 | private: |
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 | |