blob: 33261f0c2fe8448afdaf14ae7c40dea0902ec1c6 [file] [log] [blame]
// Copyright 2014 The Chromium OS 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 BUFFET_COMMANDS_SCHEMA_UTILS_H_
#define BUFFET_COMMANDS_SCHEMA_UTILS_H_
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>
#include <base/values.h>
#include <chromeos/any.h>
#include <chromeos/errors/error.h>
namespace buffet {
class PropType;
class PropValue;
class ObjectSchema;
namespace native_types {
// C++ representation of object values.
using Object = std::map<std::string, std::shared_ptr<const PropValue>>;
} // namespace native_types
// Converts an object to string.
std::string ToString(const native_types::Object& obj);
// InheritableAttribute class is used for specifying various command parameter
// attributes that can be inherited from a base (parent) schema.
// The |value| still specifies the actual attribute values, whether it
// is inherited or overridden, while |is_inherited| can be used to identify
// if the attribute was inherited (true) or overridden (false).
template<typename T>
class InheritableAttribute {
public:
InheritableAttribute() = default;
explicit InheritableAttribute(T val)
: value(std::move(val)), is_inherited(true) {}
InheritableAttribute(T val, bool inherited)
: value(std::move(val)), is_inherited(inherited) {}
T value{};
bool is_inherited{true};
};
// A bunch of helper function to create base::Value for specific C++ classes,
// including vectors of types. These are used in template classes below
// to simplify specialization logic.
std::unique_ptr<base::Value> TypedValueToJson(bool value,
chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(int value,
chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(double value,
chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(const std::string& value,
chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(const native_types::Object& value,
chromeos::ErrorPtr* error);
template<typename T>
std::unique_ptr<base::Value> TypedValueToJson(const std::vector<T>& values,
chromeos::ErrorPtr* error) {
std::unique_ptr<base::ListValue> list(new base::ListValue);
for (const auto& v : values) {
auto json = TypedValueToJson(v, error);
if (!json)
return std::unique_ptr<base::Value>();
list->Append(json.release());
}
return std::move(list);
}
// Similarly to TypedValueToJson() function above, the following overloaded
// helper methods allow to extract specific C++ data types from base::Value.
// Also used in template classes below to simplify specialization logic.
bool TypedValueFromJson(const base::Value* value_in,
const ObjectSchema* object_schema,
bool* value_out, chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
const ObjectSchema* object_schema,
int* value_out, chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
const ObjectSchema* object_schema,
double* value_out, chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
const ObjectSchema* object_schema,
std::string* value_out, chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
const ObjectSchema* object_schema,
native_types::Object* value_out,
chromeos::ErrorPtr* error);
bool operator==(const native_types::Object& obj1,
const native_types::Object& obj2);
// CompareValue is a helper function to help with implementing EqualsTo operator
// for various data types. For most scalar types it is using operator==(),
// however, for floating point values, rounding errors in binary representation
// of IEEE floats/doubles can cause straight == comparison to fail for seemingly
// equivalent values. For these, use approximate comparison with the error
// margin equal to the epsilon value defined for the corresponding data type.
// This is used when looking up values for implementation of OneOf constraints
// which should work reliably for floating points also ("number" type).
// Compare exact types using ==.
template<typename T>
inline typename std::enable_if<!std::is_floating_point<T>::value, bool>::type
CompareValue(const T& v1, const T& v2) {
return v1 == v2;
}
// Compare non-exact types (such as double) using precision margin (epsilon).
template<typename T>
inline typename std::enable_if<std::is_floating_point<T>::value, bool>::type
CompareValue(const T& v1, const T& v2) {
return std::abs(v1 - v2) <= std::numeric_limits<T>::epsilon();
}
// Converts PropValue to Any in a format understood by D-Bus data serialization.
// Has special handling for Object types where native_types::Object are
// converted to chromeos::VariantDictionary.
chromeos::Any PropValueToDBusVariant(const PropValue* value);
// Converts D-Bus variant to PropValue.
// Has special handling for Object types where chromeos::VariantDictionary
// is converted to native_types::Object.
std::shared_ptr<const PropValue> PropValueFromDBusVariant(
const PropType* type,
const chromeos::Any& value,
chromeos::ErrorPtr* error);
} // namespace buffet
#endif // BUFFET_COMMANDS_SCHEMA_UTILS_H_