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 | |
10 #include "SkData.h" | |
11 #include "SkValue.h" | |
12 | |
13 // WARNING: this implementation is for testing purposes only. | |
14 // TODO(mtklein): replace with something less fragile later. | |
mtklein
2016/01/15 17:26:20
Goodness no. Copy. Not going to ask again.
hal.canary
2016/01/15 19:44:31
done
| |
15 class SkValue::Obj : public SkRefCnt { | |
16 public: | |
17 std::unordered_map<SkValue::Key, SkValue> fMap; | |
18 std::atomic<bool> fReadOnly; | |
19 Obj() : fReadOnly(false) {} | |
20 }; | |
21 | |
22 SkValue::SkValue() : fType(Null) {} | |
23 | |
24 SkValue::SkValue(const SkValue& o) { | |
25 memcpy(this, &o, sizeof(o)); | |
26 if (Bytes == fType) { | |
27 fBytes->ref(); | |
28 } else if (this->isObject()) { | |
29 fObject->ref(); | |
30 fObject->fReadOnly = true; | |
31 } | |
32 } | |
33 | |
34 SkValue::SkValue(SkValue&& o) { | |
35 memcpy(this, &o, sizeof(o)); | |
36 new (&o) SkValue(); | |
37 } | |
38 | |
39 SkValue& SkValue::operator=(const SkValue& o) { | |
40 if (this != &o) { | |
41 this->~SkValue(); | |
42 new (this) SkValue(o); | |
43 } | |
44 return *this; | |
45 } | |
46 | |
47 SkValue& SkValue::operator=(SkValue&& o) { | |
48 if (this != &o) { | |
49 this->~SkValue(); | |
50 new (this) SkValue(std::move(o)); | |
51 } | |
52 return *this; | |
53 } | |
54 | |
55 SkValue::~SkValue() { | |
56 if (Bytes == fType) { | |
57 fBytes->unref(); | |
58 } else if (this->isObject()) { | |
59 fObject->unref(); | |
60 } | |
61 } | |
62 | |
63 #define FN(NAME, LNAME, TYPE) \ | |
64 SkValue SkValue::From##NAME(TYPE x) { \ | |
65 SkValue v; \ | |
66 v.fType = NAME; \ | |
67 v.f##NAME = x; \ | |
68 return v; \ | |
69 } \ | |
70 TYPE SkValue::LNAME() const { \ | |
71 SkASSERT(NAME == fType); \ | |
72 return f##NAME; \ | |
73 } | |
74 FN(S32, s32, int32_t) | |
75 FN(U32, u32, uint32_t) | |
76 FN(F32, f32, float) | |
77 #undef FN | |
78 | |
79 SkValue SkValue::FromBytes(const void* data, size_t length) { | |
80 SkValue v; | |
81 v.fType = Bytes; | |
82 reinterpret_cast<SkData*&>(v.fBytes) = SkData::NewWithCopy(data, length); | |
83 return v; | |
84 } | |
85 | |
86 SkValue SkValue::Object(SkValue::Type t) { | |
87 SkValue v; | |
88 v.fType = t; | |
89 SkASSERT(v.isObject()); | |
90 v.fObject = new Obj; | |
91 return v; | |
92 } | |
93 | |
94 SkValue::Type SkValue::type() const { return fType; } | |
95 | |
96 const void* SkValue::bytes() const { | |
97 return Bytes == fType ? fBytes->data() : nullptr; | |
98 } | |
99 | |
100 size_t SkValue::count() const { | |
101 if (Bytes == fType) { | |
102 return fBytes->size(); | |
103 } else if (this->isObject()) { | |
104 return fObject->fMap.size(); | |
105 } | |
106 return 0; | |
107 } | |
108 | |
109 bool SkValue::set(SkValue::Key k, SkValue v) { | |
110 if (!this->isObject() || fObject->fReadOnly) { | |
111 return false; | |
112 } | |
113 fObject->fMap[k] = std::move(v); | |
114 return true; | |
115 } | |
116 | |
117 const SkValue* SkValue::get(SkValue::Key k) const { | |
118 if (!this->isObject()) { | |
119 return nullptr; | |
120 } | |
121 auto it = fObject->fMap.find(k); | |
122 return it != fObject->fMap.end() ? &it->second : nullptr; | |
123 } | |
124 | |
125 void SkValue::foreach(std::function<void(Key, const SkValue&)> fn) const { | |
126 if (!this->isObject()) { | |
127 return; | |
128 } | |
129 for (const auto& pair : fObject->fMap) { | |
130 fn(pair.first, pair.second); | |
131 } | |
132 } | |
OLD | NEW |