/*
 * 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 "SkData.h"
#include "SkSerialProcs.h"
#include "SkDrawLooper.h"
#include "SkImageFilter.h"
#include "SkMaskFilterBase.h"
#include "SkPath.h"
#include "SkPathEffect.h"
#include "SkPicture.h"
#include "SkReadBuffer.h"
#include "SkReader32.h"
#include "SkRefCnt.h"
#include "SkShaderBase.h"
#include "SkTHash.h"
#include "SkWriteBuffer.h"

class SkImage;
class SkInflator;

#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_MAC)
    #define DEBUG_NON_DETERMINISTIC_ASSERT
#endif

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

    virtual SkReadBuffer* clone(const void* data, size_t size) const {
        return new SkReadBuffer(data, size);
    }

    enum Version {
        /*
        kFilterLevelIsEnum_Version         = 23,
        kGradientFlippedFlag_Version       = 24,
        kDashWritesPhaseIntervals_Version  = 25,
        kColorShaderNoBool_Version         = 26,
        kNoUnitMappers_Version             = 27,
        kNoMoreBitmapFlatten_Version       = 28,
        kSimplifyLocalMatrix_Version       = 30,
        kImageFilterUniqueID_Version       = 31,
        kRemoveAndroidPaintOpts_Version    = 32,
        kFlattenCreateProc_Version         = 33,
        kRemoveColorTableAlpha_Version     = 36,
        kDropShadowMode_Version            = 37,
        kPictureImageFilterResolution_Version = 38,
        kPictureImageFilterLevel_Version   = 39,
        kImageFilterNoUniqueID_Version     = 40,
        kBitmapSourceFilterQuality_Version = 41,
        kPictureShaderHasPictureBool_Version = 42,
        kHasDrawImageOpCodes_Version       = 43,
        kAnnotationsMovedToCanvas_Version  = 44,
        kLightingShaderWritesInvNormRotation = 45,
        kBlurMaskFilterWritesOccluder      = 47,
        kGradientShaderFloatColor_Version  = 49,
        kXfermodeToBlendMode_Version       = 50,
        kXfermodeToBlendMode2_Version      = 51,
        kTextBlobImplicitRunCount_Version  = 52,
        kComposeShaderCanLerp_Version      = 54,
        kNoModesInMergeImageFilter_Verison = 55,
         */
        kTileModeInBlurImageFilter_Version = 56,
        kTileInfoInSweepGradient_Version   = 57,
        k2PtConicalNoFlip_Version          = 58,
        kRemovePictureImageFilterLocalSpace = 59,
        kRemoveHeaderFlags_Version         = 60,
        kTwoColorDrawShadow_Version        = 61,
    };

    /**
     *  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() { return fReader.size(); }
    size_t offset() { 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

    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);
    virtual bool readPaint(SkPaint* paint) { return paint->unflatten(*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() {
        size_t len = this->getArrayCount();
        void* buffer = sk_malloc_throw(len);
        if (!this->readByteArray(buffer, len)) {
            sk_free(buffer);
            return SkData::MakeEmpty();
        }
        return SkData::MakeFromMalloc(buffer, len);
    }

    // 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(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;
    }

    /**
     *  For an input flattenable (specified by name), set a custom factory proc
     *  to use when unflattening.  Will make a copy of |name|.
     *
     *  If the global registry already has a default factory for the flattenable,
     *  this will override that factory.  If a custom factory has already been
     *  set for the flattenable, this will override that factory.
     *
     *  Custom factories can be removed by calling setCustomFactory("...", nullptr).
     */
    void setCustomFactory(const SkString& name, SkFlattenable::Factory factory) {
        fCustomFactory.set(name, factory);
    }

    void setDeserialProcs(const SkDeserialProcs& procs);

    /**
     *  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;
    }
    bool isValid() const { return !fError; }
    bool validateIndex(int index, int count) {
        return this->validate(index >= 0 && index < count);
    }

    SkInflator* getInflator() const { return fInflator; }
    void setInflator(SkInflator* inf) { fInflator = inf; }

    // 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();

protected:
    /**
     *  Allows subclass to check if we are using factories for expansion
     *  of flattenables.
     */
    int factoryCount() { return fFactoryCount; }

    /**
     *  Checks if a custom factory has been set for a given flattenable.
     *  Returns the custom factory if it exists, or nullptr otherwise.
     */
    SkFlattenable::Factory getCustomFactory(const SkString& name) {
        SkFlattenable::Factory* factoryPtr = fCustomFactory.find(name);
        return factoryPtr ? *factoryPtr : nullptr;
    }

    SkReader32 fReader;

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

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

    int fVersion;

    void* fMemoryPtr;

    SkTypeface** fTFArray;
    int        fTFCount;

    SkFlattenable::Factory* fFactoryArray;
    int                     fFactoryCount;

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

    SkDeserialProcs fProcs;
    friend class SkPicture;

#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
    // Debugging counter to keep track of how many bitmaps we
    // have decoded.
    int fDecodedBitmapIndex;
#endif // DEBUG_NON_DETERMINISTIC_ASSERT

    SkInflator* fInflator = nullptr;

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

    bool fError = false;
};

#endif // SkReadBuffer_DEFINED
