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 33class SkData; 34class SkImage; 35 36class SK_API SkReadBuffer { 37public: 38 SkReadBuffer() = default; 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 */ 48 bool isVersionLT(SkPicturePriv::Version targetVersion) const { 49 SkASSERT(targetVersion > 0); 50 return fVersion > 0 && fVersion < targetVersion; 51 } 52 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. */ 56 void setVersion(int version) { 57 SkASSERT(0 == fVersion || version == fVersion); 58 fVersion = version; 59 } 60 61 size_t size() const { return fStop - fBase; } 62 size_t offset() const { return fCurr - fBase; } 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 66 size_t available() const { return fStop - fCurr; } 67 68 template <typename T> const T* skipT() { 69 return static_cast<const T*>(this->skip(sizeof(T))); 70 } 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 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); 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 111 SkPaint readPaint() { 112 return SkPaintPriv::Unflatten(*this); 113 } 114 115 SkFlattenable* readFlattenable(SkFlattenable::Type); 116 template <typename T> sk_sp<T> readFlattenable() { 117 return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType())); 118 } 119 sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilterBase>(); } 120#ifdef SK_SUPPORT_LEGACY_DRAWLOOPER 121 sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); } 122#endif 123 sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter_Base>(); } 124 sk_sp<SkBlender> readBlender() { return this->readFlattenable<SkBlenderBase>(); } 125 sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); } 126 sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); } 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 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 */ 162 void setFactoryPlayback(SkFlattenable::Factory array[], int count) { 163 fFactoryArray = array; 164 fFactoryCount = count; 165 } 166 167 void setDeserialProcs(const SkDeserialProcs& procs); 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 */ 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> 187 bool validateCanReadN(size_t n) { 188 return this->validate(n <= (this->available() / sizeof(T))); 189 } 190 191 bool isValid() const { return !fError; } 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 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 211private: 212 const char* readString(size_t* length); 213 214 void setInvalid(); 215 bool readArray(void* value, size_t size, size_t elementSize); 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 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