diff options
author | zelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-03 18:31:54 +0000 |
---|---|---|
committer | zelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-03 18:31:54 +0000 |
commit | 4e1ec038f1b270cc4299bb44a0c027ddf55d3dae (patch) | |
tree | 40b6d6ab3d4a6ae836883dfa0e0680edabaf5c38 /base | |
parent | 79b7de9420992e66c38f3adf8d047f8b4ecc0db3 (diff) | |
download | chromium_src-4e1ec038f1b270cc4299bb44a0c027ddf55d3dae.zip chromium_src-4e1ec038f1b270cc4299bb44a0c027ddf55d3dae.tar.gz chromium_src-4e1ec038f1b270cc4299bb44a0c027ddf55d3dae.tar.bz2 |
Added support for parsing out data from simple repetitive values that should not be represented with class/structs.
BUG=chromium-os:30217
TEST=JSONValueConverterTest.*
Review URL: https://chromiumcodereview.appspot.com/10354015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135179 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/json/json_value_converter.h | 51 | ||||
-rw-r--r-- | base/json/json_value_converter_unittest.cc | 28 |
2 files changed, 79 insertions, 0 deletions
diff --git a/base/json/json_value_converter.h b/base/json/json_value_converter.h index d296b66..ff4271d 100644 --- a/base/json/json_value_converter.h +++ b/base/json/json_value_converter.h @@ -328,6 +328,44 @@ class RepeatedMessageConverter DISALLOW_COPY_AND_ASSIGN(RepeatedMessageConverter); }; +template <typename NestedType> +class RepeatedCustomValueConverter + : public ValueConverter<ScopedVector<NestedType> > { + public: + typedef bool(*ConvertFunc)(const base::Value* value, NestedType* field); + + RepeatedCustomValueConverter(ConvertFunc convert_func) + : convert_func_(convert_func) {} + + virtual bool Convert(const base::Value& value, + ScopedVector<NestedType>* field) const OVERRIDE { + const base::ListValue* list = NULL; + if (!value.GetAsList(&list)) + return false; + + field->reserve(list->GetSize()); + for (size_t i = 0; i < list->GetSize(); ++i) { + base::Value* element = NULL; + if (!list->Get(i, &element)) + continue; + + scoped_ptr<NestedType> nested(new NestedType); + if ((*convert_func_)(element, nested.get())) { + field->push_back(nested.release()); + } else { + DVLOG(1) << "failure at " << i << "-th element"; + return false; + } + } + return true; + } + + private: + ConvertFunc convert_func_; + DISALLOW_COPY_AND_ASSIGN(RepeatedCustomValueConverter); +}; + + } // namespace internal template <class StructType> @@ -438,6 +476,19 @@ class JSONValueConverter { } template <class NestedType> + void RegisterRepeatedCustomValue( + const std::string& field_name, + ScopedVector<NestedType> StructType::* field, + bool (*convert_func)(const base::Value*, NestedType*)) { + fields_.push_back( + new internal::FieldConverter<StructType, ScopedVector<NestedType> >( + field_name, + field, + new internal::RepeatedCustomValueConverter<NestedType>( + convert_func))); + } + + template <class NestedType> void RegisterRepeatedMessage(const std::string& field_name, ScopedVector<NestedType> StructType::* field) { fields_.push_back( diff --git a/base/json/json_value_converter_unittest.cc b/base/json/json_value_converter_unittest.cc index 120dd48..925fd5c 100644 --- a/base/json/json_value_converter_unittest.cc +++ b/base/json/json_value_converter_unittest.cc @@ -28,6 +28,7 @@ struct SimpleMessage { bool bstruct; SimpleEnum simple_enum; ScopedVector<int> ints; + ScopedVector<std::string> string_values; SimpleMessage() : foo(0), baz(false), bstruct(false) {} static bool ParseSimpleEnum(const StringPiece& value, SimpleEnum* field) { @@ -46,6 +47,17 @@ struct SimpleMessage { return true; } + static bool GetValueString(const base::Value* value, std::string* result) { + const base::DictionaryValue* dict = NULL; + if (!value->GetAsDictionary(&dict)) + return false; + + if (!dict->GetString("val", result)) + return false; + + return true; + } + static void RegisterJSONConverter( base::JSONValueConverter<SimpleMessage>* converter) { converter->RegisterIntField("foo", &SimpleMessage::foo); @@ -57,6 +69,10 @@ struct SimpleMessage { converter->RegisterCustomValueField<bool>("bstruct", &SimpleMessage::bstruct, &HasFieldPresent); + converter->RegisterRepeatedCustomValue<std::string>( + "string_values", + &SimpleMessage::string_values, + &GetValueString); } }; @@ -85,6 +101,7 @@ TEST(JSONValueConverterTest, ParseSimpleMessage) { " \"bar\": \"bar\",\n" " \"baz\": true,\n" " \"bstruct\": {},\n" + " \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}]," " \"simple_enum\": \"foo\"," " \"ints\": [1, 2]" "}\n"; @@ -99,6 +116,9 @@ TEST(JSONValueConverterTest, ParseSimpleMessage) { EXPECT_TRUE(message.baz); EXPECT_EQ(SimpleMessage::FOO, message.simple_enum); EXPECT_EQ(2, static_cast<int>(message.ints.size())); + ASSERT_EQ(2U, message.string_values.size()); + EXPECT_EQ("value_1", *message.string_values[0]); + EXPECT_EQ("value_2", *message.string_values[1]); EXPECT_EQ(1, *(message.ints[0])); EXPECT_EQ(2, *(message.ints[1])); } @@ -111,12 +131,14 @@ TEST(JSONValueConverterTest, ParseNestedMessage) { " \"foo\": 1,\n" " \"bar\": \"bar\",\n" " \"bstruct\": {},\n" + " \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}]," " \"baz\": true\n" " },\n" " \"children\": [{\n" " \"foo\": 2,\n" " \"bar\": \"foobar\",\n" " \"bstruct\": \"\",\n" + " \"string_values\": [{\"val\": \"value_1\"}]," " \"baz\": true\n" " },\n" " {\n" @@ -136,6 +158,9 @@ TEST(JSONValueConverterTest, ParseNestedMessage) { EXPECT_EQ("bar", message.child.bar); EXPECT_TRUE(message.child.baz); EXPECT_TRUE(message.child.bstruct); + ASSERT_EQ(2U, message.child.string_values.size()); + EXPECT_EQ("value_1", *message.child.string_values[0]); + EXPECT_EQ("value_2", *message.child.string_values[1]); EXPECT_EQ(2, static_cast<int>(message.children.size())); const SimpleMessage* first_child = message.children[0]; @@ -144,6 +169,8 @@ TEST(JSONValueConverterTest, ParseNestedMessage) { EXPECT_EQ("foobar", first_child->bar); EXPECT_TRUE(first_child->baz); EXPECT_TRUE(first_child->bstruct); + ASSERT_EQ(1U, first_child->string_values.size()); + EXPECT_EQ("value_1", *first_child->string_values[0]); const SimpleMessage* second_child = message.children[1]; ASSERT_TRUE(second_child); @@ -151,6 +178,7 @@ TEST(JSONValueConverterTest, ParseNestedMessage) { EXPECT_EQ("barbaz", second_child->bar); EXPECT_FALSE(second_child->baz); EXPECT_FALSE(second_child->bstruct); + EXPECT_EQ(0U, second_child->string_values.size()); } TEST(JSONValueConverterTest, ParseFailures) { |