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