/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkReadBuffer_DEFINED
#define SkReadBuffer_DEFINED

#include "SkColorFilter.h"
#include "SkSerialProcs.h"
#include "SkDrawLooper.h"
#include "SkFont.h"
#include "SkImageFilter.h"
#include "SkMaskFilterBase.h"
#include "SkPaintPriv.h"
#include "SkPath.h"
#include "SkPathEffect.h"
#include "SkPicture.h"
#include "SkReader32.h"
#include "SkRefCnt.h"
#include "SkShaderBase.h"
#include "SkWriteBuffer.h"

class SkData;
class SkImage;

#ifndef SK_DISABLE_READBUFFER

class SkReadBuffer {
public:
    SkReadBuffer();
    SkReadBuffer(const void* data, size_t size);

    enum Version {
        kTileModeInBlurImageFilter_Version = 56,
        kTileInfoInSweepGradient_Version   = 57,
        k2PtConicalNoFlip_Version          = 58,
        kRemovePictureImageFilterLocalSpace = 59,
        kRemoveHeaderFlags_Version         = 60,
        kTwoColorDrawShadow_Version        = 61,
        kDontNegateImageSize_Version       = 62,
        kStoreImageBounds_Version          = 63,
        kRemoveOccluderFromBlurMaskFilter  = 64,
        kFloat4PaintColor_Version          = 65,
        kSaveBehind_Version                = 66,
        kSerializeFonts_Version            = 67,
        kPaintDoesntSerializeFonts_Version = 68,
    };

    /**
     *  Returns true IFF the version is older than the specified version.
     */
    bool isVersionLT(Version targetVersion) const {
        SkASSERT(targetVersion > 0);
        return fVersion > 0 && fVersion < targetVersion;
    }

    uint32_t getVersion() const { return fVersion; }

    /** This may be called at most once; most clients of SkReadBuffer should not mess with it. */
    void setVersion(int version) {
        SkASSERT(0 == fVersion || version == fVersion);
        fVersion = version;
    }

    size_t size() const { return fReader.size(); }
    size_t offset() const { return fReader.offset(); }
    bool eof() { return fReader.eof(); }
    const void* skip(size_t size);
    const void* skip(size_t count, size_t size);    // does safe multiply
    size_t available() const { return fReader.available(); }

    template <typename T> const T* skipT() {
        return static_cast<const T*>(this->skip(sizeof(T)));
    }
    template <typename T> const T* skipT(size_t count) {
        return static_cast<const T*>(this->skip(count, sizeof(T)));
    }

    // primitives
    bool readBool();
    SkColor readColor();
    int32_t readInt();
    SkScalar readScalar();
    uint32_t readUInt();
    int32_t read32();

    template <typename T> T read32LE(T max) {
        uint32_t value = this->readUInt();
        if (!this->validate(value <= static_cast<uint32_t>(max))) {
            value = 0;
        }
        return static_cast<T>(value);
    }

    // peek
    uint8_t peekByte();

    // strings -- the caller is responsible for freeing the string contents
    void readString(SkString* string);

    // common data structures
    void readColor4f(SkColor4f* color);
    void readPoint(SkPoint* point);
    SkPoint readPoint() { SkPoint p; this->readPoint(&p); return p; }
    void readPoint3(SkPoint3* point);
    void readMatrix(SkMatrix* matrix);
    void readIRect(SkIRect* rect);
    void readRect(SkRect* rect);
    void readRRect(SkRRect* rrect);
    void readRegion(SkRegion* region);

    void readPath(SkPath* path);

    SkReadPaintResult readPaint(SkPaint* paint, SkFont* font) {
        return SkPaintPriv::Unflatten(paint, *this, font);
    }

