blob: a8ebaac2adbb8ba01200a9bb3600884d5ce2e55b [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkMetaData_DEFINED
11#define SkMetaData_DEFINED
12
13#include "SkScalar.h"
14
reed@google.come7330712011-03-30 18:23:21 +000015class SkRefCnt;
16
reed@google.comf3166342011-04-26 20:06:08 +000017class SK_API SkMetaData {
reed@android.com8a1c16f2008-12-17 15:59:43 +000018public:
reed@google.come7330712011-03-30 18:23:21 +000019 /**
20 * Used to manage the life-cycle of a ptr in the metadata. This is option
21 * in setPtr, and is only invoked when either copying one metadata to
22 * another, or when the metadata is destroyed.
23 *
24 * setPtr(name, ptr, proc) {
25 * fPtr = proc(ptr, true);
26 * }
27 *
28 * copy: A = B {
29 * A.fPtr = B.fProc(B.fPtr, true);
30 * }
31 *
32 * ~SkMetaData {
33 * fProc(fPtr, false);
34 * }
35 */
36 typedef void* (*PtrProc)(void* ptr, bool doRef);
37
38 /**
39 * Implements PtrProc for SkRefCnt pointers
40 */
41 static void* RefCntProc(void* ptr, bool doRef);
42
reed@android.com8a1c16f2008-12-17 15:59:43 +000043 SkMetaData();
44 SkMetaData(const SkMetaData& src);
45 ~SkMetaData();
46
47 SkMetaData& operator=(const SkMetaData& src);
48
reed@google.come7330712011-03-30 18:23:21 +000049 void reset();
reed@android.com8a1c16f2008-12-17 15:59:43 +000050
Ben Wagnera93a14a2017-08-28 10:34:05 -040051 bool findS32(const char name[], int32_t* value = nullptr) const;
52 bool findScalar(const char name[], SkScalar* value = nullptr) const;
reed@google.come7330712011-03-30 18:23:21 +000053 const SkScalar* findScalars(const char name[], int* count,
Ben Wagnera93a14a2017-08-28 10:34:05 -040054 SkScalar values[] = nullptr) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +000055 const char* findString(const char name[]) const;
Ben Wagnera93a14a2017-08-28 10:34:05 -040056 bool findPtr(const char name[], void** value = nullptr, PtrProc* = nullptr) const;
57 bool findBool(const char name[], bool* value = nullptr) const;
58 const void* findData(const char name[], size_t* byteCount = nullptr) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +000059
reed@google.come7330712011-03-30 18:23:21 +000060 bool hasS32(const char name[], int32_t value) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000061 int32_t v;
62 return this->findS32(name, &v) && v == value;
63 }
reed@google.come7330712011-03-30 18:23:21 +000064 bool hasScalar(const char name[], SkScalar value) const {
65 SkScalar v;
reed@android.com8a1c16f2008-12-17 15:59:43 +000066 return this->findScalar(name, &v) && v == value;
67 }
reed@google.come7330712011-03-30 18:23:21 +000068 bool hasString(const char name[], const char value[]) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 const char* v = this->findString(name);
Ben Wagnera93a14a2017-08-28 10:34:05 -040070 return (v == nullptr && value == nullptr) ||
71 (v != nullptr && value != nullptr && !strcmp(v, value));
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 }
reed@google.come7330712011-03-30 18:23:21 +000073 bool hasPtr(const char name[], void* value) const {
74 void* v;
reed@android.com8a1c16f2008-12-17 15:59:43 +000075 return this->findPtr(name, &v) && v == value;
76 }
reed@google.come7330712011-03-30 18:23:21 +000077 bool hasBool(const char name[], bool value) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000078 bool v;
79 return this->findBool(name, &v) && v == value;
80 }
reed@android.comf2b98d62010-12-20 18:26:13 +000081 bool hasData(const char name[], const void* data, size_t byteCount) const {
82 size_t len;
83 const void* ptr = this->findData(name, &len);
bsalomon49f085d2014-09-05 13:34:00 -070084 return ptr && len == byteCount && !memcmp(ptr, data, len);
reed@android.comf2b98d62010-12-20 18:26:13 +000085 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000086
reed@google.come7330712011-03-30 18:23:21 +000087 void setS32(const char name[], int32_t value);
88 void setScalar(const char name[], SkScalar value);
Ben Wagnera93a14a2017-08-28 10:34:05 -040089 SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nullptr);
reed@google.come7330712011-03-30 18:23:21 +000090 void setString(const char name[], const char value[]);
Ben Wagnera93a14a2017-08-28 10:34:05 -040091 void setPtr(const char name[], void* value, PtrProc proc = nullptr);
reed@google.come7330712011-03-30 18:23:21 +000092 void setBool(const char name[], bool value);
reed@android.comf2b98d62010-12-20 18:26:13 +000093 // the data is copied from the input pointer.
reed@google.come7330712011-03-30 18:23:21 +000094 void setData(const char name[], const void* data, size_t byteCount);
reed@android.com8a1c16f2008-12-17 15:59:43 +000095
reed@google.come7330712011-03-30 18:23:21 +000096 bool removeS32(const char name[]);
97 bool removeScalar(const char name[]);
98 bool removeString(const char name[]);
99 bool removePtr(const char name[]);
100 bool removeBool(const char name[]);
101 bool removeData(const char name[]);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102
reed@google.come7330712011-03-30 18:23:21 +0000103 // helpers for SkRefCnt
Ben Wagnera93a14a2017-08-28 10:34:05 -0400104 bool findRefCnt(const char name[], SkRefCnt** ptr = nullptr) {
reed@google.come7330712011-03-30 18:23:21 +0000105 return this->findPtr(name, reinterpret_cast<void**>(ptr));
106 }
107 bool hasRefCnt(const char name[], SkRefCnt* ptr) {
108 return this->hasPtr(name, ptr);
109 }
110 void setRefCnt(const char name[], SkRefCnt* ptr) {
111 this->setPtr(name, ptr, RefCntProc);
112 }
113 bool removeRefCnt(const char name[]) {
114 return this->removePtr(name);
115 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116
117 enum Type {
118 kS32_Type,
119 kScalar_Type,
120 kString_Type,
121 kPtr_Type,
122 kBool_Type,
reed@android.comf2b98d62010-12-20 18:26:13 +0000123 kData_Type,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000124
125 kTypeCount
126 };
127
128 struct Rec;
129 class Iter;
130 friend class Iter;
131
132 class Iter {
133 public:
Ben Wagnera93a14a2017-08-28 10:34:05 -0400134 Iter() : fRec(nullptr) {}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000135 Iter(const SkMetaData&);
136
137 /** Reset the iterator, so that calling next() will return the first
138 data element. This is done implicitly in the constructor.
139 */
reed@google.come7330712011-03-30 18:23:21 +0000140 void reset(const SkMetaData&);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141
142 /** Each time next is called, it returns the name of the next data element,
143 or null when there are no more elements. If non-null is returned, then the
144 element's type is returned (if not null), and the number of data values
145 is returned in count (if not null).
146 */
147 const char* next(Type*, int* count);
148
149 private:
150 Rec* fRec;
151 };
152
153public:
154 struct Rec {
155 Rec* fNext;
156 uint16_t fDataCount; // number of elements
157 uint8_t fDataLen; // sizeof a single element
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158 uint8_t fType;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159
160 const void* data() const { return (this + 1); }
161 void* data() { return (this + 1); }
162 const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
163 char* name() { return (char*)this->data() + fDataLen * fDataCount; }
164
165 static Rec* Alloc(size_t);
166 static void Free(Rec*);
167 };
168 Rec* fRec;
169
170 const Rec* find(const char name[], Type) const;
171 void* set(const char name[], const void* data, size_t len, Type, int count);
172 bool remove(const char name[], Type);
173};
174
175#endif