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