    SkFlattenable* readFlattenable(SkFlattenable::Type);
    template <typename T> sk_sp<T> readFlattenable() {
        return sk_sp<T>((T*)this->readFlattenable(T::GetFlattenableType()));
    }
    sk_sp<SkColorFilter> readColorFilter() { return this->readFlattenable<SkColorFilter>(); }
    sk_sp<SkDrawLooper> readDrawLooper() { return this->readFlattenable<SkDrawLooper>(); }
    sk_sp<SkImageFilter> readImageFilter() { return this->readFlattenable<SkImageFilter>(); }
    sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilterBase>(); }
    sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); }
    sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); }

    // Reads SkAlign4(bytes), but will only copy bytes into the buffer.
    bool readPad32(void* buffer, size_t bytes);

    // binary data and arrays
    bool readByteArray(void* value, size_t size);
    bool readColorArray(SkColor* colors, size_t size);
    bool readColor4fArray(SkColor4f* colors, size_t size);
    bool readIntArray(int32_t* values, size_t size);
    bool readPointArray(SkPoint* points, size_t size);
    bool readScalarArray(SkScalar* values, size_t size);

    sk_sp<SkData> readByteArrayAsData();

    // helpers to get info about arrays and binary data
    uint32_t getArrayCount();

    // If there is a real error (e.g. data is corrupted) this returns null. If the image cannot
    // be created (e.g. it was not originally encoded) then this returns an image that doesn't
    // draw.
    sk_sp<SkImage> readImage();
    sk_sp<SkTypeface> readTypeface();

    void setTypefaceArray(sk_sp<SkTypeface> array[], int count) {
        fTFArray = array;
        fTFCount = count;
    }

    /**
     *  Call this with a pre-loaded array of Factories, in the same order as
     *  were created/written by the writer. SkPicture uses this.
     */
    void setFactoryPlayback(SkFlattenable::Factory array[], int count) {
        fFactoryArray = array;
        fFactoryCount = count;
    }

    void setDeserialProcs(const SkDeserialProcs& procs);
    const SkDeserialProcs& getDeserialProcs() const { return fProcs; }

    /**
     *  If isValid is false, sets the buffer to be "invalid". Returns true if the buffer
     *  is still valid.
     */
    bool validate(bool isValid) {
        if (!isValid) {
            this->setInvalid();
        }
        return !fError;
    }

    /**
     * Helper function to do a preflight check before a large allocation or read.
     * Returns true if there is enough bytes in the buffer to read n elements of T.
     * If not, the buffer will be "invalid" and false will be returned.
     */
    template <typename T>
    bool validateCanReadN(size_t n) {
        return this->validate(n <= (fReader.available() / sizeof(T)));
    }

    bool isValid() const { return !fError; }
    bool validateIndex(int index, int count) {
        return this->validate(index >= 0 && index < count);
    }

    // Utilities that mark the buffer invalid if the requested value is out-of-range

    // If the read value is outside of the range, validate(false) is called, and min
    // is returned, else the value is returned.
    int32_t checkInt(int min, int max);

    template <typename T> T checkRange(T min, T max) {
        return static_cast<T>(this->checkInt(static_cast<int32_t>(min),
                                             static_cast<int32_t>(max)));
    }

    SkFilterQuality checkFilterQuality();

private:
    void setInvalid();
    bool readArray(void* value, size_t size, size_t elementSize);
    void setMemory(const void*, size_t);

    SkReader32 fReader;

    // Only used if we do not have an fFactoryArray.
    SkTHashMap<uint32_t, SkFlattenable::Factory> fFlattenableDict;

    int fVersion;

    sk_sp<SkTypeface>* fTFArray;
    int                fTFCount;

    SkFlattenable::Factory* fFactoryArray;
    int                     fFactoryCount;

    SkDeserialProcs fProcs;

    static bool IsPtrAlign4(const void* ptr) {
        return SkIsAlign4((uintptr_t)ptr);
    }

    bool fError = false;
};

#else // #ifndef SK_DISABLE_READBUFFER

class SkReadBuffer {
public:
    SkReadBuffer() {}
    SkReadBuffer(const void*, size_t) {}

    enum Version {
        kTileModeInBlurImageFilter_Version = 56,
        kTileInfoInSweepGradient_Version   = 57,
        k2PtConicalNoFlip_Version          = 58,
        kRemovePictureImageFilterLocalSpace = 59,
        kRemoveHeaderFlags_Version         = 60,
        kTwoColorDrawShadow_Version        = 61,
        kDontNegateImageSize_Version       = 62,
        kStoreImageBounds_Version          = 63,
        kRemoveOccluderFromBlurMaskFilter  = 64,
        kFloat4PaintColor_Version          = 65,
        kSaveBehind_Version                = 66,
        kSerializeFonts_Version            = 67,
        kPaintDoesntSerializeFonts_Version = 68,
    };

