1 /* libs/graphics/views/SkMetaData.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "SkMetaData.h" 19 #include "SkRefCnt.h" 20 21 struct PtrPair { 22 void* fPtr; 23 SkMetaData::PtrProc fProc; 24 }; 25 26 void* SkMetaData::RefCntProc(void* ptr, bool doRef) { 27 SkASSERT(ptr); 28 SkRefCnt* refcnt = reinterpret_cast<SkRefCnt*>(ptr); 29 30 if (doRef) { 31 refcnt->ref(); 32 } else { 33 refcnt->unref(); 34 } 35 return ptr; 36 } 37 38 SkMetaData::SkMetaData() : fRec(NULL) 39 { 40 } 41 42 SkMetaData::SkMetaData(const SkMetaData& src) : fRec(NULL) 43 { 44 *this = src; 45 } 46 47 SkMetaData::~SkMetaData() 48 { 49 this->reset(); 50 } 51 52 void SkMetaData::reset() 53 { 54 Rec* rec = fRec; 55 while (rec) { 56 if (kPtr_Type == rec->fType) { 57 PtrPair* pair = (PtrPair*)rec->data(); 58 if (pair->fProc && pair->fPtr) { 59 pair->fPtr = pair->fProc(pair->fPtr, false); 60 } 61 } 62 Rec* next = rec->fNext; 63 Rec::Free(rec); 64 rec = next; 65 } 66 fRec = NULL; 67 } 68 69 SkMetaData& SkMetaData::operator=(const SkMetaData& src) 70 { 71 this->reset(); 72 73 const Rec* rec = src.fRec; 74 while (rec) 75 { 76 this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec->fDataCount); 77 rec = rec->fNext; 78 } 79 return *this; 80 } 81 82 void SkMetaData::setS32(const char name[], int32_t value) 83 { 84 (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1); 85 } 86 87 void SkMetaData::setScalar(const char name[], SkScalar value) 88 { 89 (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1); 90 } 91 92 SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar values[]) 93 { 94 SkASSERT(count > 0); 95 if (count > 0) 96 return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type, count); 97 return NULL; 98 } 99 100 void SkMetaData::setString(const char name[], const char value[]) 101 { 102 (void)this->set(name, value, sizeof(char), kString_Type, strlen(value) + 1); 103 } 104 105 void SkMetaData::setPtr(const char name[], void* ptr, PtrProc proc) { 106 PtrPair pair = { ptr, proc }; 107 (void)this->set(name, &pair, sizeof(PtrPair), kPtr_Type, 1); 108 } 109 110 void SkMetaData::setBool(const char name[], bool value) 111 { 112 (void)this->set(name, &value, sizeof(bool), kBool_Type, 1); 113 } 114 115 void SkMetaData::setData(const char name[], const void* data, size_t byteCount) { 116 (void)this->set(name, data, sizeof(char), kData_Type, byteCount); 117 } 118 119 void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type type, int count) 120 { 121 SkASSERT(name); 122 SkASSERT(dataSize); 123 SkASSERT(count > 0); 124 125 (void)this->remove(name, type); 126 127 size_t len = strlen(name); 128 Rec* rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1); 129 130 #ifndef SK_DEBUG 131 rec->fType = SkToU8(type); 132 #else 133 rec->fType = type; 134 #endif 135 rec->fDataLen = SkToU8(dataSize); 136 rec->fDataCount = SkToU16(count); 137 if (data) 138 memcpy(rec->data(), data, dataSize * count); 139 memcpy(rec->name(), name, len + 1); 140 141 if (kPtr_Type == type) { 142 PtrPair* pair = (PtrPair*)rec->data(); 143 if (pair->fProc && pair->fPtr) { 144 pair->fPtr = pair->fProc(pair->fPtr, true); 145 } 146 } 147 148 rec->fNext = fRec; 149 fRec = rec; 150 return rec->data(); 151 } 152 153 bool SkMetaData::findS32(const char name[], int32_t* value) const 154 { 155 const Rec* rec = this->find(name, kS32_Type); 156 if (rec) 157 { 158 SkASSERT(rec->fDataCount == 1); 159 if (value) 160 *value = *(const int32_t*)rec->data(); 161 return true; 162 } 163 return false; 164 } 165 166 bool SkMetaData::findScalar(const char name[], SkScalar* value) const 167 { 168 const Rec* rec = this->find(name, kScalar_Type); 169 if (rec) 170 { 171 SkASSERT(rec->fDataCount == 1); 172 if (value) 173 *value = *(const SkScalar*)rec->data(); 174 return true; 175 } 176 return false; 177 } 178 179 const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar values[]) const 180 { 181 const Rec* rec = this->find(name, kScalar_Type); 182 if (rec) 183 { 184 if (count) 185 *count = rec->fDataCount; 186 if (values) 187 memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen); 188 return (const SkScalar*)rec->data(); 189 } 190 return NULL; 191 } 192 193 bool SkMetaData::findPtr(const char name[], void** ptr, PtrProc* proc) const { 194 const Rec* rec = this->find(name, kPtr_Type); 195 if (rec) { 196 SkASSERT(rec->fDataCount == 1); 197 const PtrPair* pair = (const PtrPair*)rec->data(); 198 if (ptr) { 199 *ptr = pair->fPtr; 200 } 201 if (proc) { 202 *proc = pair->fProc; 203 } 204 return true; 205 } 206 return false; 207 } 208 209 const char* SkMetaData::findString(const char name[]) const 210 { 211 const Rec* rec = this->find(name, kString_Type); 212 SkASSERT(rec == NULL || rec->fDataLen == sizeof(char)); 213 return rec ? (const char*)rec->data() : NULL; 214 } 215 216 bool SkMetaData::findBool(const char name[], bool* value) const 217 { 218 const Rec* rec = this->find(name, kBool_Type); 219 if (rec) 220 { 221 SkASSERT(rec->fDataCount == 1); 222 if (value) 223 *value = *(const bool*)rec->data(); 224 return true; 225 } 226 return false; 227 } 228 229 const void* SkMetaData::findData(const char name[], size_t* length) const { 230 const Rec* rec = this->find(name, kData_Type); 231 if (rec) { 232 SkASSERT(rec->fDataLen == sizeof(char)); 233 if (length) { 234 *length = rec->fDataCount; 235 } 236 return rec->data(); 237 } 238 return NULL; 239 } 240 241 const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const 242 { 243 const Rec* rec = fRec; 244 while (rec) 245 { 246 if (rec->fType == type && !strcmp(rec->name(), name)) 247 return rec; 248 rec = rec->fNext; 249 } 250 return NULL; 251 } 252 253 bool SkMetaData::remove(const char name[], Type type) { 254 Rec* rec = fRec; 255 Rec* prev = NULL; 256 while (rec) { 257 Rec* next = rec->fNext; 258 if (rec->fType == type && !strcmp(rec->name(), name)) { 259 if (prev) { 260 prev->fNext = next; 261 } else { 262 fRec = next; 263 } 264 265 if (kPtr_Type == type) { 266 PtrPair* pair = (PtrPair*)rec->data(); 267 if (pair->fProc && pair->fPtr) { 268 (void)pair->fProc(pair->fPtr, false); 269 } 270 } 271 Rec::Free(rec); 272 return true; 273 } 274 prev = rec; 275 rec = next; 276 } 277 return false; 278 } 279 280 bool SkMetaData::removeS32(const char name[]) 281 { 282 return this->remove(name, kS32_Type); 283 } 284 285 bool SkMetaData::removeScalar(const char name[]) 286 { 287 return this->remove(name, kScalar_Type); 288 } 289 290 bool SkMetaData::removeString(const char name[]) 291 { 292 return this->remove(name, kString_Type); 293 } 294 295 bool SkMetaData::removePtr(const char name[]) 296 { 297 return this->remove(name, kPtr_Type); 298 } 299 300 bool SkMetaData::removeBool(const char name[]) 301 { 302 return this->remove(name, kBool_Type); 303 } 304 305 bool SkMetaData::removeData(const char name[]) { 306 return this->remove(name, kData_Type); 307 } 308 309 /////////////////////////////////////////////////////////////////////////////// 310 311 SkMetaData::Iter::Iter(const SkMetaData& metadata) { 312 fRec = metadata.fRec; 313 } 314 315 void SkMetaData::Iter::reset(const SkMetaData& metadata) { 316 fRec = metadata.fRec; 317 } 318 319 const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count) { 320 const char* name = NULL; 321 322 if (fRec) { 323 if (t) { 324 *t = (SkMetaData::Type)fRec->fType; 325 } 326 if (count) { 327 *count = fRec->fDataCount; 328 } 329 name = fRec->name(); 330 331 fRec = fRec->fNext; 332 } 333 return name; 334 } 335 336 /////////////////////////////////////////////////////////////////////////////// 337 338 SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size) { 339 return (Rec*)sk_malloc_throw(size); 340 } 341 342 void SkMetaData::Rec::Free(Rec* rec) { 343 sk_free(rec); 344 } 345 346