|  | // 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_PROP_VALUES_H_ | 
|  | #define BUFFET_COMMANDS_PROP_VALUES_H_ | 
|  |  | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <string> | 
|  |  | 
|  | #include <chromeos/any.h> | 
|  | #include <chromeos/errors/error.h> | 
|  |  | 
|  | #include "buffet/commands/schema_utils.h" | 
|  |  | 
|  | namespace base { | 
|  | class Value; | 
|  | class DictionaryValue; | 
|  | }  // namespace base | 
|  |  | 
|  | namespace buffet { | 
|  |  | 
|  | // Enumeration to indicate supported command parameter types. | 
|  | enum class ValueType { | 
|  | Int, | 
|  | Double, | 
|  | String, | 
|  | Boolean, | 
|  | Object, | 
|  | Array, | 
|  | }; | 
|  |  | 
|  | class PropValue; | 
|  | class IntValue; | 
|  | class DoubleValue; | 
|  | class StringValue; | 
|  | class BooleanValue; | 
|  | class ObjectValue; | 
|  | class ArrayValue; | 
|  |  | 
|  | class PropType; | 
|  |  | 
|  | // Helper methods to get the parameter type enum value for the given | 
|  | // native C++ data representation. | 
|  | // The generic GetValueType<T>() is undefined, however particular | 
|  | // type specializations return the appropriate ValueType. | 
|  | template<typename T> ValueType GetValueType();  // Undefined. | 
|  | template<> | 
|  | inline ValueType GetValueType<int>() { return ValueType::Int; } | 
|  | template<> | 
|  | inline ValueType GetValueType<double>() { return ValueType::Double; } | 
|  | template<> | 
|  | inline ValueType GetValueType<std::string>() { return ValueType::String; } | 
|  | template<> | 
|  | inline ValueType GetValueType<bool>() { return ValueType::Boolean; } | 
|  | template<> | 
|  | inline ValueType GetValueType<native_types::Object>() { | 
|  | return ValueType::Object; | 
|  | } | 
|  | template<> | 
|  | inline ValueType GetValueType<native_types::Array>() { | 
|  | return ValueType::Array; | 
|  | } | 
|  |  | 
|  | // The base class for property values. | 
|  | // Concrete value classes of various types will be derived from this base. | 
|  | // A property value is the actual command parameter value (or a concrete value | 
|  | // that can be used in constraints and presets). The PropValue is mostly | 
|  | // just parsed content of base::Value when a command is dispatched, however | 
|  | // it does have some additional functionality: | 
|  | //   - it has a reference to the type definition (PropType) which is used | 
|  | //     when validating the value, especially for "object" types. | 
|  | //   - it can be compared with another instances of values of the same type. | 
|  | //     This is used to validate the values against "enum"/"one of" constraints. | 
|  | class PropValue { | 
|  | public: | 
|  | explicit PropValue(std::unique_ptr<const PropType> type); | 
|  | // Special out-of-line constructor to help implement PropValue::Clone(). | 
|  | // That method needs to clone the underlying type but can't do this in this | 
|  | // header file since PropType is just forward-declared (it needs PropValue | 
|  | // fully defined in its own inner workings). | 
|  | explicit PropValue(const PropType* type_ptr); | 
|  | virtual ~PropValue(); | 
|  |  | 
|  | // Gets the type of the value. | 
|  | virtual ValueType GetType() const = 0; | 
|  |  | 
|  | // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>. | 
|  | virtual IntValue* GetInt() { return nullptr; } | 
|  | virtual IntValue const* GetInt() const { return nullptr; } | 
|  | virtual DoubleValue* GetDouble() { return nullptr; } | 
|  | virtual DoubleValue const* GetDouble() const { return nullptr; } | 
|  | virtual StringValue* GetString() { return nullptr; } | 
|  | virtual StringValue const* GetString() const { return nullptr; } | 
|  | virtual BooleanValue* GetBoolean() { return nullptr; } | 
|  | virtual BooleanValue const* GetBoolean() const { return nullptr; } | 
|  | virtual ObjectValue* GetObject() { return nullptr; } | 
|  | virtual ObjectValue const* GetObject() const { return nullptr; } | 
|  | virtual ArrayValue* GetArray() { return nullptr; } | 
|  | virtual ArrayValue const* GetArray() const { return nullptr; } | 
|  |  | 
|  | // Makes a full copy of this value class. | 
|  | virtual std::unique_ptr<PropValue> Clone() const = 0; | 
|  |  | 
|  | // Saves the value as a JSON object. | 
|  | // If it fails, returns nullptr value and fills in the details for the | 
|  | // failure in the |error| parameter. | 
|  | virtual std::unique_ptr<base::Value> ToJson( | 
|  | chromeos::ErrorPtr* error) const = 0; | 
|  | // Parses a value from JSON. | 
|  | // If it fails, it returns false and provides additional information | 
|  | // via the |error| parameter. | 
|  | virtual bool FromJson(const base::Value* value, | 
|  | chromeos::ErrorPtr* error) = 0; | 
|  |  | 
|  | // Returns the contained C++ value as Any. | 
|  | virtual chromeos::Any GetValueAsAny() const = 0; | 
|  |  | 
|  | // Return the type definition of this value. | 
|  | const PropType* GetPropType() const { return type_.get(); } | 
|  | // Compares two values and returns true if they are equal. | 
|  | virtual bool IsEqual(const PropValue* value) const = 0; | 
|  |  | 
|  | protected: | 
|  | std::unique_ptr<const PropType> type_; | 
|  | }; | 
|  |  | 
|  | // A helper template base class for implementing value classes. | 
|  | template<typename Derived, typename T> | 
|  | class TypedValueBase : public PropValue { | 
|  | public: | 
|  | // To help refer to this base class from derived classes, define Base to | 
|  | // be this class. | 
|  | using Base = TypedValueBase<Derived, T>; | 
|  | // Expose the non-default constructor of the base class. | 
|  | using PropValue::PropValue; | 
|  |  | 
|  | // Overrides from PropValue base class. | 
|  | ValueType GetType() const override { return GetValueType<T>(); } | 
|  |  | 
|  | std::unique_ptr<PropValue> Clone() const override { | 
|  | std::unique_ptr<Derived> derived{new Derived{type_.get()}}; | 
|  | derived->value_ = value_; | 
|  | return std::move(derived); | 
|  | } | 
|  |  | 
|  | std::unique_ptr<base::Value> ToJson( | 
|  | chromeos::ErrorPtr* error) const override { | 
|  | return TypedValueToJson(value_, error); | 
|  | } | 
|  |  | 
|  | bool FromJson(const base::Value* value, chromeos::ErrorPtr* error) override { | 
|  | return TypedValueFromJson(value, GetPropType(), &value_, error); | 
|  | } | 
|  |  | 
|  | bool IsEqual(const PropValue* value) const override { | 
|  | if (GetType() != value->GetType()) | 
|  | return false; | 
|  | const Base* value_base = static_cast<const Base*>(value); | 
|  | return CompareValue(GetValue(), value_base->GetValue()); | 
|  | } | 
|  |  | 
|  | // Helper methods to get and set the C++ representation of the value. | 
|  | chromeos::Any GetValueAsAny() const override { return value_; } | 
|  | const T& GetValue() const { return value_; } | 
|  | void SetValue(T value) { value_ = std::move(value); } | 
|  |  | 
|  | protected: | 
|  | T value_{};  // The value of the parameter in C++ data representation. | 
|  | }; | 
|  |  | 
|  | // Value of type Integer. | 
|  | class IntValue final : public TypedValueBase<IntValue, int> { | 
|  | public: | 
|  | using Base::Base;  // Expose the custom constructor of the base class. | 
|  | IntValue* GetInt() override { return this; } | 
|  | IntValue const* GetInt() const override { return this; } | 
|  | }; | 
|  |  | 
|  | // Value of type Number. | 
|  | class DoubleValue final : public TypedValueBase<DoubleValue, double> { | 
|  | public: | 
|  | using Base::Base;  // Expose the custom constructor of the base class. | 
|  | DoubleValue* GetDouble() override { return this; } | 
|  | DoubleValue const* GetDouble() const override { return this; } | 
|  | }; | 
|  |  | 
|  | // Value of type String. | 
|  | class StringValue final : public TypedValueBase<StringValue, std::string> { | 
|  | public: | 
|  | using Base::Base;  // Expose the custom constructor of the base class. | 
|  | StringValue* GetString() override { return this; } | 
|  | StringValue const* GetString() const override { return this; } | 
|  | }; | 
|  |  | 
|  | // Value of type Boolean. | 
|  | class BooleanValue final : public TypedValueBase<BooleanValue, bool> { | 
|  | public: | 
|  | using Base::Base;  // Expose the custom constructor of the base class. | 
|  | BooleanValue* GetBoolean() override { return this; } | 
|  | BooleanValue const* GetBoolean() const override { return this; } | 
|  | }; | 
|  |  | 
|  | // Value of type Object. | 
|  | class ObjectValue final | 
|  | : public TypedValueBase<ObjectValue, native_types::Object> { | 
|  | public: | 
|  | using Base::Base;  // Expose the custom constructor of the base class. | 
|  | ObjectValue* GetObject() override { return this; } | 
|  | ObjectValue const* GetObject() const override { return this; } | 
|  | }; | 
|  |  | 
|  | // Value of type Array. | 
|  | class ArrayValue final | 
|  | : public TypedValueBase<ArrayValue, native_types::Array> { | 
|  | public: | 
|  | using Base::Base;  // Expose the custom constructor of the base class. | 
|  | ArrayValue* GetArray() override { return this; } | 
|  | ArrayValue const* GetArray() const override { return this; } | 
|  | }; | 
|  |  | 
|  | }  // namespace buffet | 
|  |  | 
|  | #endif  // BUFFET_COMMANDS_PROP_VALUES_H_ |