blob: b493252fd6cb5eb2b2661c82d82d69bf4f09b1bd [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00007#ifndef SkMetaData_DEFINED
8#define SkMetaData_DEFINED
9
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkScalar.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000011
Hal Canarya1730e12019-07-24 09:44:43 -040012/** A map from c-string keys to arrays of POD (int32_t, kScalar, void*, or bool)
13 values.
14*/
15class SkMetaData {
reed@android.com8a1c16f2008-12-17 15:59:43 +000016public:
Hal Canarya1730e12019-07-24 09:44:43 -040017 SkMetaData() {}
18 ~SkMetaData() { if (fRec) { this->reset(); } }
reed@google.come7330712011-03-30 18:23:21 +000019 void reset();
reed@android.com8a1c16f2008-12-17 15:59:43 +000020
Ben Wagnera93a14a2017-08-28 10:34:05 -040021 bool findS32(const char name[], int32_t* value = nullptr) const;
22 bool findScalar(const char name[], SkScalar* value = nullptr) const;
reed@google.come7330712011-03-30 18:23:21 +000023 const SkScalar* findScalars(const char name[], int* count,
Ben Wagnera93a14a2017-08-28 10:34:05 -040024 SkScalar values[] = nullptr) const;
Hal Canaryca9e1872019-07-25 10:36:30 -040025 bool findPtr(const char name[], void** value = nullptr) const;
Ben Wagnera93a14a2017-08-28 10:34:05 -040026 bool findBool(const char name[], bool* value = nullptr) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +000027
reed@google.come7330712011-03-30 18:23:21 +000028 bool hasS32(const char name[], int32_t value) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000029 int32_t v;
30 return this->findS32(name, &v) && v == value;
31 }
reed@google.come7330712011-03-30 18:23:21 +000032 bool hasScalar(const char name[], SkScalar value) const {
33 SkScalar v;
reed@android.com8a1c16f2008-12-17 15:59:43 +000034 return this->findScalar(name, &v) && v == value;
35 }
reed@google.come7330712011-03-30 18:23:21 +000036 bool hasPtr(const char name[], void* value) const {
37 void* v;
reed@android.com8a1c16f2008-12-17 15:59:43 +000038 return this->findPtr(name, &v) && v == value;
39 }
reed@google.come7330712011-03-30 18:23:21 +000040 bool hasBool(const char name[], bool value) const {
reed@android.com8a1c16f2008-12-17 15:59:43 +000041 bool v;
42 return this->findBool(name, &v) && v == value;
43 }
44
reed@google.come7330712011-03-30 18:23:21 +000045 void setS32(const char name[], int32_t value);
46 void setScalar(const char name[], SkScalar value);
Ben Wagnera93a14a2017-08-28 10:34:05 -040047 SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nullptr);
Hal Canaryca9e1872019-07-25 10:36:30 -040048 void setPtr(const char name[], void* value);
reed@google.come7330712011-03-30 18:23:21 +000049 void setBool(const char name[], bool value);
reed@android.com8a1c16f2008-12-17 15:59:43 +000050
reed@google.come7330712011-03-30 18:23:21 +000051 bool removeS32(const char name[]);
52 bool removeScalar(const char name[]);
reed@google.come7330712011-03-30 18:23:21 +000053 bool removePtr(const char name[]);
54 bool removeBool(const char name[]);
reed@android.com8a1c16f2008-12-17 15:59:43 +000055
56 enum Type {
57 kS32_Type,
58 kScalar_Type,
reed@android.com8a1c16f2008-12-17 15:59:43 +000059 kPtr_Type,
60 kBool_Type,
reed@android.com8a1c16f2008-12-17 15:59:43 +000061
62 kTypeCount
63 };
64
65 struct Rec;
66 class Iter;
67 friend class Iter;
68
69 class Iter {
70 public:
Ben Wagnera93a14a2017-08-28 10:34:05 -040071 Iter() : fRec(nullptr) {}
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 Iter(const SkMetaData&);
73
74 /** Reset the iterator, so that calling next() will return the first
75 data element. This is done implicitly in the constructor.
76 */
reed@google.come7330712011-03-30 18:23:21 +000077 void reset(const SkMetaData&);
reed@android.com8a1c16f2008-12-17 15:59:43 +000078
79 /** Each time next is called, it returns the name of the next data element,
80 or null when there are no more elements. If non-null is returned, then the
81 element's type is returned (if not null), and the number of data values
82 is returned in count (if not null).
83 */
84 const char* next(Type*, int* count);
85
86 private:
87 Rec* fRec;
88 };
89
90public:
91 struct Rec {
92 Rec* fNext;
93 uint16_t fDataCount; // number of elements
94 uint8_t fDataLen; // sizeof a single element
reed@android.com8a1c16f2008-12-17 15:59:43 +000095 uint8_t fType;
reed@android.com8a1c16f2008-12-17 15:59:43 +000096
97 const void* data() const { return (this + 1); }
98 void* data() { return (this + 1); }
99 const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
100 char* name() { return (char*)this->data() + fDataLen * fDataCount; }
101
102 static Rec* Alloc(size_t);
103 static void Free(Rec*);
104 };
Hal Canarya1730e12019-07-24 09:44:43 -0400105 Rec* fRec = nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000106
107 const Rec* find(const char name[], Type) const;
108 void* set(const char name[], const void* data, size_t len, Type, int count);
109 bool remove(const char name[], Type);
Hal Canarya1730e12019-07-24 09:44:43 -0400110
111 SkMetaData(const SkMetaData&) = delete;
112 SkMetaData& operator=(const SkMetaData&) = delete;
Ben Wagner19684732020-08-21 16:52:48 -0400113
114private:
115 struct FindResult {
116 SkMetaData::Rec* rec;
117 SkMetaData::Rec* prev;
118 };
119 FindResult findWithPrev(const char name[], Type type) const;
120 void remove(FindResult);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000121};
122
123#endif