rpc_base header updates
authorJustin Dickow <jjdickow@gmail.com>
Thu, 17 Jul 2014 18:14:07 +0000 (14:14 -0400)
committerJustin Dickow <jjdickow@gmail.com>
Thu, 17 Jul 2014 18:14:07 +0000 (14:14 -0400)
Authors

Igor Kozyrenko
Nikolay Khlopkov

Signed-off-by: Justin Dickow <jjdickow@gmail.com>
src/components/rpc_base/include/rpc_base/rpc_base.h
src/components/rpc_base/include/rpc_base/rpc_base_inl.h
src/components/rpc_base/include/rpc_base/rpc_base_json_inl.h

index 24bb45b..4d7f260 100644 (file)
@@ -63,19 +63,20 @@ template<typename T, size_t minsize, size_t maxsize> class Array;
 template<typename T, size_t minsize, size_t maxsize> class Map;
 template<typename T> class Nullable;
 template<typename T> class Optional;
+template<typename T> class Stringifyable;
 
 template<typename T>
 class Range {
- public:
-  // Methods
-  Range(const T min, const T max);
-  T min() const;
-  T max() const;
-  template<typename U>
-  bool Includes(U val) const;
- private:
-  T min_;
-  T max_;
 public:
+    // Methods
+    Range(const T min, const T max);
+    T min() const;
+    T max() const;
+    template<typename U>
+    bool Includes(U val) const;
 private:
+    T min_;
+    T max_;
 };
 
 /*
@@ -83,262 +84,289 @@ class Range {
  * tell whether descendant object was initialized
  */
 class PrimitiveType {
- public:
-  bool is_initialized() const;
-  bool is_valid() const;
-  void ReportErrors(ValidationReport* report) const;
- 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_;
 public:
+    bool is_initialized() const;
+    bool is_valid() const;
+    void ReportErrors(ValidationReport* report) const;
 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_;
 };
 
 /*
  * Base class for all composite types (arrays and all user-defined types)
  */
 class CompositeType {
- public:
-  void mark_initialized();
-  void ReportErrors(ValidationReport* report) const;
- protected:
-  enum InitializationState {
-    kUninitialized,
-    kInitialized,
-    kInvalidInitialized
-  };
-  explicit CompositeType(InitializationState init_state);
-  static InitializationState InitHelper(bool is_next);
-  static InitializationState InitHelper(const Json::Value* value,
-                               bool (Json::Value::*type_check)() const);
- protected:
-  InitializationState initialization_state__;
 public:
+    void mark_initialized();
+    void ReportErrors(ValidationReport* report) const;
 protected:
+    enum InitializationState {
+      kUninitialized,
+      kInitialized,
+      kInvalidInitialized
+    };
+    explicit CompositeType(InitializationState init_state);
+    static InitializationState InitHelper(bool is_next);
+    static InitializationState InitHelper(const Json::Value* value,
+                                          bool (Json::Value::*type_check)() const);
 protected:
+    mutable InitializationState initialization_state__;
 };
 
 /*
  * 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);
-  explicit Boolean(dbus::MessageReader* reader);
-  Boolean(const Json::Value* value, bool def_value);
-  Boolean& operator=(bool new_val);
-  operator bool() const;
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
-private:
-  // Fields
-  ValueType value_;
 public:
+    // Types
+    typedef bool ValueType;
 public:
+    // Methods
+    Boolean();
+    explicit Boolean(bool value);
+    explicit Boolean(const Json::Value* value);
+    explicit Boolean(dbus::MessageReader* reader);
+    Boolean(const Json::Value* value, bool def_value);
+    Boolean& operator=(bool new_val);
+    operator bool() const;
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
+  private:
+    // Fields
+    ValueType value_;
 };
 
 template<typename T, T minval, T maxval>
 class Integer : public PrimitiveType {
- public:
-  // Types
-  typedef T IntType;
- public:
-  // Methods
-  Integer();
-  explicit Integer(IntType value);
-  explicit Integer(const Json::Value* value);
-  explicit Integer(dbus::MessageReader* reader);
-  Integer(const Json::Value* value, IntType def_value);
-  Integer& operator=(IntType new_val);
-  operator IntType() const;
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
- private:
-  IntType value_;
-  static const Range<T> range_;
 public:
+    // Types
+    typedef T IntType;
 public:
+    // Methods
+    Integer();
+    explicit Integer(IntType value);
+    explicit Integer(const Json::Value* value);
+    explicit Integer(dbus::MessageReader* reader);
+    Integer(const Json::Value* value, IntType def_value);
+    Integer& operator=(IntType new_val);
+    operator IntType() const;
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
 private:
+    IntType value_;
+    static const Range<T> range_;
 };
 
 template<int64_t minnum, int64_t maxnum, int64_t minden, int64_t maxden>
 class Float : public PrimitiveType {
- public:
-  // Methods
-  Float();
-  explicit Float(double value);
-  explicit Float(const Json::Value* value);
-  explicit Float(dbus::MessageReader* reader);
-  Float(const Json::Value* value, double def_value);
-  Float& operator=(double new_val);
-  operator double() const;
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
- private:
-  double value_;
-  static const Range<double> range_;
 public:
+    // Methods
+    Float();
+    explicit Float(double value);
+    explicit Float(const Json::Value* value);
+    explicit Float(dbus::MessageReader* reader);
+    Float(const Json::Value* value, double def_value);
+    Float& operator=(double new_val);
+    operator double() const;
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
 private:
+    double value_;
+    static const Range<double> range_;
 };
 
 template<size_t minlen, size_t maxlen>
 class String : public PrimitiveType {
- public:
-  // Methods
-  String();
-  explicit String(const std::string& value);
-  explicit String(const char* value);
-  explicit String(const Json::Value* value);
-  explicit String(dbus::MessageReader* reader);
-  String(const Json::Value* value, const std::string& def_value);
-  String& operator=(const std::string& new_val);
-  operator const std::string&() const;
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
- private:
-  std::string value_;
-  static const Range<size_t> length_range_;
 public:
+    // Methods
+    String();
+    explicit String(const std::string& value);
+    explicit String(const char* value);
+    explicit String(const Json::Value* value);
+    explicit String(dbus::MessageReader* reader);
+    String(const Json::Value* value, const std::string& def_value);
+    String& operator=(const std::string& new_val);
+    operator const std::string& () const;
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
 private:
+    std::string value_;
+    static const Range<size_t> length_range_;
 };
 
 template<typename T>
 class Enum : public PrimitiveType {
- public:
-  // Types
-  typedef T EnumType;
- public:
-  // Methods
-  Enum();
-  explicit Enum(EnumType value);
-  explicit Enum(const Json::Value* value);
-  explicit Enum(dbus::MessageReader* reader);
-  Enum(const Json::Value* value, EnumType def_value);
-  Enum& operator=(EnumType new_val);
-  operator EnumType() const;
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
- private:
-  // Fields
-  EnumType value_;
 public:
+    // Types
+    typedef T EnumType;
 public:
+    // Methods
+    Enum();
+    explicit Enum(EnumType value);
+    explicit Enum(const Json::Value* value);
+    explicit Enum(dbus::MessageReader* reader);
+    Enum(const Json::Value* value, EnumType def_value);
+    Enum& operator=(EnumType new_val);
+    operator EnumType() const;
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
 private:
+    // Fields
+    EnumType value_;
 };
 
 template<typename T, size_t minsize, size_t maxsize>
 class Array : public std::vector<T>, public CompositeType {
- public:
-  // Types
-  typedef std::vector<T> 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);
-  explicit Array(dbus::MessageReader* reader);
-  template<typename U>
-  explicit Array(const U& value);
-  template<typename U>
-  Array& operator=(const U& that);
-  using ArrayType::push_back;
-  template<typename U>
-  void push_back(const U& value);
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
-  bool is_valid() const;
-  bool is_initialized() const;
-  void ReportErrors(ValidationReport* report) const;
 public:
+    // Types
+    typedef std::vector<T> 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);
+    explicit Array(dbus::MessageReader* reader);
+    template<typename U>
+    explicit Array(const U& value);
+    template<typename U>
+    Array& operator=(const U& that);
+    using ArrayType::push_back;
+    template<typename U>
+    void push_back(const U& value);
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
+    bool is_valid() const;
+    bool is_initialized() const;
+    void ReportErrors(ValidationReport* report) const;
 };
 
 template<typename T, size_t minsize, size_t maxsize>
 class Map : public std::map<std::string, T>, public CompositeType  {
- public:
-  // Types
-  typedef Map<T, minsize, maxsize> Frankenbase;
-  typedef std::map<std::string, T> 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);
-  explicit Map(dbus::MessageReader* reader);
-  template<typename U>
-  explicit Map(const U& value);
-  template<typename U>
-  Map& operator=(const U& that);
-  using MapType::insert;
-  template<typename U>
-  void insert(const std::pair<std::string, U>& value);
-  Json::Value ToJsonValue() const;
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
-  bool is_valid() const;
-  bool is_initialized() const;
-  void ReportErrors(ValidationReport* report) const;
 public:
+    // Types
+    typedef Map<T, minsize, maxsize> Frankenbase;
+    typedef std::map<std::string, T> 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);
+    explicit Map(dbus::MessageReader* reader);
+    template<typename U>
+    explicit Map(const U& value);
+    template<typename U>
+    Map& operator=(const U& that);
+    using MapType::insert;
+    template<typename U>
+    void insert(const std::pair<std::string, U>& value);
+    Json::Value ToJsonValue() const;
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
+    bool is_valid() const;
+    bool is_initialized() const;
+    void ReportErrors(ValidationReport* report) const;
 };
 
 template<typename T>
 class Nullable : public T {
- public:
-  // Methods
-  Nullable();
-  explicit Nullable(dbus::MessageReader* reader);
-  // Need const and non-const versions to beat all-type accepting constructor
-  explicit Nullable(Json::Value* value);
-  explicit Nullable(const Json::Value* value);
-  template<typename U>
-  explicit Nullable(const U& value);
-  template<typename U>
-  Nullable(const Json::Value* value, const U& def_value);
-  template<typename U>
-  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_;
+  public:
+    // Methods
+    Nullable();
+    explicit Nullable(dbus::MessageReader* reader);
+    // Need const and non-const versions to beat all-type accepting constructor
+    explicit Nullable(Json::Value* value);
+    explicit Nullable(const Json::Value* value);
+    template<typename U>
+    explicit Nullable(const U& value);
+    template<typename U>
+    Nullable(const Json::Value* value, const U& def_value);
+    template<typename U>
+    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<typename T>
+class Stringifyable : public T {
+  public:
+    // Methods
+    Stringifyable();
+    explicit Stringifyable(dbus::MessageReader* reader);
+    // Need const and non-const versions to beat all-type accepting constructor
+    explicit Stringifyable(Json::Value* value);
+    explicit Stringifyable(const Json::Value* value);
+    template<typename U>
+    explicit Stringifyable(const U& value);
+    template<typename U>
+    Stringifyable(const Json::Value* value, const U& def_value);
+    template<typename U>
+    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<typename T>
 class Optional {
- public:
-  // Methods
-  Optional();
-  explicit Optional(dbus::MessageReader* reader);
-  template<typename U>
-  explicit Optional(const U& value);
-  template<typename U>
-  Optional(const Json::Value* value,const U& def_value);
-  Json::Value ToJsonValue() const;
-
-  void ToDbusWriter(dbus::MessageWriter* writer) const;
-
-  // Pointer semantics
-  T& operator*();
-  const T& operator*() const;
-  T* operator->();
-  const T* operator->() const;
-  // 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;
- private:
-  T value_;
 public:
+    // Methods
+    Optional();
+    explicit Optional(dbus::MessageReader* reader);
+    template<typename U>
+    explicit Optional(const U& value);
+    template<typename U>
+    Optional(const Json::Value* value, const U& def_value);
+    Json::Value ToJsonValue() const;
+
+    void ToDbusWriter(dbus::MessageWriter* writer) const;
+
+    // Pointer semantics
+    T& operator*();
+    const T& operator*() const;
+    T* operator->();
+    const T* operator->() const;
+    // 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;
 private:
+    T value_;
 };
 
 }  // namespace rpc
index b6a5473..96d9bf8 100644 (file)
@@ -325,8 +325,9 @@ bool Array<T, minsize, maxsize>::is_valid() const {
   // All array elements must be valid
   for (typename ArrayType::const_iterator i = this->begin();
       i != this->end(); ++i) {
-    if (!i->is_valid())
+    if (!i->is_valid()) {
       return false;
+    }
   }
   return true;
 }
@@ -420,8 +421,9 @@ bool Map<T, minsize, maxsize>::is_valid() const {
   // All map elements must be valid
   for (typename Map::const_iterator i = this->begin();
       i != this->end(); ++i) {
-    if (!i->second.is_valid())
+    if (!i->second.is_valid()) {
       return false;
+    }
   }
   return true;
 }
@@ -568,6 +570,62 @@ void Optional<T>::ReportErrors(ValidationReport* report) const {
   }
 }
 
+/*
+ * Stringifyable class
+ */
+template<typename T>
+Stringifyable<T>::Stringifyable()
+  : predefined_string_("") {
+}
+
+template<typename T>
+template<typename U>
+Stringifyable<T>::Stringifyable(const U& value)
+  : T(value),
+    predefined_string_("") {
+}
+
+template<typename T>
+template<typename U>
+Stringifyable<T>& Stringifyable<T>::operator=(const U& new_val) {
+  this->T::operator=(new_val);
+  return *this;
+}
+
+template<typename T>
+bool Stringifyable<T>::is_valid() const {
+  return is_string() || T::is_valid();
+}
+
+template<typename T>
+bool Stringifyable<T>::is_initialized() const {
+  return is_string() || T::is_initialized();
+}
+
+template<typename T>
+bool Stringifyable<T>::is_string() const {
+  return !predefined_string_.empty();
+}
+
+template<typename T>
+std::string Stringifyable<T>::get_string() const {
+  return predefined_string_;
+}
+
+template<typename T>
+void Stringifyable<T>::set_to_string(const std::string& input) {
+  predefined_string_ = input;
+}
+
+template<typename T>
+void Stringifyable<T>::ReportErrors(ValidationReport* report) const {
+  if (is_string()) {
+    // No error
+  } else {
+    T::ReportErrors(report);
+  }
+}
+
 }  // namespace rpc
 
 
