Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(586)

Unified Diff: base/json/json_value_converter.h

Issue 8952029: Returns a bool for JSONValueConverter::Convert() (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix code and add more tests Created 8 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/json/json_value_converter_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/json/json_value_converter.h
diff --git a/base/json/json_value_converter.h b/base/json/json_value_converter.h
index 64cd90b7aa6e9dfe84ea394655e3ee25ba13f775..7d8357fe9d7437cb6c98840393effec10a6dd437 100644
--- a/base/json/json_value_converter.h
+++ b/base/json/json_value_converter.h
@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
+#include "base/string16.h"
#include "base/values.h"
// JSONValueConverter converts a JSON value into a C++ struct in a
@@ -45,12 +46,18 @@
// JSONValueConverter<Message> converter;
// converter.Convert(json, &message);
//
+// Convert() returns false when it fails. Here "fail" means that the value is
+// structurally different from expected, such like a string value appears
+// for an int field. Do not report failures for missing fields.
+// Also note that Convert() will modify the passed |message| even when it
+// fails for performance reason.
+//
// For nested field, the internal message also has to implement the registration
// method. Then, just use RegisterNestedField() from the containing struct's
// RegisterJSONConverter method.
// struct Nested {
// Message foo;
-// void RegisterJSONConverter(...) {
+// static void RegisterJSONConverter(...) {
// ...
// converter->RegisterNestedField("foo", &Nested::foo);
// }
@@ -72,7 +79,7 @@ class FieldConverterBase {
public:
BASE_EXPORT explicit FieldConverterBase(const std::string& path);
BASE_EXPORT virtual ~FieldConverterBase();
- virtual void ConvertField(const base::Value& value, void* obj) const = 0;
+ virtual bool ConvertField(const base::Value& value, void* obj) const = 0;
const std::string& field_path() const { return field_path_; }
private:
@@ -84,7 +91,7 @@ template <typename FieldType>
class ValueConverter {
public:
virtual ~ValueConverter() {}
- virtual void Convert(const base::Value& value, FieldType* field) const = 0;
+ virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
};
template <typename StructType, typename FieldType>
@@ -98,10 +105,10 @@ class FieldConverter : public FieldConverterBase {
value_converter_(converter) {
}
- virtual void ConvertField(
+ virtual bool ConvertField(
const base::Value& value, void* obj) const OVERRIDE {
StructType* dst = reinterpret_cast<StructType*>(obj);
- value_converter_->Convert(value, &(dst->*field_pointer_));
+ return value_converter_->Convert(value, &(dst->*field_pointer_));
}
private:
@@ -118,8 +125,8 @@ class BasicValueConverter<int> : public ValueConverter<int> {
public:
BasicValueConverter() {}
- virtual void Convert(const base::Value& value, int* field) const OVERRIDE {
- value.GetAsInteger(field);
+ virtual bool Convert(const base::Value& value, int* field) const OVERRIDE {
+ return value.GetAsInteger(field);
}
private:
@@ -131,9 +138,23 @@ class BasicValueConverter<std::string> : public ValueConverter<std::string> {
public:
BasicValueConverter() {}
- virtual void Convert(
+ virtual bool Convert(
const base::Value& value, std::string* field) const OVERRIDE {
- value.GetAsString(field);
+ return value.GetAsString(field);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
+};
+
+template <>
+class BasicValueConverter<string16> : public ValueConverter<string16> {
+ public:
+ BasicValueConverter() {}
+
+ virtual bool Convert(
+ const base::Value& value, string16* field) const OVERRIDE {
+ return value.GetAsString(field);
}
private:
@@ -145,8 +166,8 @@ class BasicValueConverter<double> : public ValueConverter<double> {
public:
BasicValueConverter() {}
- virtual void Convert(const base::Value& value, double* field) const OVERRIDE {
- value.GetAsDouble(field);
+ virtual bool Convert(const base::Value& value, double* field) const OVERRIDE {
+ return value.GetAsDouble(field);
}
private:
@@ -158,8 +179,8 @@ class BasicValueConverter<bool> : public ValueConverter<bool> {
public:
BasicValueConverter() {}
- virtual void Convert(const base::Value& value, bool* field) const OVERRIDE {
- value.GetAsBoolean(field);
+ virtual bool Convert(const base::Value& value, bool* field) const OVERRIDE {
+ return value.GetAsBoolean(field);
}
private:
@@ -171,9 +192,9 @@ class NestedValueConverter : public ValueConverter<NestedType> {
public:
NestedValueConverter() {}
- virtual void Convert(
+ virtual bool Convert(
const base::Value& value, NestedType* field) const OVERRIDE {
- converter_.Convert(value, field);
+ return converter_.Convert(value, field);
}
private:
@@ -186,12 +207,12 @@ class RepeatedValueConverter : public ValueConverter<std::vector<Element> > {
public:
RepeatedValueConverter() {}
- virtual void Convert(
+ virtual bool Convert(
const base::Value& value, std::vector<Element>* field) const OVERRIDE {
const base::ListValue* list = NULL;
if (!value.GetAsList(&list)) {
// The field is not a list.
- return;
+ return false;
}
field->reserve(list->GetSize());
@@ -201,9 +222,13 @@ class RepeatedValueConverter : public ValueConverter<std::vector<Element> > {
continue;
Element e;
- basic_converter_.Convert(*element, &e);
+ if (!basic_converter_.Convert(*element, &e)) {
+ DVLOG(1) << "failure at " << i << "-th element";
+ return false;
+ }
field->push_back(e);
}
+ return true;
}
private:
@@ -217,11 +242,11 @@ class RepeatedMessageConverter
public:
RepeatedMessageConverter() {}
- virtual void Convert(
+ virtual bool Convert(
const base::Value& value, std::vector<NestedType>* field) const OVERRIDE {
const base::ListValue* list = NULL;
if (!value.GetAsList(&list))
- return;
+ return false;
field->reserve(list->GetSize());
for (size_t i = 0; i < list->GetSize(); ++i) {
@@ -230,8 +255,12 @@ class RepeatedMessageConverter
continue;
field->push_back(NestedType());
- converter_.Convert(*element, &field->back());
+ if (!converter_.Convert(*element, &field->back())) {
+ DVLOG(1) << "failure at " << i << "-th element";
+ return false;
+ }
}
+ return true;
}
private:
@@ -259,11 +288,17 @@ class JSONValueConverter {
}
void RegisterStringField(const std::string& field_name,
- std::string StructType::* field) {
+ std::string StructType::* field) {
fields_.push_back(new internal::FieldConverter<StructType, std::string>(
field_name, field, new internal::BasicValueConverter<std::string>));
}
+ void RegisterStringField(const std::string& field_name,
+ string16 StructType::* field) {
+ fields_.push_back(new internal::FieldConverter<StructType, string16>(
+ field_name, field, new internal::BasicValueConverter<string16>));
+ }
+
void RegisterBoolField(const std::string& field_name,
bool StructType::* field) {
fields_.push_back(new internal::FieldConverter<StructType, bool>(
@@ -301,6 +336,15 @@ class JSONValueConverter {
new internal::RepeatedValueConverter<std::string>));
}
+ void RegisterRepeatedString(const std::string& field_name,
+ std::vector<string16> StructType::* field) {
+ fields_.push_back(
+ new internal::FieldConverter<StructType, std::vector<string16> >(
+ field_name,
+ field,
+ new internal::RepeatedValueConverter<string16>));
+ }
+
void RegisterRepeatedDouble(const std::string& field_name,
std::vector<double> StructType::* field) {
fields_.push_back(
@@ -325,18 +369,22 @@ class JSONValueConverter {
new internal::RepeatedMessageConverter<NestedType>));
}
- void Convert(const base::Value& value, StructType* output) const {
+ bool Convert(const base::Value& value, StructType* output) const {
const DictionaryValue* dictionary_value = NULL;
if (!value.GetAsDictionary(&dictionary_value))
- return;
+ return false;
for(std::vector<internal::FieldConverterBase*>::const_iterator it =
fields_.begin(); it != fields_.end(); ++it) {
base::Value* field = NULL;
if (dictionary_value->Get((*it)->field_path(), &field)) {
- (*it)->ConvertField(*field, output);
+ if (!(*it)->ConvertField(*field, output)) {
+ DVLOG(1) << "failure at field " << (*it)->field_path();
+ return false;
+ }
}
}
+ return true;
}
private:
« no previous file with comments | « no previous file | base/json/json_value_converter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698