1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkMetaData_DEFINED 11 #define SkMetaData_DEFINED 12 13 #include "SkScalar.h" 14 15 class SkRefCnt; 16 17 class SK_API SkMetaData { 18 public: 19 /** 20 * Used to manage the life-cycle of a ptr in the metadata. This is option 21 * in setPtr, and is only invoked when either copying one metadata to 22 * another, or when the metadata is destroyed. 23 * 24 * setPtr(name, ptr, proc) { 25 * fPtr = proc(ptr, true); 26 * } 27 * 28 * copy: A = B { 29 * A.fPtr = B.fProc(B.fPtr, true); 30 * } 31 * 32 * ~SkMetaData { 33 * fProc(fPtr, false); 34 * } 35 */ 36 typedef void* (*PtrProc)(void* ptr, bool doRef); 37 38 /** 39 * Implements PtrProc for SkRefCnt pointers 40 */ 41 static void* RefCntProc(void* ptr, bool doRef); 42 43 SkMetaData(); 44 SkMetaData(const SkMetaData& src); 45 ~SkMetaData(); 46 47 SkMetaData& operator=(const SkMetaData& src); 48 49 void reset(); 50 51 bool findS32(const char name[], int32_t* value = NULL) const; 52 bool findScalar(const char name[], SkScalar* value = NULL) const; 53 const SkScalar* findScalars(const char name[], int* count, 54 SkScalar values[] = NULL) const; 55 const char* findString(const char name[]) const; 56 bool findPtr(const char name[], void** value = NULL, PtrProc* = NULL) const; 57 bool findBool(const char name[], bool* value = NULL) const; 58 const void* findData(const char name[], size_t* byteCount = NULL) const; 59 60 bool hasS32(const char name[], int32_t value) const { 61 int32_t v; 62 return this->findS32(name, &v) && v == value; 63 } 64 bool hasScalar(const char name[], SkScalar value) const { 65 SkScalar v; 66 return this->findScalar(name, &v) && v == value; 67 } 68 bool hasString(const char name[], const char value[]) const { 69 const char* v = this->findString(name); 70 return (v == NULL && value == NULL) || 71 (v != NULL && value != NULL && !strcmp(v, value)); 72 } 73 bool hasPtr(const char name[], void* value) const { 74 void* v; 75 return this->findPtr(name, &v) && v == value; 76 } 77 bool hasBool(const char name[], bool value) const { 78 bool v; 79 return this->findBool(name, &v) && v == value; 80 } 81 bool hasData(const char name[], const void* data, size_t byteCount) const { 82 size_t len; 83 const void* ptr = this->findData(name, &len); 84 return ptr && len == byteCount && !memcmp(ptr, data, len); 85 } 86 87 void setS32(const char name[], int32_t value); 88 void setScalar(const char name[], SkScalar value); 89 SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL); 90 void setString(const char name[], const char value[]); 91 void setPtr(const char name[], void* value, PtrProc proc = NULL); 92 void setBool(const char name[], bool value); 93 // the data is copied from the input pointer. 94 void setData(const char name[], const void* data, size_t byteCount); 95 96 bool removeS32(const char name[]); 97 bool removeScalar(const char name[]); 98 bool removeString(const char name[]); 99 bool removePtr(const char name[]); 100 bool removeBool(const char name[]); 101 bool removeData(const char name[]); 102 103 // helpers for SkRefCnt 104 bool findRefCnt(const char name[], SkRefCnt** ptr = NULL) { 105 return this->findPtr(name, reinterpret_cast<void**>(ptr)); 106 } 107 bool hasRefCnt(const char name[], SkRefCnt* ptr) { 108 return this->hasPtr(name, ptr); 109 } 110 void setRefCnt(const char name[], SkRefCnt* ptr) { 111 this->setPtr(name, ptr, RefCntProc); 112 } 113 bool removeRefCnt(const char name[]) { 114 return this->removePtr(name); 115 } 116 117 enum Type { 118 kS32_Type, 119 kScalar_Type, 120 kString_Type, 121 kPtr_Type, 122 kBool_Type, 123 kData_Type, 124 125 kTypeCount 126 }; 127 128 struct Rec; 129 class Iter; 130 friend class Iter; 131 132 class Iter { 133 public: 134 Iter() : fRec(NULL) {} 135 Iter(const SkMetaData&); 136 137 /** Reset the iterator, so that calling next() will return the first 138 data element. This is done implicitly in the constructor. 139 */ 140 void reset(const SkMetaData&); 141 142 /** Each time next is called, it returns the name of the next data element, 143 or null when there are no more elements. If non-null is returned, then the 144 element's type is returned (if not null), and the number of data values 145 is returned in count (if not null). 146 */ 147 const char* next(Type*, int* count); 148 149 private: 150 Rec* fRec; 151 }; 152 153 public: 154 struct Rec { 155 Rec* fNext; 156 uint16_t fDataCount; // number of elements 157 uint8_t fDataLen; // sizeof a single element 158 uint8_t fType; 159 160 const void* data() const { return (this + 1); } 161 void* data() { return (this + 1); } 162 const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; } 163 char* name() { return (char*)this->data() + fDataLen * fDataCount; } 164 165 static Rec* Alloc(size_t); 166 static void Free(Rec*); 167 }; 168 Rec* fRec; 169 170 const Rec* find(const char name[], Type) const; 171 void* set(const char name[], const void* data, size_t len, Type, int count); 172 bool remove(const char name[], Type); 173 }; 174 175 #endif 176