aboutsummaryrefslogtreecommitdiffstats
path: root/include/views/SkMetaData.h
blob: 95097107f2138fbfcd9cefb691b2df49dd1dae08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SkMetaData_DEFINED
#define SkMetaData_DEFINED

#include "SkScalar.h"

class SkMetaData {
public:
    SkMetaData();
    SkMetaData(const SkMetaData& src);
    ~SkMetaData();

    SkMetaData& operator=(const SkMetaData& src);

    void    reset();

    bool    findS32(const char name[], int32_t* value = NULL) const;
    bool    findScalar(const char name[], SkScalar* value = NULL) const;
    const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const;
    const char* findString(const char name[]) const;
    bool    findPtr(const char name[], void** value = NULL) const;
    bool    findBool(const char name[], bool* value = NULL) const;
    const void* findData(const char name[], size_t* byteCount = NULL) const;

    bool    hasS32(const char name[], int32_t value) const
    {
        int32_t v;
        return this->findS32(name, &v) && v == value;
    }
    bool    hasScalar(const char name[], SkScalar value) const
    {
        SkScalar    v;
        return this->findScalar(name, &v) && v == value;
    }
    bool    hasString(const char name[], const char value[]) const
    {
        const char* v = this->findString(name);
        return  v == NULL && value == NULL ||
                v != NULL && value != NULL && !strcmp(v, value);
    }
    bool    hasPtr(const char name[], void* value) const
    {
        void*   v;
        return this->findPtr(name, &v) && v == value;
    }
    bool    hasBool(const char name[], bool value) const
    {
        bool    v;
        return this->findBool(name, &v) && v == value;
    }
    bool hasData(const char name[], const void* data, size_t byteCount) const {
        size_t len;
        const void* ptr = this->findData(name, &len);
        return NULL != ptr && len == byteCount && !memcmp(ptr, data, len);
    }

    void    setS32(const char name[], int32_t value);
    void    setScalar(const char name[], SkScalar value);
    SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL);
    void    setString(const char name[], const char value[]);
    void    setPtr(const char name[], void* value);
    void    setBool(const char name[], bool value);
    // the data is copied from the input pointer.
    void    setData(const char name[], const void* data, size_t byteCount);

    bool    removeS32(const char name[]);
    bool    removeScalar(const char name[]);
    bool    removeString(const char name[]);
    bool    removePtr(const char name[]);
    bool    removeBool(const char name[]);
    bool    removeData(const char name[]);

    SkDEBUGCODE(static void UnitTest();)

    enum Type {
        kS32_Type,
        kScalar_Type,
        kString_Type,
        kPtr_Type,
        kBool_Type,
        kData_Type,

        kTypeCount
    };

    struct Rec;
    class Iter;
    friend class Iter;

    class Iter {
    public:
        Iter() : fRec(NULL) {}
        Iter(const SkMetaData&);

        /** Reset the iterator, so that calling next() will return the first
            data element. This is done implicitly in the constructor.
        */
        void    reset(const SkMetaData&);

        /** Each time next is called, it returns the name of the next data element,
            or null when there are no more elements. If non-null is returned, then the
            element's type is returned (if not null), and the number of data values
            is returned in count (if not null).
        */
        const char* next(Type*, int* count);

    private:
        Rec* fRec;
    };

public:
    struct Rec {
        Rec*        fNext;
        uint16_t    fDataCount; // number of elements
        uint8_t     fDataLen;   // sizeof a single element
#ifdef SK_DEBUG
        Type        fType;
#else
        uint8_t     fType;
#endif

#ifdef SK_DEBUG
        const char* fName;
        union {
            int32_t     fS32;
            SkScalar    fScalar;
            const char* fString;
            void*       fPtr;
            bool        fBool;
        } fData;
#endif

        const void* data() const { return (this + 1); }
        void*       data() { return (this + 1); }
        const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
        char*       name() { return (char*)this->data() + fDataLen * fDataCount; }

        static Rec* Alloc(size_t);
        static void Free(Rec*);
    };
    Rec*    fRec;

    const Rec* find(const char name[], Type) const;
    void* set(const char name[], const void* data, size_t len, Type, int count);
    bool remove(const char name[], Type);
};

#endif