/*
 * 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 "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,
    };

    /**
     *  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);
    bool readPaint(SkPaint* paint) { return SkPaintPriv::Unflatten(paint, *this); }

    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,
    };

    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();           }
    bool readPaint  (SkPaint*   out) { *out = SkPaint(); return false; }

    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
