Home | History | Annotate | Download | only in core
      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