michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkMetaData_DEFINED michael@0: #define SkMetaData_DEFINED michael@0: michael@0: #include "SkScalar.h" michael@0: michael@0: class SkRefCnt; michael@0: michael@0: class SK_API SkMetaData { michael@0: public: michael@0: /** michael@0: * Used to manage the life-cycle of a ptr in the metadata. This is option michael@0: * in setPtr, and is only invoked when either copying one metadata to michael@0: * another, or when the metadata is destroyed. michael@0: * michael@0: * setPtr(name, ptr, proc) { michael@0: * fPtr = proc(ptr, true); michael@0: * } michael@0: * michael@0: * copy: A = B { michael@0: * A.fPtr = B.fProc(B.fPtr, true); michael@0: * } michael@0: * michael@0: * ~SkMetaData { michael@0: * fProc(fPtr, false); michael@0: * } michael@0: */ michael@0: typedef void* (*PtrProc)(void* ptr, bool doRef); michael@0: michael@0: /** michael@0: * Implements PtrProc for SkRefCnt pointers michael@0: */ michael@0: static void* RefCntProc(void* ptr, bool doRef); michael@0: michael@0: SkMetaData(); michael@0: SkMetaData(const SkMetaData& src); michael@0: ~SkMetaData(); michael@0: michael@0: SkMetaData& operator=(const SkMetaData& src); michael@0: michael@0: void reset(); michael@0: michael@0: bool findS32(const char name[], int32_t* value = NULL) const; michael@0: bool findScalar(const char name[], SkScalar* value = NULL) const; michael@0: const SkScalar* findScalars(const char name[], int* count, michael@0: SkScalar values[] = NULL) const; michael@0: const char* findString(const char name[]) const; michael@0: bool findPtr(const char name[], void** value = NULL, PtrProc* = NULL) const; michael@0: bool findBool(const char name[], bool* value = NULL) const; michael@0: const void* findData(const char name[], size_t* byteCount = NULL) const; michael@0: michael@0: bool hasS32(const char name[], int32_t value) const { michael@0: int32_t v; michael@0: return this->findS32(name, &v) && v == value; michael@0: } michael@0: bool hasScalar(const char name[], SkScalar value) const { michael@0: SkScalar v; michael@0: return this->findScalar(name, &v) && v == value; michael@0: } michael@0: bool hasString(const char name[], const char value[]) const { michael@0: const char* v = this->findString(name); michael@0: return (v == NULL && value == NULL) || michael@0: (v != NULL && value != NULL && !strcmp(v, value)); michael@0: } michael@0: bool hasPtr(const char name[], void* value) const { michael@0: void* v; michael@0: return this->findPtr(name, &v) && v == value; michael@0: } michael@0: bool hasBool(const char name[], bool value) const { michael@0: bool v; michael@0: return this->findBool(name, &v) && v == value; michael@0: } michael@0: bool hasData(const char name[], const void* data, size_t byteCount) const { michael@0: size_t len; michael@0: const void* ptr = this->findData(name, &len); michael@0: return NULL != ptr && len == byteCount && !memcmp(ptr, data, len); michael@0: } michael@0: michael@0: void setS32(const char name[], int32_t value); michael@0: void setScalar(const char name[], SkScalar value); michael@0: SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL); michael@0: void setString(const char name[], const char value[]); michael@0: void setPtr(const char name[], void* value, PtrProc proc = NULL); michael@0: void setBool(const char name[], bool value); michael@0: // the data is copied from the input pointer. michael@0: void setData(const char name[], const void* data, size_t byteCount); michael@0: michael@0: bool removeS32(const char name[]); michael@0: bool removeScalar(const char name[]); michael@0: bool removeString(const char name[]); michael@0: bool removePtr(const char name[]); michael@0: bool removeBool(const char name[]); michael@0: bool removeData(const char name[]); michael@0: michael@0: // helpers for SkRefCnt michael@0: bool findRefCnt(const char name[], SkRefCnt** ptr = NULL) { michael@0: return this->findPtr(name, reinterpret_cast(ptr)); michael@0: } michael@0: bool hasRefCnt(const char name[], SkRefCnt* ptr) { michael@0: return this->hasPtr(name, ptr); michael@0: } michael@0: void setRefCnt(const char name[], SkRefCnt* ptr) { michael@0: this->setPtr(name, ptr, RefCntProc); michael@0: } michael@0: bool removeRefCnt(const char name[]) { michael@0: return this->removePtr(name); michael@0: } michael@0: michael@0: enum Type { michael@0: kS32_Type, michael@0: kScalar_Type, michael@0: kString_Type, michael@0: kPtr_Type, michael@0: kBool_Type, michael@0: kData_Type, michael@0: michael@0: kTypeCount michael@0: }; michael@0: michael@0: struct Rec; michael@0: class Iter; michael@0: friend class Iter; michael@0: michael@0: class Iter { michael@0: public: michael@0: Iter() : fRec(NULL) {} michael@0: Iter(const SkMetaData&); michael@0: michael@0: /** Reset the iterator, so that calling next() will return the first michael@0: data element. This is done implicitly in the constructor. michael@0: */ michael@0: void reset(const SkMetaData&); michael@0: michael@0: /** Each time next is called, it returns the name of the next data element, michael@0: or null when there are no more elements. If non-null is returned, then the michael@0: element's type is returned (if not null), and the number of data values michael@0: is returned in count (if not null). michael@0: */ michael@0: const char* next(Type*, int* count); michael@0: michael@0: private: michael@0: Rec* fRec; michael@0: }; michael@0: michael@0: public: michael@0: struct Rec { michael@0: Rec* fNext; michael@0: uint16_t fDataCount; // number of elements michael@0: uint8_t fDataLen; // sizeof a single element michael@0: uint8_t fType; michael@0: michael@0: const void* data() const { return (this + 1); } michael@0: void* data() { return (this + 1); } michael@0: const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; } michael@0: char* name() { return (char*)this->data() + fDataLen * fDataCount; } michael@0: michael@0: static Rec* Alloc(size_t); michael@0: static void Free(Rec*); michael@0: }; michael@0: Rec* fRec; michael@0: michael@0: const Rec* find(const char name[], Type) const; michael@0: void* set(const char name[], const void* data, size_t len, Type, int count); michael@0: bool remove(const char name[], Type); michael@0: }; michael@0: michael@0: #endif