| Index: base/json/json_value_converter.h
|
| diff --git a/base/json/json_value_converter.h b/base/json/json_value_converter.h
|
| deleted file mode 100644
|
| index f94d46e3ccf71cbd7a19aeef0c608dcd17b14a06..0000000000000000000000000000000000000000
|
| --- a/base/json/json_value_converter.h
|
| +++ /dev/null
|
| @@ -1,514 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium 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 BASE_JSON_JSON_VALUE_CONVERTER_H_
|
| -#define BASE_JSON_JSON_VALUE_CONVERTER_H_
|
| -
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/base_export.h"
|
| -#include "base/basictypes.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/memory/scoped_vector.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/strings/string_piece.h"
|
| -#include "base/values.h"
|
| -
|
| -// JSONValueConverter converts a JSON value into a C++ struct in a
|
| -// lightweight way.
|
| -//
|
| -// Usage:
|
| -// For real examples, you may want to refer to _unittest.cc file.
|
| -//
|
| -// Assume that you have a struct like this:
|
| -// struct Message {
|
| -// int foo;
|
| -// std::string bar;
|
| -// static void RegisterJSONConverter(
|
| -// JSONValueConverter<Message>* converter);
|
| -// };
|
| -//
|
| -// And you want to parse a json data into this struct. First, you
|
| -// need to declare RegisterJSONConverter() method in your struct.
|
| -// // static
|
| -// void Message::RegisterJSONConverter(
|
| -// JSONValueConverter<Message>* converter) {
|
| -// converter->RegisterIntField("foo", &Message::foo);
|
| -// converter->RegisterStringField("bar", &Message::bar);
|
| -// }
|
| -//
|
| -// Then, you just instantiate your JSONValueConverter of your type and call
|
| -// Convert() method.
|
| -// Message message;
|
| -// 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;
|
| -// static void RegisterJSONConverter(...) {
|
| -// ...
|
| -// converter->RegisterNestedField("foo", &Nested::foo);
|
| -// }
|
| -// };
|
| -//
|
| -// For repeated field, we just assume ScopedVector for its container
|
| -// and you can put RegisterRepeatedInt or some other types. Use
|
| -// RegisterRepeatedMessage for nested repeated fields.
|
| -//
|
| -// Sometimes JSON format uses string representations for other types such
|
| -// like enum, timestamp, or URL. You can use RegisterCustomField method
|
| -// and specify a function to convert a StringPiece to your type.
|
| -// bool ConvertFunc(const StringPiece& s, YourEnum* result) {
|
| -// // do something and return true if succeed...
|
| -// }
|
| -// struct Message {
|
| -// YourEnum ye;
|
| -// ...
|
| -// static void RegisterJSONConverter(...) {
|
| -// ...
|
| -// converter->RegsiterCustomField<YourEnum>(
|
| -// "your_enum", &Message::ye, &ConvertFunc);
|
| -// }
|
| -// };
|
| -
|
| -namespace base {
|
| -
|
| -template <typename StructType>
|
| -class JSONValueConverter;
|
| -
|
| -namespace internal {
|
| -
|
| -template<typename StructType>
|
| -class FieldConverterBase {
|
| - public:
|
| - explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
|
| - virtual ~FieldConverterBase() {}
|
| - virtual bool ConvertField(const base::Value& value, StructType* obj)
|
| - const = 0;
|
| - const std::string& field_path() const { return field_path_; }
|
| -
|
| - private:
|
| - std::string field_path_;
|
| - DISALLOW_COPY_AND_ASSIGN(FieldConverterBase);
|
| -};
|
| -
|
| -template <typename FieldType>
|
| -class ValueConverter {
|
| - public:
|
| - virtual ~ValueConverter() {}
|
| - virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
|
| -};
|
| -
|
| -template <typename StructType, typename FieldType>
|
| -class FieldConverter : public FieldConverterBase<StructType> {
|
| - public:
|
| - explicit FieldConverter(const std::string& path,
|
| - FieldType StructType::* field,
|
| - ValueConverter<FieldType>* converter)
|
| - : FieldConverterBase<StructType>(path),
|
| - field_pointer_(field),
|
| - value_converter_(converter) {
|
| - }
|
| -
|
| - bool ConvertField(const base::Value& value, StructType* dst) const override {
|
| - return value_converter_->Convert(value, &(dst->*field_pointer_));
|
| - }
|
| -
|
| - private:
|
| - FieldType StructType::* field_pointer_;
|
| - scoped_ptr<ValueConverter<FieldType> > value_converter_;
|
| - DISALLOW_COPY_AND_ASSIGN(FieldConverter);
|
| -};
|
| -
|
| -template <typename FieldType>
|
| -class BasicValueConverter;
|
| -
|
| -template <>
|
| -class BASE_EXPORT BasicValueConverter<int> : public ValueConverter<int> {
|
| - public:
|
| - BasicValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value, int* field) const override;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
|
| -};
|
| -
|
| -template <>
|
| -class BASE_EXPORT BasicValueConverter<std::string>
|
| - : public ValueConverter<std::string> {
|
| - public:
|
| - BasicValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value, std::string* field) const override;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
|
| -};
|
| -
|
| -template <>
|
| -class BASE_EXPORT BasicValueConverter<string16>
|
| - : public ValueConverter<string16> {
|
| - public:
|
| - BasicValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value, string16* field) const override;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
|
| -};
|
| -
|
| -template <>
|
| -class BASE_EXPORT BasicValueConverter<double> : public ValueConverter<double> {
|
| - public:
|
| - BasicValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value, double* field) const override;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
|
| -};
|
| -
|
| -template <>
|
| -class BASE_EXPORT BasicValueConverter<bool> : public ValueConverter<bool> {
|
| - public:
|
| - BasicValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value, bool* field) const override;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(BasicValueConverter);
|
| -};
|
| -
|
| -template <typename FieldType>
|
| -class ValueFieldConverter : public ValueConverter<FieldType> {
|
| - public:
|
| - typedef bool(*ConvertFunc)(const base::Value* value, FieldType* field);
|
| -
|
| - ValueFieldConverter(ConvertFunc convert_func)
|
| - : convert_func_(convert_func) {}
|
| -
|
| - bool Convert(const base::Value& value, FieldType* field) const override {
|
| - return convert_func_(&value, field);
|
| - }
|
| -
|
| - private:
|
| - ConvertFunc convert_func_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ValueFieldConverter);
|
| -};
|
| -
|
| -template <typename FieldType>
|
| -class CustomFieldConverter : public ValueConverter<FieldType> {
|
| - public:
|
| - typedef bool(*ConvertFunc)(const StringPiece& value, FieldType* field);
|
| -
|
| - CustomFieldConverter(ConvertFunc convert_func)
|
| - : convert_func_(convert_func) {}
|
| -
|
| - bool Convert(const base::Value& value, FieldType* field) const override {
|
| - std::string string_value;
|
| - return value.GetAsString(&string_value) &&
|
| - convert_func_(string_value, field);
|
| - }
|
| -
|
| - private:
|
| - ConvertFunc convert_func_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CustomFieldConverter);
|
| -};
|
| -
|
| -template <typename NestedType>
|
| -class NestedValueConverter : public ValueConverter<NestedType> {
|
| - public:
|
| - NestedValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value, NestedType* field) const override {
|
| - return converter_.Convert(value, field);
|
| - }
|
| -
|
| - private:
|
| - JSONValueConverter<NestedType> converter_;
|
| - DISALLOW_COPY_AND_ASSIGN(NestedValueConverter);
|
| -};
|
| -
|
| -template <typename Element>
|
| -class RepeatedValueConverter : public ValueConverter<ScopedVector<Element> > {
|
| - public:
|
| - RepeatedValueConverter() {}
|
| -
|
| - bool Convert(const base::Value& value,
|
| - ScopedVector<Element>* field) const override {
|
| - const base::ListValue* list = NULL;
|
| - if (!value.GetAsList(&list)) {
|
| - // The field is not a list.
|
| - return false;
|
| - }
|
| -
|
| - field->reserve(list->GetSize());
|
| - for (size_t i = 0; i < list->GetSize(); ++i) {
|
| - const base::Value* element = NULL;
|
| - if (!list->Get(i, &element))
|
| - continue;
|
| -
|
| - scoped_ptr<Element> e(new Element);
|
| - if (basic_converter_.Convert(*element, e.get())) {
|
| - field->push_back(e.release());
|
| - } else {
|
| - DVLOG(1) << "failure at " << i << "-th element";
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - private:
|
| - BasicValueConverter<Element> basic_converter_;
|
| - DISALLOW_COPY_AND_ASSIGN(RepeatedValueConverter);
|
| -};
|
| -
|
| -template <typename NestedType>
|
| -class RepeatedMessageConverter
|
| - : public ValueConverter<ScopedVector<NestedType> > {
|
| - public:
|
| - RepeatedMessageConverter() {}
|
| -
|
| - 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) {
|
| - const base::Value* element = NULL;
|
| - if (!list->Get(i, &element))
|
| - continue;
|
| -
|
| - scoped_ptr<NestedType> nested(new NestedType);
|
| - if (converter_.Convert(*element, nested.get())) {
|
| - field->push_back(nested.release());
|
| - } else {
|
| - DVLOG(1) << "failure at " << i << "-th element";
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - private:
|
| - JSONValueConverter<NestedType> converter_;
|
| - 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) {}
|
| -
|
| - 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) {
|
| - const 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>
|
| -class JSONValueConverter {
|
| - public:
|
| - JSONValueConverter() {
|
| - StructType::RegisterJSONConverter(this);
|
| - }
|
| -
|
| - void RegisterIntField(const std::string& field_name,
|
| - int StructType::* field) {
|
| - fields_.push_back(new internal::FieldConverter<StructType, int>(
|
| - field_name, field, new internal::BasicValueConverter<int>));
|
| - }
|
| -
|
| - void RegisterStringField(const std::string& field_name,
|
| - 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>(
|
| - field_name, field, new internal::BasicValueConverter<bool>));
|
| - }
|
| -
|
| - void RegisterDoubleField(const std::string& field_name,
|
| - double StructType::* field) {
|
| - fields_.push_back(new internal::FieldConverter<StructType, double>(
|
| - field_name, field, new internal::BasicValueConverter<double>));
|
| - }
|
| -
|
| - template <class NestedType>
|
| - void RegisterNestedField(
|
| - const std::string& field_name, NestedType StructType::* field) {
|
| - fields_.push_back(new internal::FieldConverter<StructType, NestedType>(
|
| - field_name,
|
| - field,
|
| - new internal::NestedValueConverter<NestedType>));
|
| - }
|
| -
|
| - template <typename FieldType>
|
| - void RegisterCustomField(
|
| - const std::string& field_name,
|
| - FieldType StructType::* field,
|
| - bool (*convert_func)(const StringPiece&, FieldType*)) {
|
| - fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
|
| - field_name,
|
| - field,
|
| - new internal::CustomFieldConverter<FieldType>(convert_func)));
|
| - }
|
| -
|
| - template <typename FieldType>
|
| - void RegisterCustomValueField(
|
| - const std::string& field_name,
|
| - FieldType StructType::* field,
|
| - bool (*convert_func)(const base::Value*, FieldType*)) {
|
| - fields_.push_back(new internal::FieldConverter<StructType, FieldType>(
|
| - field_name,
|
| - field,
|
| - new internal::ValueFieldConverter<FieldType>(convert_func)));
|
| - }
|
| -
|
| - void RegisterRepeatedInt(const std::string& field_name,
|
| - ScopedVector<int> StructType::* field) {
|
| - fields_.push_back(
|
| - new internal::FieldConverter<StructType, ScopedVector<int> >(
|
| - field_name, field, new internal::RepeatedValueConverter<int>));
|
| - }
|
| -
|
| - void RegisterRepeatedString(const std::string& field_name,
|
| - ScopedVector<std::string> StructType::* field) {
|
| - fields_.push_back(
|
| - new internal::FieldConverter<StructType, ScopedVector<std::string> >(
|
| - field_name,
|
| - field,
|
| - new internal::RepeatedValueConverter<std::string>));
|
| - }
|
| -
|
| - void RegisterRepeatedString(const std::string& field_name,
|
| - ScopedVector<string16> StructType::* field) {
|
| - fields_.push_back(
|
| - new internal::FieldConverter<StructType, ScopedVector<string16> >(
|
| - field_name,
|
| - field,
|
| - new internal::RepeatedValueConverter<string16>));
|
| - }
|
| -
|
| - void RegisterRepeatedDouble(const std::string& field_name,
|
| - ScopedVector<double> StructType::* field) {
|
| - fields_.push_back(
|
| - new internal::FieldConverter<StructType, ScopedVector<double> >(
|
| - field_name, field, new internal::RepeatedValueConverter<double>));
|
| - }
|
| -
|
| - void RegisterRepeatedBool(const std::string& field_name,
|
| - ScopedVector<bool> StructType::* field) {
|
| - fields_.push_back(
|
| - new internal::FieldConverter<StructType, ScopedVector<bool> >(
|
| - field_name, field, new internal::RepeatedValueConverter<bool>));
|
| - }
|
| -
|
| - 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(
|
| - new internal::FieldConverter<StructType, ScopedVector<NestedType> >(
|
| - field_name,
|
| - field,
|
| - new internal::RepeatedMessageConverter<NestedType>));
|
| - }
|
| -
|
| - bool Convert(const base::Value& value, StructType* output) const {
|
| - const DictionaryValue* dictionary_value = NULL;
|
| - if (!value.GetAsDictionary(&dictionary_value))
|
| - return false;
|
| -
|
| - for(size_t i = 0; i < fields_.size(); ++i) {
|
| - const internal::FieldConverterBase<StructType>* field_converter =
|
| - fields_[i];
|
| - const base::Value* field = NULL;
|
| - if (dictionary_value->Get(field_converter->field_path(), &field)) {
|
| - if (!field_converter->ConvertField(*field, output)) {
|
| - DVLOG(1) << "failure at field " << field_converter->field_path();
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - private:
|
| - ScopedVector<internal::FieldConverterBase<StructType> > fields_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(JSONValueConverter);
|
| -};
|
| -
|
| -} // namespace base
|
| -
|
| -#endif // BASE_JSON_JSON_VALUE_CONVERTER_H_
|
|
|