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