blob: 126d1efd1d584ab195c3aa4787d18a593e60bc66 [file] [log] [blame]
// 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 "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 <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 value.CreateDeepCopy();
}
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 value.CreateDeepCopy();
}
};
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.GetList())
result.push_back(FromValue<T>::Parse(item, errors));
errors->Pop();
return result;
}
};
} // namespace internal
} // namespace headless
#endif // HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_