Home | History | Annotate | Download | only in core
      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 = nullptr) const;
     52     bool findScalar(const char name[], SkScalar* value = nullptr) const;
     53     const SkScalar* findScalars(const char name[], int* count,
     54                                 SkScalar values[] = nullptr) const;
     55     const char* findString(const char name[]) const;
     56     bool findPtr(const char name[], void** value = nullptr, PtrProc* = nullptr) const;
     57     bool findBool(const char name[], bool* value = nullptr) const;
     58     const void* findData(const char name[], size_t* byteCount = nullptr) 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 == nullptr && value == nullptr) ||
     71                 (v != nullptr && value != nullptr && !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[] = nullptr);
     90     void setString(const char name[], const char value[]);
     91     void setPtr(const char name[], void* value, PtrProc proc = nullptr);
     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 = nullptr) {
    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(nullptr) {}
    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