| // 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 "buffet/any.h" |
| #include "buffet/commands/schema_utils.h" |
| #include "buffet/error.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 |
| }; |
| |
| class PropValue; |
| class IntValue; |
| class DoubleValue; |
| class StringValue; |
| class BooleanValue; |
| class ObjectValue; |
| |
| 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; |
| } |
| |
| // 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(const PropType* type) |
| : type_(type) {} |
| virtual ~PropValue() = default; |
| |
| // 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; } |
| |
| // Makes a full copy of this value class. |
| virtual std::shared_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(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, |
| ErrorPtr* error) = 0; |
| |
| // Returns the contained C++ value as Any. |
| virtual Any GetValueAsAny() const = 0; |
| |
| // Return the type definition of this value. |
| const PropType* GetPropType() const { return type_; } |
| // Compares two values and returns true if they are equal. |
| virtual bool IsEqual(const PropValue* value) const = 0; |
| |
| protected: |
| const PropType* type_; // weak pointer |
| }; |
| |
| // A helper template base class for implementing simple (non-Object) 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. |
| virtual ValueType GetType() const override { return GetValueType<T>(); } |
| virtual std::shared_ptr<PropValue> Clone() const override { |
| return std::make_shared<Derived>(*static_cast<const Derived*>(this)); |
| } |
| |
| virtual std::unique_ptr<base::Value> ToJson(ErrorPtr* error) const override { |
| return TypedValueToJson(value_, error); |
| } |
| |
| virtual bool FromJson(const base::Value* value, |
| ErrorPtr* error) override { |
| return TypedValueFromJson(value, GetPropType()->GetObjectSchemaPtr(), |
| &value_, error); |
| } |
| |
| virtual 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. |
| virtual 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. |
| virtual IntValue* GetInt() override { return this; } |
| virtual 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. |
| virtual DoubleValue* GetDouble() override { return this; } |
| virtual 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. |
| virtual StringValue* GetString() override { return this; } |
| virtual 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. |
| virtual BooleanValue* GetBoolean() override { return this; } |
| virtual 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. |
| virtual ObjectValue* GetObject() override { return this; } |
| virtual ObjectValue const* GetObject() const override { return this; } |
| }; |
| } // namespace buffet |
| |
| #endif // BUFFET_COMMANDS_PROP_VALUES_H_ |