• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/graphics/views/SkMetaData.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include "SkMetaData.h"
19 #include "SkRefCnt.h"
20 
21 struct PtrPair {
22     void*               fPtr;
23     SkMetaData::PtrProc fProc;
24 };
25 
RefCntProc(void * ptr,bool doRef)26 void* SkMetaData::RefCntProc(void* ptr, bool doRef) {
27     SkASSERT(ptr);
28     SkRefCnt* refcnt = reinterpret_cast<SkRefCnt*>(ptr);
29 
30     if (doRef) {
31         refcnt->ref();
32     } else {
33         refcnt->unref();
34     }
35     return ptr;
36 }
37 
SkMetaData()38 SkMetaData::SkMetaData() : fRec(NULL)
39 {
40 }
41 
SkMetaData(const SkMetaData & src)42 SkMetaData::SkMetaData(const SkMetaData& src) : fRec(NULL)
43 {
44     *this = src;
45 }
46 
~SkMetaData()47 SkMetaData::~SkMetaData()
48 {
49     this->reset();
50 }
51 
reset()52 void SkMetaData::reset()
53 {
54     Rec* rec = fRec;
55     while (rec) {
56         if (kPtr_Type == rec->fType) {
57             PtrPair* pair = (PtrPair*)rec->data();
58             if (pair->fProc && pair->fPtr) {
59                 pair->fPtr = pair->fProc(pair->fPtr, false);
60             }
61         }
62         Rec* next = rec->fNext;
63         Rec::Free(rec);
64         rec = next;
65     }
66     fRec = NULL;
67 }
68 
operator =(const SkMetaData & src)69 SkMetaData& SkMetaData::operator=(const SkMetaData& src)
70 {
71     this->reset();
72 
73     const Rec* rec = src.fRec;
74     while (rec)
75     {
76         this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec->fDataCount);
77         rec = rec->fNext;
78     }
79     return *this;
80 }
81 
setS32(const char name[],int32_t value)82 void SkMetaData::setS32(const char name[], int32_t value)
83 {
84     (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1);
85 }
86 
setScalar(const char name[],SkScalar value)87 void SkMetaData::setScalar(const char name[], SkScalar value)
88 {
89     (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1);
90 }
91 
setScalars(const char name[],int count,const SkScalar values[])92 SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar values[])
93 {
94     SkASSERT(count > 0);
95     if (count > 0)
96         return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type, count);
97     return NULL;
98 }
99 
setString(const char name[],const char value[])100 void SkMetaData::setString(const char name[], const char value[])
101 {
102     (void)this->set(name, value, sizeof(char), kString_Type, strlen(value) + 1);
103 }
104 
setPtr(const char name[],void * ptr,PtrProc proc)105 void SkMetaData::setPtr(const char name[], void* ptr, PtrProc proc) {
106     PtrPair pair = { ptr, proc };
107     (void)this->set(name, &pair, sizeof(PtrPair), kPtr_Type, 1);
108 }
109 
setBool(const char name[],bool value)110 void SkMetaData::setBool(const char name[], bool value)
111 {
112     (void)this->set(name, &value, sizeof(bool), kBool_Type, 1);
113 }
114 
setData(const char name[],const void * data,size_t byteCount)115 void SkMetaData::setData(const char name[], const void* data, size_t byteCount) {
116     (void)this->set(name, data, sizeof(char), kData_Type, byteCount);
117 }
118 
set(const char name[],const void * data,size_t dataSize,Type type,int count)119 void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type type, int count)
120 {
121     SkASSERT(name);
122     SkASSERT(dataSize);
123     SkASSERT(count > 0);
124 
125     (void)this->remove(name, type);
126 
127     size_t  len = strlen(name);
128     Rec*    rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1);
129 
130 #ifndef SK_DEBUG
131     rec->fType = SkToU8(type);
132 #else
133     rec->fType = type;
134 #endif
135     rec->fDataLen = SkToU8(dataSize);
136     rec->fDataCount = SkToU16(count);
137     if (data)
138         memcpy(rec->data(), data, dataSize * count);
139     memcpy(rec->name(), name, len + 1);
140 
141     if (kPtr_Type == type) {
142         PtrPair* pair = (PtrPair*)rec->data();
143         if (pair->fProc && pair->fPtr) {
144             pair->fPtr = pair->fProc(pair->fPtr, true);
145         }
146     }
147 
148     rec->fNext = fRec;
149     fRec = rec;
150     return rec->data();
151 }
152 
findS32(const char name[],int32_t * value) const153 bool SkMetaData::findS32(const char name[], int32_t* value) const
154 {
155     const Rec* rec = this->find(name, kS32_Type);
156     if (rec)
157     {
158         SkASSERT(rec->fDataCount == 1);
159         if (value)
160             *value = *(const int32_t*)rec->data();
161         return true;
162     }
163     return false;
164 }
165 
findScalar(const char name[],SkScalar * value) const166 bool SkMetaData::findScalar(const char name[], SkScalar* value) const
167 {
168     const Rec* rec = this->find(name, kScalar_Type);
169     if (rec)
170     {
171         SkASSERT(rec->fDataCount == 1);
172         if (value)
173             *value = *(const SkScalar*)rec->data();
174         return true;
175     }
176     return false;
177 }
178 
findScalars(const char name[],int * count,SkScalar values[]) const179 const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar values[]) const
180 {
181     const Rec* rec = this->find(name, kScalar_Type);
182     if (rec)
183     {
184         if (count)
185             *count = rec->fDataCount;
186         if (values)
187             memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen);
188         return (const SkScalar*)rec->data();
189     }
190     return NULL;
191 }
192 
findPtr(const char name[],void ** ptr,PtrProc * proc) const193 bool SkMetaData::findPtr(const char name[], void** ptr, PtrProc* proc) const {
194     const Rec* rec = this->find(name, kPtr_Type);
195     if (rec) {
196         SkASSERT(rec->fDataCount == 1);
197         const PtrPair* pair = (const PtrPair*)rec->data();
198         if (ptr) {
199             *ptr = pair->fPtr;
200         }
201         if (proc) {
202             *proc = pair->fProc;
203         }
204         return true;
205     }
206     return false;
207 }
208 
findString(const char name[]) const209 const char* SkMetaData::findString(const char name[]) const
210 {
211     const Rec* rec = this->find(name, kString_Type);
212     SkASSERT(rec == NULL || rec->fDataLen == sizeof(char));
213     return rec ? (const char*)rec->data() : NULL;
214 }
215 
findBool(const char name[],bool * value) const216 bool SkMetaData::findBool(const char name[], bool* value) const
217 {
218     const Rec* rec = this->find(name, kBool_Type);
219     if (rec)
220     {
221         SkASSERT(rec->fDataCount == 1);
222         if (value)
223             *value = *(const bool*)rec->data();
224         return true;
225     }
226     return false;
227 }
228 
findData(const char name[],size_t * length) const229 const void* SkMetaData::findData(const char name[], size_t* length) const {
230     const Rec* rec = this->find(name, kData_Type);
231     if (rec) {
232         SkASSERT(rec->fDataLen == sizeof(char));
233         if (length) {
234             *length = rec->fDataCount;
235         }
236         return rec->data();
237     }
238     return NULL;
239 }
240 
find(const char name[],Type type) const241 const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const
242 {
243     const Rec* rec = fRec;
244     while (rec)
245     {
246         if (rec->fType == type && !strcmp(rec->name(), name))
247             return rec;
248         rec = rec->fNext;
249     }
250     return NULL;
251 }
252 
remove(const char name[],Type type)253 bool SkMetaData::remove(const char name[], Type type) {
254     Rec* rec = fRec;
255     Rec* prev = NULL;
256     while (rec) {
257         Rec* next = rec->fNext;
258         if (rec->fType == type && !strcmp(rec->name(), name)) {
259             if (prev) {
260                 prev->fNext = next;
261             } else {
262                 fRec = next;
263             }
264 
265             if (kPtr_Type == type) {
266                 PtrPair* pair = (PtrPair*)rec->data();
267                 if (pair->fProc && pair->fPtr) {
268                     (void)pair->fProc(pair->fPtr, false);
269                 }
270             }
271             Rec::Free(rec);
272             return true;
273         }
274         prev = rec;
275         rec = next;
276     }
277     return false;
278 }
279 
removeS32(const char name[])280 bool SkMetaData::removeS32(const char name[])
281 {
282     return this->remove(name, kS32_Type);
283 }
284 
removeScalar(const char name[])285 bool SkMetaData::removeScalar(const char name[])
286 {
287     return this->remove(name, kScalar_Type);
288 }
289 
removeString(const char name[])290 bool SkMetaData::removeString(const char name[])
291 {
292     return this->remove(name, kString_Type);
293 }
294 
removePtr(const char name[])295 bool SkMetaData::removePtr(const char name[])
296 {
297     return this->remove(name, kPtr_Type);
298 }
299 
removeBool(const char name[])300 bool SkMetaData::removeBool(const char name[])
301 {
302     return this->remove(name, kBool_Type);
303 }
304 
removeData(const char name[])305 bool SkMetaData::removeData(const char name[]) {
306     return this->remove(name, kData_Type);
307 }
308 
309 ///////////////////////////////////////////////////////////////////////////////
310 
Iter(const SkMetaData & metadata)311 SkMetaData::Iter::Iter(const SkMetaData& metadata) {
312     fRec = metadata.fRec;
313 }
314 
reset(const SkMetaData & metadata)315 void SkMetaData::Iter::reset(const SkMetaData& metadata) {
316     fRec = metadata.fRec;
317 }
318 
next(SkMetaData::Type * t,int * count)319 const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count) {
320     const char* name = NULL;
321 
322     if (fRec) {
323         if (t) {
324             *t = (SkMetaData::Type)fRec->fType;
325         }
326         if (count) {
327             *count = fRec->fDataCount;
328         }
329         name = fRec->name();
330 
331         fRec = fRec->fNext;
332     }
333     return name;
334 }
335 
336 ///////////////////////////////////////////////////////////////////////////////
337 
Alloc(size_t size)338 SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size) {
339     return (Rec*)sk_malloc_throw(size);
340 }
341 
Free(Rec * rec)342 void SkMetaData::Rec::Free(Rec* rec) {
343     sk_free(rec);
344 }
345 
346