OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2016 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include <unordered_map> | |
9 #include <vector> | |
10 | |
11 #include "SkData.h" | |
12 #include "SkValue.h" | |
13 | |
14 class SkValue::Obj { | |
15 public: | |
16 void set(SkValue::Key k, SkValue&& v) { fMap[k] = std::move(v); } | |
17 const SkValue* get(SkValue::Key k) const { | |
18 auto it = fMap.find(k); | |
19 return it != fMap.end() ? &it->second : nullptr; | |
20 } | |
21 void foreach(std::function<void(Key, const SkValue&)> fn) const { | |
22 for (const auto& pair : fMap) { | |
23 fn(pair.first, pair.second); | |
24 } | |
25 } | |
26 | |
27 private: | |
28 std::unordered_map<SkValue::Key, SkValue> fMap; | |
29 }; | |
30 | |
31 class SkValue::Arr { | |
32 public: | |
33 size_t length() const { return fVec.size(); } | |
34 void append(SkValue&& val) { fVec.emplace_back(std::move(val)); } | |
35 const SkValue& at(size_t index) const { | |
36 SkASSERT(index < fVec.size()); | |
37 return fVec[index]; | |
38 } | |
39 | |
40 private: | |
41 std::vector<SkValue> fVec; | |
42 }; | |
43 | |
44 SkValue::SkValue() : fType(Null) {} | |
45 | |
46 SkValue::SkValue(Type type) : fType(type) {} | |
47 | |
48 SkValue::SkValue(const SkValue& o) { | |
49 memcpy(this, &o, sizeof(o)); | |
50 if (this->isData()) { | |
51 fBytes->ref(); | |
52 } else if (this->isObject()) { | |
53 fObject = new Obj(*fObject); | |
54 } else if (Array == fType) { | |
55 fArray = new Arr(*fArray); | |
56 } | |
57 } | |
58 | |
59 SkValue::SkValue(SkValue&& o) { | |
60 memcpy(this, &o, sizeof(o)); | |
61 new (&o) SkValue(); | |
62 } | |
63 | |
64 SkValue& SkValue::operator=(const SkValue& o) { | |
65 if (this != &o) { | |
66 this->~SkValue(); | |
67 new (this) SkValue(o); | |
68 } | |
69 return *this; | |
70 } | |
71 | |
72 SkValue& SkValue::operator=(SkValue&& o) { | |
73 if (this != &o) { | |
74 this->~SkValue(); | |
75 new (this) SkValue(std::move(o)); | |
76 } | |
77 return *this; | |
78 } | |
79 | |
80 SkValue::~SkValue() { | |
81 if (this->isData()) { | |
82 fBytes->unref(); | |
83 } else if (this->isObject()) { | |
84 delete fObject; | |
85 } else if (Array == fType) { | |
86 delete fArray; | |
87 } | |
88 } | |
89 | |
90 template <typename T> | |
91 SkValue SkValue::FromT(SkValue::Type type, T SkValue::*mp, T t) { | |
92 SkValue v(type); | |
93 v.*mp = t; | |
94 return v; | |
95 } | |
96 | |
97 SkValue SkValue::FromS32(int32_t x) { return FromT(S32, &SkValue::fS32, x); } | |
98 SkValue SkValue::FromU32(uint32_t x) { return FromT(U32, &SkValue::fU32, x); } | |
99 SkValue SkValue::FromF32(float x) { return FromT(F32, &SkValue::fF32, x); } | |
100 | |
101 int32_t SkValue::s32() const { SkASSERT(S32 == fType); return fS32; } | |
102 uint32_t SkValue::u32() const { SkASSERT(U32 == fType); return fU32; } | |
103 float SkValue::f32() const { SkASSERT(F32 == fType); return fF32; } | |
104 | |
105 SkValue SkValue::FromBytes(SkData* data) { | |
106 if (!data) { | |
107 return SkValue(); | |
108 } | |
109 SkValue v(Bytes); | |
110 v.fBytes = SkRef(data); | |
111 return v; | |
112 } | |
113 | |
114 SkValue SkValue::Object(SkValue::Type t) { | |
115 SkValue v(t); | |
116 SkASSERT(v.isObject()); | |
117 v.fObject = new Obj; | |
118 return v; | |
119 } | |
120 | |
121 SkValue SkValue::ValueArray() { | |
122 SkValue v(Array); | |
123 v.fArray = new Arr; | |
124 return v; | |
125 } | |
126 | |
127 SkData* SkValue::bytes() const { | |
128 SkASSERT(this->isData()); | |
129 return fBytes; | |
130 } | |
131 | |
132 void SkValue::set(SkValue::Key k, SkValue v) { | |
133 SkASSERT(this->isObject()); | |
134 fObject->set(k, std::move(v)); | |
135 } | |
136 | |
137 const SkValue* SkValue::get(Key k) const { | |
138 SkASSERT(this->isObject()); | |
139 return fObject->get(k); | |
140 } | |
141 | |
142 void SkValue::foreach(std::function<void(Key, const SkValue&)> fn) const { | |
143 SkASSERT(this->isObject()); | |
144 fObject->foreach(fn); | |
145 } | |
146 | |
147 size_t SkValue::length() const { | |
148 SkASSERT(Array == fType); | |
149 return fArray->length(); | |
150 } | |
151 | |
152 const SkValue& SkValue::at(size_t index) const { | |
153 SkASSERT(Array == fType); | |
154 return fArray->at(index); | |
155 } | |
156 | |
157 void SkValue::append(SkValue val) { | |
158 SkASSERT(Array == fType); | |
159 fArray->append(std::move(val)); | |
160 } | |
161 | |
162 template <typename T> | |
163 const T* SkValue::asTs(SkValue::Type t, int* count) const { | |
164 SkASSERT(t == fType && this->isData()); | |
165 SkASSERT(count); | |
166 *count = fBytes->size() / sizeof(T); | |
167 return static_cast<const T*>(fBytes->data()); | |
168 } | |
169 | |
170 const uint16_t* SkValue::u16s(int* c) const { return this->asTs<uint16_t>(U16s,
c); } | |
171 const uint32_t* SkValue::u32s(int* c) const { return this->asTs<uint32_t>(U32s,
c); } | |
172 const float* SkValue::f32s(int* c) const { return this->asTs<float >(F32s,
c); } | |
173 | |
174 template <typename T> | |
175 SkValue SkValue::FromTs(SkValue::Type type, SkData* data) { | |
176 SkValue val(type); | |
177 val.fBytes = SkRef(data); | |
178 SkASSERT(val.isData()); | |
179 SkASSERT(0 == (reinterpret_cast<uintptr_t>(data->bytes()) & (sizeof(T)-1))); | |
180 return val; | |
181 } | |
182 | |
183 SkValue SkValue::FromU16s(SkData* d) { return FromTs<uint16_t>(U16s, d); } | |
184 SkValue SkValue::FromU32s(SkData* d) { return FromTs<uint32_t>(U32s, d); } | |
185 SkValue SkValue::FromF32s(SkData* d) { return FromTs< float>(F32s, d); } | |
OLD | NEW |