xref: /third_party/skia/tools/SkMetaData.h (revision cb93a386)
1/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkMetaData_DEFINED
8#define SkMetaData_DEFINED
9
10#include "include/core/SkScalar.h"
11
12/** A map from c-string keys to arrays of POD (int32_t, kScalar, void*, or bool)
13    values.
14*/
15class SkMetaData {
16public:
17    SkMetaData() {}
18    ~SkMetaData() { if (fRec) { this->reset(); } }
19    void reset();
20
21    bool findS32(const char name[], int32_t* value = nullptr) const;
22    bool findScalar(const char name[], SkScalar* value = nullptr) const;
23    const SkScalar* findScalars(const char name[], int* count,
24                                SkScalar values[] = nullptr) const;
25    bool findPtr(const char name[], void** value = nullptr) const;
26    bool findBool(const char name[], bool* value = nullptr) const;
27
28    bool hasS32(const char name[], int32_t value) const {
29        int32_t v;
30        return this->findS32(name, &v) && v == value;
31    }
32    bool hasScalar(const char name[], SkScalar value) const {
33        SkScalar v;
34        return this->findScalar(name, &v) && v == value;
35    }
36    bool hasPtr(const char name[], void* value) const {
37        void* v;
38        return this->findPtr(name, &v) && v == value;
39    }
40    bool hasBool(const char name[], bool value) const {
41        bool    v;
42        return this->findBool(name, &v) && v == value;
43    }
44
45    void setS32(const char name[], int32_t value);
46    void setScalar(const char name[], SkScalar value);
47    SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nullptr);
48    void setPtr(const char name[], void* value);
49    void setBool(const char name[], bool value);
50
51    bool removeS32(const char name[]);
52    bool removeScalar(const char name[]);
53    bool removePtr(const char name[]);
54    bool removeBool(const char name[]);
55
56    enum Type {
57        kS32_Type,
58        kScalar_Type,
59        kPtr_Type,
60        kBool_Type,
61
62        kTypeCount
63    };
64
65    struct Rec;
66    class Iter;
67    friend class Iter;
68
69    class Iter {
70    public:
71        Iter() : fRec(nullptr) {}
72        Iter(const SkMetaData&);
73
74        /** Reset the iterator, so that calling next() will return the first
75            data element. This is done implicitly in the constructor.
76        */
77        void reset(const SkMetaData&);
78
79        /** Each time next is called, it returns the name of the next data element,
80            or null when there are no more elements. If non-null is returned, then the
81            element's type is returned (if not null), and the number of data values
82            is returned in count (if not null).
83        */
84        const char* next(Type*, int* count);
85
86    private:
87        Rec* fRec;
88    };
89
90public:
91    struct Rec {
92        Rec*        fNext;
93        uint16_t    fDataCount; // number of elements
94        uint8_t     fDataLen;   // sizeof a single element
95        uint8_t     fType;
96
97        const void* data() const { return (this + 1); }
98        void*       data() { return (this + 1); }
99        const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
100        char*       name() { return (char*)this->data() + fDataLen * fDataCount; }
101
102        static Rec* Alloc(size_t);
103        static void Free(Rec*);
104    };
105    Rec*    fRec = nullptr;
106
107    const Rec* find(const char name[], Type) const;
108    void* set(const char name[], const void* data, size_t len, Type, int count);
109    bool remove(const char name[], Type);
110
111    SkMetaData(const SkMetaData&) = delete;
112    SkMetaData& operator=(const SkMetaData&) = delete;
113
114private:
115    struct FindResult {
116        SkMetaData::Rec* rec;
117        SkMetaData::Rec* prev;
118    };
119    FindResult findWithPrev(const char name[], Type type) const;
120    void remove(FindResult);
121};
122
123#endif
124