Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Unified Diff: src/core/SkValue.cpp

Issue 1604253002: SkValue: implementation, unit test (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: another unit test Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkValue.h ('k') | tests/ValueTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkValue.cpp
diff --git a/src/core/SkValue.cpp b/src/core/SkValue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8f58dd6ef9a0da4b12a0afa5a6464c54a4fb77ee
--- /dev/null
+++ b/src/core/SkValue.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <unordered_map>
+#include <vector>
+
+#include "SkData.h"
+#include "SkMatrix.h"
+#include "SkValue.h"
+
+class SkValue::Obj {
+public:
+ void set(SkValue::Key k, SkValue&& v) { fMap[k] = std::move(v); }
+ const SkValue* get(SkValue::Key k) const {
+ auto it = fMap.find(k);
+ return it != fMap.end() ? &it->second : nullptr;
+ }
+ void foreach(std::function<void(Key, const SkValue&)> fn) const {
+ for (const auto& pair : fMap) {
+ fn(pair.first, pair.second);
+ }
+ }
+
+private:
+ std::unordered_map<SkValue::Key, SkValue> fMap;
+};
+
+class SkValue::Arr {
+public:
+ size_t length() const { return fVec.size(); }
+ void append(SkValue&& val) { fVec.emplace_back(std::move(val)); }
+ const SkValue& at(size_t index) const {
+ SkASSERT(index < fVec.size());
+ return fVec[index];
+ }
+
+private:
+ std::vector<SkValue> fVec;
+};
+
+SkValue::SkValue() : fType(Null) {}
+
+SkValue::SkValue(Type type) : fType(type) {}
+
+SkValue::SkValue(const SkValue& o) {
+ memcpy(this, &o, sizeof(o));
+ if (this->isData()) {
+ fBytes->ref();
+ } else if (this->isObject()) {
+ fObject = new Obj(*fObject);
+ } else if (Array == fType) {
+ fArray = new Arr(*fArray);
+ }
+}
+
+SkValue::SkValue(SkValue&& o) {
+ memcpy(this, &o, sizeof(o));
+ new (&o) SkValue();
+}
+
+SkValue& SkValue::operator=(const SkValue& o) {
+ if (this != &o) {
+ this->~SkValue();
+ new (this) SkValue(o);
+ }
+ return *this;
+}
+
+SkValue& SkValue::operator=(SkValue&& o) {
+ if (this != &o) {
+ this->~SkValue();
+ new (this) SkValue(std::move(o));
+ }
+ return *this;
+}
+
+SkValue::~SkValue() {
+ if (this->isData()) {
+ fBytes->unref();
+ } else if (this->isObject()) {
+ delete fObject;
+ } else if (Array == fType) {
+ delete fArray;
+ }
+}
+
+template <typename T>
+SkValue SkValue::FromT(SkValue::Type type, T SkValue::*mp, T t) {
+ SkValue v(type);
+ v.*mp = t;
+ return v;
+}
+
+SkValue SkValue::FromS32(int32_t x) { return FromT(S32, &SkValue::fS32, x); }
+SkValue SkValue::FromU32(uint32_t x) { return FromT(U32, &SkValue::fU32, x); }
+SkValue SkValue::FromF32(float x) { return FromT(F32, &SkValue::fF32, x); }
+
+int32_t SkValue::s32() const { SkASSERT(S32 == fType); return fS32; }
+uint32_t SkValue::u32() const { SkASSERT(U32 == fType); return fU32; }
+float SkValue::f32() const { SkASSERT(F32 == fType); return fF32; }
+
+SkValue SkValue::FromBytes(SkData* data) {
+ if (!data) {
+ return SkValue();
+ }
+ SkValue v(Bytes);
+ v.fBytes = SkRef(data);
+ return v;
+}
+
+SkValue SkValue::Object(SkValue::Type t) {
+ SkValue v(t);
+ SkASSERT(v.isObject());
+ v.fObject = new Obj;
+ return v;
+}
+
+SkValue SkValue::ValueArray() {
+ SkValue v(Array);
+ v.fArray = new Arr;
+ return v;
+}
+
+SkData* SkValue::bytes() const {
+ SkASSERT(this->isData());
+ return fBytes;
+}
+
+void SkValue::set(SkValue::Key k, SkValue v) {
+ SkASSERT(this->isObject());
+ fObject->set(k, std::move(v));
+}
+
+void SkValue::foreach(std::function<void(Key, const SkValue&)> fn) const {
+ SkASSERT(this->isObject());
+ fObject->foreach(fn);
+}
+
+size_t SkValue::length() const {
+ SkASSERT(Array == fType);
+ return fArray->length();
+}
+
+const SkValue& SkValue::at(size_t index) const {
+ SkASSERT(Array == fType);
+ return fArray->at(index);
+}
+
+void SkValue::append(SkValue val) {
+ SkASSERT(Array == fType);
+ fArray->append(std::move(val));
+}
+
+template <typename T>
+const T* SkValue::asTs(SkValue::Type t, int* count) const {
+ SkASSERT(t == fType && this->isData());
+ SkASSERT(count);
+ *count = fBytes->size() / sizeof(T);
+ return static_cast<const T*>(fBytes->data());
+}
+
+const uint16_t* SkValue::u16s(int* c) const { return this->asTs<uint16_t>(U16s, c); }
+const uint32_t* SkValue::u32s(int* c) const { return this->asTs<uint32_t>(U32s, c); }
+const float* SkValue::f32s(int* c) const { return this->asTs<float >(F32s, c); }
+
+template <typename T>
+SkValue SkValue::FromTs(SkValue::Type type, SkData* data) {
+ SkValue val(type);
+ val.fBytes = SkRef(data);
+ SkASSERT(val.isData());
+ SkASSERT(0 == (reinterpret_cast<uintptr_t>(data->bytes()) & (sizeof(T)-1)));
+ return val;
+}
+
+SkValue SkValue::FromU16s(SkData* d) { return FromTs<uint16_t>(U16s, d); }
+SkValue SkValue::FromU32s(SkData* d) { return FromTs<uint32_t>(U32s, d); }
+SkValue SkValue::FromF32s(SkData* d) { return FromTs< float>(F32s, d); }
+
+////////////////////////////////////////////////////////////////////////////////
+
+template<> SkValue SkToValue<SkMatrix>(const SkMatrix& mat) {
+ auto val = SkValue::Object(SkValue::Matrix);
+ for (int i = 0; i < 9; ++i) {
+ if (mat[i] != SkMatrix::I()[i]) {
+ val.set(i, SkValue::FromF32(mat[i]));
+ }
+ }
+ return val;
+}
+
+template<> bool SkFromValue<SkMatrix>(const SkValue& val, SkMatrix* m){
+ SkASSERT(val.type() == SkValue::Matrix);
+ if (val.type() != SkValue::Matrix) {
+ return false;
+ }
+ *m = SkMatrix::I();
+ bool good = true;
+ auto fn = [&](SkValue::Key key, const SkValue& v) {
+ if (key < 9) {
+ if (v.type() != SkValue::F32) {
+ SkASSERT(false);
+ good = false;
+ } else {
+ (*m)[key] = v.f32();
+ }
+ } else {
+ SkASSERT(false);
+ good = false;
+ }
+ };
+ val.foreach(fn);
+ return good;
+}
« no previous file with comments | « src/core/SkValue.h ('k') | tests/ValueTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698