| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_ |
| #define HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_ |
| |
| #include <memory> |
| |
| #include "base/values.h" |
| #include "headless/public/util/error_reporter.h" |
| |
| namespace headless { |
| namespace internal { |
| |
| // Generic conversion from a type to a base::Value. Implemented below |
| // (for composite and low level types) and and in types_DOMAIN.cc. |
| template <typename T> |
| std::unique_ptr<base::Value> ToValue(const T& value); |
| |
| // Generic conversion from a base::Value to a type. Note that this generic |
| // variant is never defined. Instead, we declare a specific template |
| // specialization for all the used types. |
| template <typename T> |
| struct FromValue { |
| static std::unique_ptr<T> Parse(const base::Value& value, |
| ErrorReporter* errors); |
| }; |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue(const int& value) { |
| return std::make_unique<base::Value>(value); |
| } |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue(const double& value) { |
| return std::make_unique<base::Value>(value); |
| } |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue(const bool& value) { |
| return std::make_unique<base::Value>(value); |
| } |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue(const std::string& value) { |
| return std::make_unique<base::Value>(value); |
| } |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue(const base::Value& value) { |
| return base::Value::ToUniquePtrValue(value.Clone()); |
| } |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue( |
| const base::DictionaryValue& value) { |
| return ToValue(static_cast<const base::Value&>(value)); |
| } |
| |
| // Note: Order of the two templates below is important to handle |
| // vectors of unique_ptr. |
| template <typename T> |
| std::unique_ptr<base::Value> ToValue(const std::unique_ptr<T>& value) { |
| return ToValue(*value); |
| } |
| |
| template <typename T> |
| std::unique_ptr<base::Value> ToValue(const std::vector<T>& vector_of_values) { |
| std::unique_ptr<base::ListValue> result(new base::ListValue()); |
| for (const T& value : vector_of_values) |
| result->Append(ToValue(value)); |
| return std::move(result); |
| } |
| |
| template <> |
| inline std::unique_ptr<base::Value> ToValue(const protocol::Binary& value) { |
| return ToValue(value.toBase64()); |
| } |
| |
| // FromValue specializations for basic types. |
| template <> |
| struct FromValue<bool> { |
| static bool Parse(const base::Value& value, ErrorReporter* errors) { |
| if (!value.is_bool()) { |
| errors->AddError("boolean value expected"); |
| return false; |
| } |
| return value.GetBool(); |
| } |
| }; |
| |
| template <> |
| struct FromValue<int> { |
| static int Parse(const base::Value& value, ErrorReporter* errors) { |
| if (!value.is_int()) { |
| errors->AddError("integer value expected"); |
| return 0; |
| } |
| return value.GetInt(); |
| } |
| }; |
| |
| template <> |
| struct FromValue<double> { |
| static double Parse(const base::Value& value, ErrorReporter* errors) { |
| if (!value.is_double() && !value.is_int()) { |
| errors->AddError("double value expected"); |
| return 0; |
| } |
| return value.GetDouble(); |
| } |
| }; |
| |
| template <> |
| struct FromValue<std::string> { |
| static std::string Parse(const base::Value& value, ErrorReporter* errors) { |
| if (!value.is_string()) { |
| errors->AddError("string value expected"); |
| return ""; |
| } |
| return value.GetString(); |
| } |
| }; |
| |
| template <> |
| struct FromValue<base::DictionaryValue> { |
| static std::unique_ptr<base::DictionaryValue> Parse(const base::Value& value, |
| ErrorReporter* errors) { |
| const base::DictionaryValue* result; |
| if (!value.GetAsDictionary(&result)) { |
| errors->AddError("dictionary value expected"); |
| return nullptr; |
| } |
| return result->CreateDeepCopy(); |
| } |
| }; |
| |
| template <> |
| struct FromValue<base::Value> { |
| static std::unique_ptr<base::Value> Parse(const base::Value& value, |
| ErrorReporter* errors) { |
| return base::Value::ToUniquePtrValue(value.Clone()); |
| } |
| }; |
| |
| template <typename T> |
| struct FromValue<std::unique_ptr<T>> { |
| static std::unique_ptr<T> Parse(const base::Value& value, |
| ErrorReporter* errors) { |
| return FromValue<T>::Parse(value, errors); |
| } |
| }; |
| |
| template <> |
| struct FromValue<protocol::Binary> { |
| static protocol::Binary Parse(const base::Value& value, |
| ErrorReporter* errors) { |
| if (!value.is_string()) { |
| errors->AddError("string value expected"); |
| return protocol::Binary(); |
| } |
| bool success = false; |
| protocol::Binary out = |
| protocol::Binary::fromBase64(value.GetString(), &success); |
| if (!success) |
| errors->AddError("base64 decoding error"); |
| return out; |
| } |
| }; |
| |
| template <typename T> |
| struct FromValue<std::vector<T>> { |
| static std::vector<T> Parse(const base::Value& value, ErrorReporter* errors) { |
| std::vector<T> result; |
| if (!value.is_list()) { |
| errors->AddError("list value expected"); |
| return result; |
| } |
| errors->Push(); |
| for (const auto& item : value.GetListDeprecated()) |
| result.push_back(FromValue<T>::Parse(item, errors)); |
| errors->Pop(); |
| return result; |
| } |
| }; |
| |
| } // namespace internal |
| } // namespace headless |
| |
| #endif // HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_ |