/* * Copyright (c) 2014, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the * distribution. * * Neither the name of the Ford Motor Company nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef SRC_COMPONENTS_RPC_BASE_INCLUDE_RPC_BASE_RPC_BASE_H_ #define SRC_COMPONENTS_RPC_BASE_INCLUDE_RPC_BASE_RPC_BASE_H_ #include #include #include #include namespace Json { class Value; } // namespace Json namespace rpc { class ValidationReport; namespace policy_table_interface_base { enum PolicyTableType { INVALID_PT_TYPE = -1, PT_PRELOADED, PT_UPDATE, PT_SNAPSHOT }; const std::string omitted_validation_info = "should be omitted in "; const std::string required_validation_info = "is required in "; std::string PolicyTableTypeToString(const PolicyTableType pt_type); } template class Range; class PrimitiveType; class CompositeType; class Boolean; template class Integer; template class Float; template class String; template class Enum; template class Array; template class Map; template class Nullable; template class Optional; template class Stringifyable; template class Range { public: // Methods Range(const T min, const T max); T min() const; T max() const; template bool Includes(U val) const; private: T min_; T max_; }; /* * Base class for all primitive types, keeps a flag to * tell whether descendant object was initialized */ class PrimitiveType { public: bool is_initialized() const; bool is_valid() const; void ReportErrors(ValidationReport* report) const; policy_table_interface_base::PolicyTableType GetPolicyTableType() const; virtual void SetPolicyTableType( policy_table_interface_base::PolicyTableType pt_type); protected: enum ValueState { kUninitialized, kInvalid, kValid }; explicit PrimitiveType(ValueState value_state); static ValueState InitHelper(bool is_next); static ValueState InitHelper(const Json::Value* value, bool (Json::Value::*type_check)() const); protected: ValueState value_state_; policy_table_interface_base::PolicyTableType policy_table_type_; }; /* * Base class for all composite types (arrays and all user-defined types) */ class CompositeType { public: void mark_initialized(); void ReportErrors(ValidationReport* report) const; policy_table_interface_base::PolicyTableType GetPolicyTableType() const; virtual void SetPolicyTableType( policy_table_interface_base::PolicyTableType pt_type); protected: enum InitializationState { kUninitialized, kInitialized, kInvalidInitialized }; explicit CompositeType(InitializationState init_state); virtual ~CompositeType() {} static InitializationState InitHelper(bool is_next); static InitializationState InitHelper(const Json::Value* value, bool (Json::Value::*type_check)() const); protected: mutable InitializationState initialization_state__; policy_table_interface_base::PolicyTableType policy_table_type_; }; /* * Class that holds primitive boolean value. It is always valid. */ class Boolean : public PrimitiveType { public: // Types typedef bool ValueType; public: // Methods Boolean(); explicit Boolean(bool value); explicit Boolean(const Json::Value* value); Boolean(const Json::Value* value, bool def_value); Boolean& operator=(bool new_val); operator bool() const; Json::Value ToJsonValue() const; private: // Fields ValueType value_; }; template class Integer : public PrimitiveType { public: // Types typedef T IntType; public: // Methods Integer(); explicit Integer(IntType value); Integer(const Integer& value); explicit Integer(const Json::Value* value); Integer(const Json::Value* value, IntType def_value); Integer& operator=(IntType new_val); Integer& operator=(const Integer& new_val); Integer& operator++(); Integer& operator+=(int value); operator IntType() const; Json::Value ToJsonValue() const; private: IntType value_; static const Range range_; }; template class Float : public PrimitiveType { public: // Methods Float(); explicit Float(double value); explicit Float(const Json::Value* value); Float(const Json::Value* value, double def_value); Float& operator=(double new_val); operator double() const; Json::Value ToJsonValue() const; private: double value_; static const Range range_; }; template class String : public PrimitiveType { public: // Methods String(); explicit String(const std::string& value); explicit String(const char* value); explicit String(const Json::Value* value); String(const Json::Value* value, const std::string& def_value); bool operator<(const String& new_val) const; String& operator=(const std::string& new_val); String& operator=(const String& new_val); bool operator==(const String& rhs) const; operator const std::string&() const; Json::Value ToJsonValue() const; private: std::string value_; static const Range length_range_; }; template class Enum : public PrimitiveType { public: // Types typedef T EnumType; public: // Methods Enum(); explicit Enum(EnumType value); explicit Enum(const Json::Value* value); Enum(const Json::Value* value, EnumType def_value); Enum& operator=(const EnumType& new_val); operator EnumType() const; Json::Value ToJsonValue() const; private: // Fields EnumType value_; }; template class Array : public std::vector, public CompositeType { public: // Types typedef std::vector ArrayType; public: // Methods Array(); // Need const and non-const versions to beat all-type accepting constructor explicit Array(Json::Value* value); explicit Array(const Json::Value* value); template explicit Array(const U& value); template Array& operator=(const U& that); using ArrayType::push_back; template void push_back(const U& value); Json::Value ToJsonValue() const; virtual bool is_valid() const; bool is_initialized() const; void ReportErrors(ValidationReport* report) const; virtual void SetPolicyTableType( policy_table_interface_base::PolicyTableType pt_type); }; template class Map : public std::map, public CompositeType { public: // Types typedef Map Frankenbase; typedef std::map MapType; public: // Methods Map(); // Need const and non-const versions to beat all-type accepting constructor explicit Map(Json::Value* value); explicit Map(const Json::Value* value); template explicit Map(const U& value); template Map& operator=(const U& that); using MapType::insert; template void insert(const std::pair& value); Json::Value ToJsonValue() const; bool is_valid() const; bool is_initialized() const; void ReportErrors(ValidationReport* report) const; virtual void SetPolicyTableType( policy_table_interface_base::PolicyTableType pt_type); }; template class Nullable : public T { public: // Methods Nullable(); // Need const and non-const versions to beat all-type accepting constructor explicit Nullable(Json::Value* value); explicit Nullable(const Json::Value* value); template explicit Nullable(const U& value); template Nullable(const Json::Value* value, const U& def_value); template Nullable& operator=(const U& new_val); Json::Value ToJsonValue() const; bool is_valid() const; bool is_initialized() const; bool is_null() const; void set_to_null(); void ReportErrors(ValidationReport* report) const; private: bool marked_null_; }; template class Stringifyable : public T { public: // Methods Stringifyable(); // Need const and non-const versions to beat all-type accepting constructor explicit Stringifyable(Json::Value* value); explicit Stringifyable(const Json::Value* value); template explicit Stringifyable(const U& value); template Stringifyable(const Json::Value* value, const U& def_value); template Stringifyable& operator=(const U& new_val); Json::Value ToJsonValue() const; bool is_valid() const; bool is_initialized() const; bool is_string() const; std::string get_string() const; void set_to_string(const std::string& input); void ReportErrors(ValidationReport* report) const; private: std::string predefined_string_; }; template class Optional { public: // Methods Optional(); template explicit Optional(const U& value); template Optional(const Json::Value* value, const U& def_value); Json::Value ToJsonValue() const; // Pointer semantics T& operator*(); const T& operator*() const; T* operator->(); const T* operator->() const; void assign_if_valid(const Optional& value); // For pointer-like 'if (optional_value)' tests // Better than operator bool because bool can be implicitly // casted to integral types operator const void*() const; bool is_valid() const; bool is_initialized() const; void ReportErrors(ValidationReport* report) const; policy_table_interface_base::PolicyTableType GetPolicyTableType() const; virtual void SetPolicyTableType( policy_table_interface_base::PolicyTableType pt_type); protected: policy_table_interface_base::PolicyTableType policy_table_type_; private: T value_; }; } // namespace rpc // Template methods implementation #include "rpc_base_inl.h" #include "rpc_base_json_inl.h" #endif // SRC_COMPONENTS_RPC_BASE_INCLUDE_RPC_BASE_RPC_BASE_H_