
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkDescriptor_DEFINED
#define SkDescriptor_DEFINED

#include "SkChecksum.h"
#include "SkTypes.h"

class SkDescriptor : SkNoncopyable {
public:
    static size_t ComputeOverhead(int entryCount) {
        SkASSERT(entryCount >= 0);
        return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
    }

    static SkDescriptor* Alloc(size_t length) {
        SkASSERT(SkAlign4(length) == length);
        SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
        return desc;
    }

    static void Free(SkDescriptor* desc) {
        sk_free(desc);
    }

    void init() {
        fLength = sizeof(SkDescriptor);
        fCount  = 0;
    }

    uint32_t getLength() const { return fLength; }

    void* addEntry(uint32_t tag, size_t length, const void* data = NULL) {
        SkASSERT(tag);
        SkASSERT(SkAlign4(length) == length);
        SkASSERT(this->findEntry(tag, NULL) == NULL);

        Entry* entry = (Entry*)((char*)this + fLength);
        entry->fTag = tag;
        entry->fLen = SkToU32(length);
        if (data) {
            memcpy(entry + 1, data, length);
        }

        fCount += 1;
        fLength = SkToU32(fLength + sizeof(Entry) + length);
        return (entry + 1); // return its data
    }

    void computeChecksum() {
        fChecksum = SkDescriptor::ComputeChecksum(this);
    }

#ifdef SK_DEBUG
    void assertChecksum() const {
        SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum);
    }
#endif

    const void* findEntry(uint32_t tag, uint32_t* length) const {
        const Entry* entry = (const Entry*)(this + 1);
        int          count = fCount;

        while (--count >= 0) {
            if (entry->fTag == tag) {
                if (length) {
                    *length = entry->fLen;
                }
                return entry + 1;
            }
            entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
        }
        return NULL;
    }

    SkDescriptor* copy() const {
        SkDescriptor* desc = SkDescriptor::Alloc(fLength);
        memcpy(desc, this, fLength);
        return desc;
    }

    bool equals(const SkDescriptor& other) const {
        // probe to see if we have a good checksum algo
//        SkASSERT(a.fChecksum != b.fChecksum || memcmp(&a, &b, a.fLength) == 0);

        // the first value we should look at is the checksum, so this loop
        // should terminate early if they descriptors are different.
        // NOTE: if we wrote a sentinel value at the end of each, we chould
        //       remove the aa < stop test in the loop...
        const uint32_t* aa = (const uint32_t*)this;
        const uint32_t* bb = (const uint32_t*)&other;
        const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
        do {
            if (*aa++ != *bb++)
                return false;
        } while (aa < stop);
        return true;
    }

    uint32_t getChecksum() const { return fChecksum; }

    struct Entry {
        uint32_t fTag;
        uint32_t fLen;
    };

#ifdef SK_DEBUG
    uint32_t getCount() const { return fCount; }
#endif

private:
    uint32_t fChecksum;  // must be first
    uint32_t fLength;    // must be second
    uint32_t fCount;

    static uint32_t ComputeChecksum(const SkDescriptor* desc) {
        const uint32_t* ptr = (const uint32_t*)desc + 1; // skip the checksum field
        size_t len = desc->fLength - sizeof(uint32_t);
        return SkChecksum::Murmur3(ptr, len);
    }

    // private so no one can create one except our factories
    SkDescriptor() {}
};

#include "SkScalerContext.h"

class SkAutoDescriptor : SkNoncopyable {
public:
    SkAutoDescriptor() : fDesc(NULL) {}
    SkAutoDescriptor(size_t size) : fDesc(NULL) { this->reset(size); }

    ~SkAutoDescriptor() { this->free(); }

    void reset(size_t size) {
        this->free();
        if (size <= sizeof(fStorage)) {
            fDesc = (SkDescriptor*)(void*)fStorage;
        } else {
            fDesc = SkDescriptor::Alloc(size);
        }
    }

    SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; }
private:
    void free() {
        if (fDesc != (SkDescriptor*)(void*)fStorage) {
            SkDescriptor::Free(fDesc);
        }
    }

    enum {
        kStorageSize =  sizeof(SkDescriptor)
                        + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec)    // for rec
                        + sizeof(SkDescriptor::Entry) + sizeof(void*)                   // for typeface
                        + 32   // slop for occational small extras
    };
    SkDescriptor*   fDesc;
    uint32_t        fStorage[(kStorageSize + 3) >> 2];
};
#define SkAutoDescriptor(...) SK_REQUIRE_LOCAL_VAR(SkAutoDescriptor)


#endif