    bool isVersionLT(Version) const { return false; }
    uint32_t getVersion() const { return 0xffffffff; }
    void     setVersion(int) {}

    size_t size() const { return 0; }
    size_t offset() const { return 0; }
    bool eof() { return true; }
    size_t available() const { return 0; }

    const void* skip(size_t)         { return nullptr; }
    const void* skip(size_t, size_t) { return nullptr; }
    template <typename T> const T* skipT()       { return nullptr; }
    template <typename T> const T* skipT(size_t) { return nullptr; }

    bool     readBool()   { return 0; }
    SkColor  readColor()  { return 0; }
    int32_t  readInt()    { return 0; }
    SkScalar readScalar() { return 0; }
    uint32_t readUInt()   { return 0; }
    int32_t  read32()     { return 0; }

    template <typename T> T read32LE(T max) { return max; }

    uint8_t  peekByte()   { return 0; }

    void readColor4f(SkColor4f* out) { *out = SkColor4f{0,0,0,0}; }
    void readPoint  (SkPoint*   out) { *out = SkPoint{0,0};       }
    void readPoint3 (SkPoint3*  out) { *out = SkPoint3{0,0,0};    }
    void readMatrix (SkMatrix*  out) { *out = SkMatrix::I();      }
    void readIRect  (SkIRect*   out) { *out = SkIRect{0,0,0,0};   }
    void readRect   (SkRect*    out) { *out = SkRect{0,0,0,0};    }
    void readRRect  (SkRRect*   out) { *out = SkRRect();          }
    void readRegion (SkRegion*  out) { *out = SkRegion();         }
    void readString (SkString*  out) { *out = SkString();         }
    void readPath   (SkPath*    out) { *out = SkPath();           }
    SkReadPaintResult readPaint  (SkPaint*   out, SkFont* font) {
        *out = SkPaint();
        if (font) {
            *font = SkFont();
        }
        return kFailed_ReadPaint;
    }

    SkPoint readPoint() { return {0,0}; }

    SkFlattenable* readFlattenable(SkFlattenable::Type) { return nullptr; }

    template <typename T> sk_sp<T> readFlattenable() { return nullptr; }
    sk_sp<SkColorFilter> readColorFilter() { return nullptr; }
    sk_sp<SkDrawLooper>  readDrawLooper()  { return nullptr; }
    sk_sp<SkImageFilter> readImageFilter() { return nullptr; }
    sk_sp<SkMaskFilter>  readMaskFilter()  { return nullptr; }
    sk_sp<SkPathEffect>  readPathEffect()  { return nullptr; }
    sk_sp<SkShader>      readShader()      { return nullptr; }

    bool readPad32       (void*,      size_t) { return false; }
    bool readByteArray   (void*,      size_t) { return false; }
    bool readColorArray  (SkColor*,   size_t) { return false; }
    bool readColor4fArray(SkColor4f*, size_t) { return false; }
    bool readIntArray    (int32_t*,   size_t) { return false; }
    bool readPointArray  (SkPoint*,   size_t) { return false; }
    bool readScalarArray (SkScalar*,  size_t) { return false; }

    sk_sp<SkData> readByteArrayAsData() { return nullptr; }
    uint32_t getArrayCount() { return 0; }

    sk_sp<SkImage>    readImage()    { return nullptr; }
    sk_sp<SkTypeface> readTypeface() { return nullptr; }

    bool validate(bool)                                 { return false; }
    template <typename T> bool validateCanReadN(size_t) { return false; }
    bool isValid() const                                { return false; }
    bool validateIndex(int, int)                        { return false; }

    int32_t checkInt(int min, int)               { return min; }
    template <typename T> T checkRange(T min, T) { return min; }

    SkFilterQuality checkFilterQuality() { return SkFilterQuality::kNone_SkFilterQuality; }

    void setTypefaceArray(sk_sp<SkTypeface>[], int)        {}
    void setFactoryPlayback(SkFlattenable::Factory[], int) {}
    void setDeserialProcs(const SkDeserialProcs&)          {}

    const SkDeserialProcs& getDeserialProcs() const {
        static const SkDeserialProcs procs;
        return procs;
    }
};

#endif // #ifndef SK_DISABLE_READBUFFER

#endif // SkReadBuffer_DEFINED
