blob: 625b8542918de8335d45bef8a894cf54dcfbcea6 [file] [log] [blame]
Alex Vakulenko66ec2922014-06-17 15:30:22 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BUFFET_COMMANDS_SCHEMA_UTILS_H_
6#define BUFFET_COMMANDS_SCHEMA_UTILS_H_
7
8#include <limits>
9#include <map>
10#include <memory>
11#include <string>
12#include <type_traits>
13#include <vector>
14
15#include <base/values.h>
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -070016#include <chromeos/any.h>
Alex Vakulenkoa8b95bc2014-08-27 11:00:57 -070017#include <chromeos/errors/error.h>
Anton Muhincfde8692014-11-25 03:36:59 +040018#include <chromeos/variant_dictionary.h>
Alex Vakulenko66ec2922014-06-17 15:30:22 -070019
20namespace buffet {
21
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -070022class PropType;
Alex Vakulenko66ec2922014-06-17 15:30:22 -070023class PropValue;
24class ObjectSchema;
Anton Muhincfde8692014-11-25 03:36:59 +040025class ObjectValue;
Alex Vakulenko66ec2922014-06-17 15:30:22 -070026
27namespace native_types {
28// C++ representation of object values.
Alex Vakulenkoaa3a5592014-08-07 07:24:06 -070029using Object = std::map<std::string, std::shared_ptr<const PropValue>>;
Alex Vakulenko29e64442015-03-20 13:59:19 -070030// C++ representation of array of values.
31using Array = std::vector<std::shared_ptr<const PropValue>>;
Alex Vakulenko66ec2922014-06-17 15:30:22 -070032} // namespace native_types
Alex Vakulenko29e64442015-03-20 13:59:19 -070033
Alex Vakulenko66ec2922014-06-17 15:30:22 -070034// Converts an object to string.
35std::string ToString(const native_types::Object& obj);
36
Alex Vakulenko29e64442015-03-20 13:59:19 -070037// Converts an array to string.
38std::string ToString(const native_types::Array& arr);
39
Alex Vakulenko66ec2922014-06-17 15:30:22 -070040// InheritableAttribute class is used for specifying various command parameter
41// attributes that can be inherited from a base (parent) schema.
42// The |value| still specifies the actual attribute values, whether it
43// is inherited or overridden, while |is_inherited| can be used to identify
44// if the attribute was inherited (true) or overridden (false).
45template<typename T>
46class InheritableAttribute {
47 public:
48 InheritableAttribute() = default;
49 explicit InheritableAttribute(T val)
50 : value(std::move(val)), is_inherited(true) {}
51 InheritableAttribute(T val, bool inherited)
52 : value(std::move(val)), is_inherited(inherited) {}
53 T value{};
54 bool is_inherited{true};
55};
56
57// A bunch of helper function to create base::Value for specific C++ classes,
58// including vectors of types. These are used in template classes below
59// to simplify specialization logic.
Alex Vakulenko5f472062014-08-14 17:54:04 -070060std::unique_ptr<base::Value> TypedValueToJson(bool value,
61 chromeos::ErrorPtr* error);
62std::unique_ptr<base::Value> TypedValueToJson(int value,
63 chromeos::ErrorPtr* error);
64std::unique_ptr<base::Value> TypedValueToJson(double value,
65 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -070066std::unique_ptr<base::Value> TypedValueToJson(const std::string& value,
Alex Vakulenko5f472062014-08-14 17:54:04 -070067 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -070068std::unique_ptr<base::Value> TypedValueToJson(const native_types::Object& value,
Alex Vakulenko5f472062014-08-14 17:54:04 -070069 chromeos::ErrorPtr* error);
Alex Vakulenko29e64442015-03-20 13:59:19 -070070std::unique_ptr<base::Value> TypedValueToJson(const native_types::Array& value,
71 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -070072template<typename T>
73std::unique_ptr<base::Value> TypedValueToJson(const std::vector<T>& values,
Alex Vakulenko5f472062014-08-14 17:54:04 -070074 chromeos::ErrorPtr* error) {
Alex Vakulenko66ec2922014-06-17 15:30:22 -070075 std::unique_ptr<base::ListValue> list(new base::ListValue);
76 for (const auto& v : values) {
77 auto json = TypedValueToJson(v, error);
78 if (!json)
79 return std::unique_ptr<base::Value>();
80 list->Append(json.release());
81 }
82 return std::move(list);
83}
84
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -070085// Similarly to TypedValueToJson() function above, the following overloaded
Alex Vakulenko66ec2922014-06-17 15:30:22 -070086// helper methods allow to extract specific C++ data types from base::Value.
87// Also used in template classes below to simplify specialization logic.
88bool TypedValueFromJson(const base::Value* value_in,
Alex Vakulenkod94656e2015-03-18 09:54:37 -070089 const PropType* type,
90 bool* value_out,
91 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -070092bool TypedValueFromJson(const base::Value* value_in,
Alex Vakulenkod94656e2015-03-18 09:54:37 -070093 const PropType* type,
94 int* value_out,
95 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -070096bool TypedValueFromJson(const base::Value* value_in,
Alex Vakulenkod94656e2015-03-18 09:54:37 -070097 const PropType* type,
98 double* value_out,
99 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700100bool TypedValueFromJson(const base::Value* value_in,
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700101 const PropType* type,
102 std::string* value_out,
103 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700104bool TypedValueFromJson(const base::Value* value_in,
Alex Vakulenkod94656e2015-03-18 09:54:37 -0700105 const PropType* type,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700106 native_types::Object* value_out,
107 chromeos::ErrorPtr* error);
Alex Vakulenko29e64442015-03-20 13:59:19 -0700108bool TypedValueFromJson(const base::Value* value_in,
109 const PropType* type,
110 native_types::Array* value_out,
111 chromeos::ErrorPtr* error);
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700112
113bool operator==(const native_types::Object& obj1,
114 const native_types::Object& obj2);
Alex Vakulenko29e64442015-03-20 13:59:19 -0700115bool operator==(const native_types::Array& arr1,
116 const native_types::Array& arr2);
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700117
118// CompareValue is a helper function to help with implementing EqualsTo operator
119// for various data types. For most scalar types it is using operator==(),
120// however, for floating point values, rounding errors in binary representation
121// of IEEE floats/doubles can cause straight == comparison to fail for seemingly
122// equivalent values. For these, use approximate comparison with the error
123// margin equal to the epsilon value defined for the corresponding data type.
124// This is used when looking up values for implementation of OneOf constraints
125// which should work reliably for floating points also ("number" type).
126
127// Compare exact types using ==.
128template<typename T>
129inline typename std::enable_if<!std::is_floating_point<T>::value, bool>::type
130CompareValue(const T& v1, const T& v2) {
131 return v1 == v2;
132}
133
134// Compare non-exact types (such as double) using precision margin (epsilon).
135template<typename T>
136inline typename std::enable_if<std::is_floating_point<T>::value, bool>::type
137CompareValue(const T& v1, const T& v2) {
138 return std::abs(v1 - v2) <= std::numeric_limits<T>::epsilon();
139}
140
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700141// Converts PropValue to Any in a format understood by D-Bus data serialization.
142// Has special handling for Object types where native_types::Object are
Alex Vakulenko576c9792014-09-22 16:49:45 -0700143// converted to chromeos::VariantDictionary.
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700144chromeos::Any PropValueToDBusVariant(const PropValue* value);
Anton Muhincfde8692014-11-25 03:36:59 +0400145// Converts native_types::Object to chromeos::VariantDictionary
146// with proper conversion of all nested properties.
147chromeos::VariantDictionary
148ObjectToDBusVariant(const native_types::Object& object);
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700149// Converts D-Bus variant to PropValue.
Alex Vakulenko576c9792014-09-22 16:49:45 -0700150// Has special handling for Object types where chromeos::VariantDictionary
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700151// is converted to native_types::Object.
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700152std::unique_ptr<const PropValue> PropValueFromDBusVariant(
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700153 const PropType* type,
154 const chromeos::Any& value,
155 chromeos::ErrorPtr* error);
Anton Muhincfde8692014-11-25 03:36:59 +0400156// Converts D-Bus variant to ObjectValue.
157bool ObjectFromDBusVariant(const ObjectSchema* object_schema,
158 const chromeos::VariantDictionary& dict,
159 native_types::Object* obj,
160 chromeos::ErrorPtr* error);
Alex Vakulenkoa32d83a2014-09-19 15:05:24 -0700161
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700162} // namespace buffet
163
164#endif // BUFFET_COMMANDS_SCHEMA_UTILS_H_