blob: 95097107f2138fbfcd9cefb691b2df49dd1dae08 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkMetaData_DEFINED
18#define SkMetaData_DEFINED
19
20#include "SkScalar.h"
21
22class SkMetaData {
23public:
24 SkMetaData();
25 SkMetaData(const SkMetaData& src);
26 ~SkMetaData();
27
28 SkMetaData& operator=(const SkMetaData& src);
29
30 void reset();
31
32 bool findS32(const char name[], int32_t* value = NULL) const;
33 bool findScalar(const char name[], SkScalar* value = NULL) const;
34 const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const;
35 const char* findString(const char name[]) const;
36 bool findPtr(const char name[], void** value = NULL) const;
37 bool findBool(const char name[], bool* value = NULL) const;
reed@android.comf2b98d62010-12-20 18:26:13 +000038 const void* findData(const char name[], size_t* byteCount = NULL) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +000039
40 bool hasS32(const char name[], int32_t value) const
41 {
42 int32_t v;
43 return this->findS32(name, &v) && v == value;
44 }
45 bool hasScalar(const char name[], SkScalar value) const
46 {
47 SkScalar v;
48 return this->findScalar(name, &v) && v == value;
49 }
50 bool hasString(const char name[], const char value[]) const
51 {
52 const char* v = this->findString(name);
53 return v == NULL && value == NULL ||
54 v != NULL && value != NULL && !strcmp(v, value);
55 }
56 bool hasPtr(const char name[], void* value) const
57 {
58 void* v;
59 return this->findPtr(name, &v) && v == value;
60 }
61 bool hasBool(const char name[], bool value) const
62 {
63 bool v;
64 return this->findBool(name, &v) && v == value;
65 }
reed@android.comf2b98d62010-12-20 18:26:13 +000066 bool hasData(const char name[], const void* data, size_t byteCount) const {
67 size_t len;
68 const void* ptr = this->findData(name, &len);
69 return NULL != ptr && len == byteCount && !memcmp(ptr, data, len);
70 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000071
72 void setS32(const char name[], int32_t value);
73 void setScalar(const char name[], SkScalar value);
74 SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL);
75 void setString(const char name[], const char value[]);
76 void setPtr(const char name[], void* value);
77 void setBool(const char name[], bool value);
reed@android.comf2b98d62010-12-20 18:26:13 +000078 // the data is copied from the input pointer.
79 void setData(const char name[], const void* data, size_t byteCount);
reed@android.com8a1c16f2008-12-17 15:59:43 +000080
81 bool removeS32(const char name[]);
82 bool removeScalar(const char name[]);
83 bool removeString(const char name[]);
84 bool removePtr(const char name[]);
85 bool removeBool(const char name[]);
reed@android.comf2b98d62010-12-20 18:26:13 +000086 bool removeData(const char name[]);
reed@android.com8a1c16f2008-12-17 15:59:43 +000087
88 SkDEBUGCODE(static void UnitTest();)
89
90 enum Type {
91 kS32_Type,
92 kScalar_Type,
93 kString_Type,
94 kPtr_Type,
95 kBool_Type,
reed@android.comf2b98d62010-12-20 18:26:13 +000096 kData_Type,
reed@android.com8a1c16f2008-12-17 15:59:43 +000097
98 kTypeCount
99 };
100
101 struct Rec;
102 class Iter;
103 friend class Iter;
104
105 class Iter {
106 public:
107 Iter() : fRec(NULL) {}
108 Iter(const SkMetaData&);
109
110 /** Reset the iterator, so that calling next() will return the first
111 data element. This is done implicitly in the constructor.
112 */
113 void reset(const SkMetaData&);
114
115 /** Each time next is called, it returns the name of the next data element,
116 or null when there are no more elements. If non-null is returned, then the
117 element's type is returned (if not null), and the number of data values
118 is returned in count (if not null).
119 */
120 const char* next(Type*, int* count);
121
122 private:
123 Rec* fRec;
124 };
125
126public:
127 struct Rec {
128 Rec* fNext;
129 uint16_t fDataCount; // number of elements
130 uint8_t fDataLen; // sizeof a single element
131#ifdef SK_DEBUG
132 Type fType;
133#else
134 uint8_t fType;
135#endif
136
137#ifdef SK_DEBUG
138 const char* fName;
139 union {
140 int32_t fS32;
141 SkScalar fScalar;
142 const char* fString;
143 void* fPtr;
144 bool fBool;
145 } fData;
146#endif
147
148 const void* data() const { return (this + 1); }
149 void* data() { return (this + 1); }
150 const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
151 char* name() { return (char*)this->data() + fDataLen * fDataCount; }
152
153 static Rec* Alloc(size_t);
154 static void Free(Rec*);
155 };
156 Rec* fRec;
157
158 const Rec* find(const char name[], Type) const;
159 void* set(const char name[], const void* data, size_t len, Type, int count);
160 bool remove(const char name[], Type);
161};
162
163#endif
164