index 93d0729..f48021b 100644 (file)
@@ -40,8 +40,8 @@ namespace rpc {
 
 // static
 inline PrimitiveType::ValueState PrimitiveType::InitHelper(
-    const Json::Value* value,
-    bool (Json::Value::*type_check)() const) {
+  const Json::Value* value,
+  bool (Json::Value::*type_check)() const) {
   if (!value) {
     return kUninitialized;
   } else if ((value->*type_check)()) {
@@ -53,8 +53,8 @@ inline PrimitiveType::ValueState PrimitiveType::InitHelper(
 
 // static
 inline CompositeType::InitializationState CompositeType::InitHelper(
-    const Json::Value* value,
-    bool (Json::Value::*type_check)() const) {
+  const Json::Value* value,
+  bool (Json::Value::*type_check)() const) {
   if (!value) {
     return kUninitialized;
   } else if ((value->*type_check)()) {
@@ -91,13 +91,13 @@ inline void WriteJsonField(const char* field_name,
 }  // namespace impl
 
 inline Boolean::Boolean(const Json::Value* value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isBool)),
-      value_(is_valid() ? value->asBool() : bool()) {
+  : PrimitiveType(InitHelper(value, &Json::Value::isBool)),
+    value_(is_valid() ? value->asBool() : bool()) {
 }
 
 inline Boolean::Boolean(const Json::Value* value, bool def_value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isBool)),
-      value_(is_valid() ? value->asBool() : def_value) {
+  : PrimitiveType(InitHelper(value, &Json::Value::isBool)),
+    value_(is_valid() ? value->asBool() : def_value) {
   // If there is no value, mark it as valid and use def_value
   if (!is_initialized()) {
     value_state_ = kValid;
@@ -110,8 +110,8 @@ inline Json::Value Boolean::ToJsonValue() const {
 
 template<typename T, T minval, T maxval>
 Integer<T, minval, maxval>::Integer(const Json::Value* value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isInt)),
-      value_() {
+  : PrimitiveType(InitHelper(value, &Json::Value::isInt)),
+    value_() {
   if (is_valid()) {
     Json::Value::Int64 intval = value->asInt64();
     if (range_.Includes(intval)) {
@@ -124,8 +124,8 @@ Integer<T, minval, maxval>::Integer(const Json::Value* value)
 
 template<typename T, T minval, T maxval>
 Integer<T, minval, maxval>::Integer(const Json::Value* value, IntType def_value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isInt)),
-      value_(def_value) {
+  : PrimitiveType(InitHelper(value, &Json::Value::isInt)),
+    value_(def_value) {
   if (!is_initialized()) {
     value_state_ = kValid;
   } else if (is_valid()) {
@@ -145,8 +145,8 @@ Json::Value Integer<T, minval, maxval>::ToJsonValue() const {
 
 template<int64_t minnum, int64_t maxnum, int64_t minden, int64_t maxden>
 Float<minnum, maxnum, minden, maxden>::Float(const Json::Value* value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isDouble)),
-      value_() {
+  : PrimitiveType(InitHelper(value, &Json::Value::isDouble)),
+    value_() {
   if (is_valid()) {
     value_ = value->asDouble();
     value_state_ = range_.Includes(value_) ? kValid : kInvalid;
@@ -155,9 +155,9 @@ Float<minnum, maxnum, minden, maxden>::Float(const Json::Value* value)
 
 template<int64_t minnum, int64_t maxnum, int64_t minden, int64_t maxden>
 Float<minnum, maxnum, minden, maxden>::Float(const Json::Value* value,
-                                             double def_value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isDouble)),
-      value_(def_value) {
+    double def_value)
+  : PrimitiveType(InitHelper(value, &Json::Value::isDouble)),
+    value_(def_value) {
   if (!is_initialized()) {
     value_state_ = kValid;
   } else if (is_valid()) {
@@ -173,8 +173,8 @@ Json::Value Float<minnum, maxnum, minden, maxden>::ToJsonValue() const {
 
 template<size_t minlen, size_t maxlen>
 String<minlen, maxlen>::String(const Json::Value* value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isString)),
-      value_(is_valid() ? value->asString() : std::string()) {
+  : PrimitiveType(InitHelper(value, &Json::Value::isString)),
+    value_(is_valid() ? value->asString() : std::string()) {
   if (is_valid()) {
     value_state_ = length_range_.Includes(value_.length()) ? kValid : kInvalid;
   }
@@ -196,23 +196,23 @@ Json::Value String<minlen, maxlen>::ToJsonValue() const {
 
 template<typename T>
 Enum<T>::Enum(const Json::Value* value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isString)),
-      value_(EnumType()) {
+  : PrimitiveType(InitHelper(value, &Json::Value::isString)),
+    value_(EnumType()) {
   if (is_valid()) {
     value_state_ =
-        EnumFromJsonString(value->asString(), &value_) ? kValid : kInvalid;
+      EnumFromJsonString(value->asString(), &value_) ? kValid : kInvalid;
   }
 }
 
 template<typename T>
 Enum<T>::Enum(const Json::Value* value, EnumType def_value)
-    : PrimitiveType(InitHelper(value, &Json::Value::isString)),
-      value_(def_value) {
+  : PrimitiveType(InitHelper(value, &Json::Value::isString)),
+    value_(def_value) {
   if (!is_initialized()) {
     value_state_ = kValid;
   } else if (is_valid()) {
     value_state_ =
-        EnumFromJsonString(value->asString(), &value_) ? kValid : kInvalid;
+      EnumFromJsonString(value->asString(), &value_) ? kValid : kInvalid;
   }
 }
 
@@ -224,7 +224,7 @@ Json::Value Enum<T>::ToJsonValue() const {
 // Non-const version
 template<typename T, size_t minsize, size_t maxsize>
 Array<T, minsize, maxsize>::Array(Json::Value* value)
-    : CompositeType(InitHelper(value, &Json::Value::isArray)) {
+  : CompositeType(InitHelper(value, &Json::Value::isArray)) {
   if (value) {
     if (value->isArray()) {
       this->reserve(value->size());
@@ -241,7 +241,7 @@ Array<T, minsize, maxsize>::Array(Json::Value* value)
 // Const version, must be identical to the non-const version
 template<typename T, size_t minsize, size_t maxsize>
 Array<T, minsize, maxsize>::Array(const Json::Value* value)
-    : CompositeType(InitHelper(value, &Json::Value::isArray)) {
+  : CompositeType(InitHelper(value, &Json::Value::isArray)) {
   if (value) {
     if (value->isArray()) {
       this->reserve(value->size());
@@ -268,7 +268,7 @@ Json::Value Array<T, minsize, maxsize>::ToJsonValue() const {
 // Non-const version
 template<typename T, size_t minsize, size_t maxsize>
 Map<T, minsize, maxsize>::Map(Json::Value* value)
-    : CompositeType(InitHelper(value, &Json::Value::isObject)) {
+  : CompositeType(InitHelper(value, &Json::Value::isObject)) {
   if (value) {
     if (value->isObject()) {
       for (Json::Value::iterator i = value->begin(); i != value->end(); ++i) {
@@ -283,7 +283,7 @@ Map<T, minsize, maxsize>::Map(Json::Value* value)
 
 template<typename T, size_t minsize, size_t maxsize>
 Map<T, minsize, maxsize>::Map(const Json::Value* value)
-    : CompositeType(InitHelper(value, &Json::Value::isObject)) {
+  : CompositeType(InitHelper(value, &Json::Value::isObject)) {
   if (value) {
     if (value->isObject()) {
       for (Json::Value::const_iterator i = value->begin(); i != value->end(); ++i) {
@@ -307,21 +307,21 @@ Json::Value Map<T, minsize, maxsize>::ToJsonValue() const {
 
 template<typename T>
 Nullable<T>::Nullable(const Json::Value* value)
-    : T(value),
-      marked_null_(value != NULL && value->isNull()){
+  : T(value),
+    marked_null_(value != NULL&&  value->isNull()) {
 }
 
 template<typename T>
 Nullable<T>::Nullable(Json::Value* value)
-    : T(value),
-      marked_null_(value != NULL && value->isNull()){
+  : T(value),
+    marked_null_(value != NULL&&  value->isNull()) {
 }
 
 template<typename T>
 template<typename U>
 Nullable<T>::Nullable(const Json::Value* value, const U& def_value)
-    : T(value, def_value),
-      marked_null_(value != NULL && value->isNull()) {
+  : T(value, def_value),
+    marked_null_(value != NULL&&  value->isNull()) {
 }
 
 template<typename T>
@@ -332,7 +332,7 @@ inline Json::Value Nullable<T>::ToJsonValue() const {
 template<typename T>
 template<typename U>
 Optional<T>::Optional(const Json::Value* value, const U& def_value)
-    : value_(value, def_value) {
+  : value_(value, def_value) {
 }
 
 template<typename T>
@@ -340,6 +340,30 @@ inline Json::Value Optional<T>::ToJsonValue() const {
   return value_.ToJsonValue();
 }
 
+template<typename T>
+Stringifyable<T>::Stringifyable(const Json::Value* value)
+  : T(NULL != value&&  !value->isString() ? value : NULL),
+    predefined_string_(NULL != value&&   value->isString() ? value->asString() : "") {
+}
+
+template<typename T>
+Stringifyable<T>::Stringifyable(Json::Value* value)
+  : T(NULL != value&&  !value->isString() ? value : NULL),
+    predefined_string_(NULL != value&&   value->isString() ? value->asString() : "") {
+}
+
+template<typename T>
+template<typename U>
+Stringifyable<T>::Stringifyable(const Json::Value* value, const U& def_value)
+  : T(NULL != value&&  !value->isString() ? (value, def_value) : NULL),
+    predefined_string_(NULL != value&&   value->isString() ? value->asString() : "")  {
+}
+
+template<typename T>
+inline Json::Value Stringifyable<T>::ToJsonValue() const {
+  return predefined_string_.empty() ? T::ToJsonValue() : predefined_string_;
+}
+
 }  // namespace rpc
 
 #endif /* VALIDATED_TYPES_JSON_INL_H_ */