// 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 #include "headless/lib/browser/protocol/base_string_adapter.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 std::unique_ptr 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 struct FromValue { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors); }; template <> inline std::unique_ptr ToValue(const int& value) { return std::make_unique(value); } template <> inline std::unique_ptr ToValue(const double& value) { return std::make_unique(value); } template <> inline std::unique_ptr ToValue(const bool& value) { return std::make_unique(value); } template <> inline std::unique_ptr ToValue(const std::string& value) { return std::make_unique(value); } template <> inline std::unique_ptr ToValue(const base::Value& value) { return value.CreateDeepCopy(); } template <> inline std::unique_ptr ToValue( const base::DictionaryValue& value) { return ToValue(static_cast(value)); } // Note: Order of the two templates below is important to handle // vectors of unique_ptr. template std::unique_ptr ToValue(const std::unique_ptr& value) { return ToValue(*value); } template std::unique_ptr ToValue(const std::vector& vector_of_values) { std::unique_ptr result(new base::ListValue()); for (const T& value : vector_of_values) result->Append(ToValue(value)); return std::move(result); } template <> inline std::unique_ptr ToValue(const protocol::Binary& value) { return ToValue(value.toBase64()); } // FromValue specializations for basic types. template <> struct FromValue { 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 { 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 { 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 { 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 { static std::unique_ptr 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 { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors) { return value.CreateDeepCopy(); } }; template struct FromValue> { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors) { return FromValue::Parse(value, errors); } }; template <> struct FromValue { 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 struct FromValue> { static std::vector Parse(const base::Value& value, ErrorReporter* errors) { std::vector result; if (!value.is_list()) { errors->AddError("list value expected"); return result; } errors->Push(); for (const auto& item : value.GetList()) result.push_back(FromValue::Parse(item, errors)); errors->Pop(); return result; } }; } // namespace internal } // namespace headless #endif // HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_