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