Chromium Code Reviews| Index: components/policy/core/common/schema.cc |
| diff --git a/components/policy/core/common/schema.cc b/components/policy/core/common/schema.cc |
| index 5f0cc18db875a1e34c2695699fdf5867f7b85461..c230f207a3eb7c999afaf791f144732bcd9fc016 100644 |
| --- a/components/policy/core/common/schema.cc |
| +++ b/components/policy/core/common/schema.cc |
| @@ -5,6 +5,7 @@ |
| #include "components/policy/core/common/schema.h" |
| #include <algorithm> |
| +#include <climits> |
| #include <map> |
| #include <utility> |
| #include <vector> |
| @@ -22,6 +23,7 @@ namespace policy { |
| using internal::PropertiesNode; |
| using internal::PropertyNode; |
| +using internal::RestrictionNode; |
| using internal::SchemaData; |
| using internal::SchemaNode; |
| @@ -41,11 +43,15 @@ typedef std::vector<std::pair<std::string, int*> > ReferenceList; |
| // for "$ref" attributes). |
| struct StorageSizes { |
| StorageSizes() |
| - : strings(0), schema_nodes(0), property_nodes(0), properties_nodes(0) {} |
| + : strings(0), schema_nodes(0), property_nodes(0), properties_nodes(0), |
| + restriction_nodes(0), int_enums(0), string_enums(0) { } |
| size_t strings; |
| size_t schema_nodes; |
| size_t property_nodes; |
| size_t properties_nodes; |
| + size_t restriction_nodes; |
| + size_t int_enums; |
| + size_t string_enums; |
| }; |
| // An invalid index, indicating that a node is not present; similar to a NULL |
| @@ -108,6 +114,18 @@ class Schema::InternalStorage |
| return schema_data_.property_nodes + index; |
| } |
| + const RestrictionNode* restriction(int index) const { |
| + return schema_data_.restriction_nodes + index; |
| + } |
| + |
| + const int* int_enums(int index) const { |
| + return schema_data_.int_enums + index; |
| + } |
| + |
| + const char** string_enums(int index) const { |
| + return schema_data_.string_enums + index; |
| + } |
| + |
| private: |
| friend class base::RefCountedThreadSafe<InternalStorage>; |
| @@ -152,6 +170,15 @@ class Schema::InternalStorage |
| ReferenceList* reference_list, |
| std::string* error); |
| + bool ParseEnum(const base::DictionaryValue& schema, |
| + base::Value::Type type, |
| + SchemaNode* schema_node, |
| + std::string* error); |
| + |
| + bool ParseRangedInt(const base::DictionaryValue& schema, |
| + SchemaNode* schema_node, |
| + std::string* error); |
| + |
| // Assigns the IDs in |id_map| to the pending references in the |
| // |reference_list|. If an ID is missing then |error| is set and false is |
| // returned; otherwise returns true. |
| @@ -164,6 +191,9 @@ class Schema::InternalStorage |
| std::vector<SchemaNode> schema_nodes_; |
| std::vector<PropertyNode> property_nodes_; |
| std::vector<PropertiesNode> properties_nodes_; |
| + std::vector<RestrictionNode> restriction_nodes_; |
| + std::vector<int> int_enums_; |
| + std::vector<const char*> string_enums_; |
| DISALLOW_COPY_AND_ASSIGN(InternalStorage); |
| }; |
| @@ -179,6 +209,9 @@ scoped_refptr<const Schema::InternalStorage> Schema::InternalStorage::Wrap( |
| storage->schema_data_.schema_nodes = data->schema_nodes; |
| storage->schema_data_.property_nodes = data->property_nodes; |
| storage->schema_data_.properties_nodes = data->properties_nodes; |
| + storage->schema_data_.restriction_nodes = data->restriction_nodes; |
| + storage->schema_data_.int_enums = data->int_enums; |
| + storage->schema_data_.string_enums = data->string_enums; |
| return storage; |
| } |
| @@ -198,6 +231,9 @@ Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, |
| storage->schema_nodes_.reserve(sizes.schema_nodes); |
| storage->property_nodes_.reserve(sizes.property_nodes); |
| storage->properties_nodes_.reserve(sizes.properties_nodes); |
| + storage->restriction_nodes_.reserve(sizes.restriction_nodes); |
| + storage->int_enums_.reserve(sizes.int_enums); |
| + storage->string_enums_.reserve(sizes.string_enums); |
| int root_index = kInvalid; |
| IdMap id_map; |
| @@ -217,7 +253,10 @@ Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, |
| sizes.strings != storage->strings_.size() || |
| sizes.schema_nodes != storage->schema_nodes_.size() || |
| sizes.property_nodes != storage->property_nodes_.size() || |
| - sizes.properties_nodes != storage->properties_nodes_.size()) { |
| + sizes.properties_nodes != storage->properties_nodes_.size() || |
| + sizes.restriction_nodes != storage->restriction_nodes_.size() || |
| + sizes.int_enums != storage->int_enums_.size() || |
| + sizes.string_enums != storage->string_enums_.size()) { |
| *error = "Failed to parse the schema due to a Chrome bug. Please file a " |
| "new issue at http://crbug.com"; |
| return NULL; |
| @@ -230,6 +269,9 @@ Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, |
| data->schema_nodes = vector_as_array(&storage->schema_nodes_); |
| data->property_nodes = vector_as_array(&storage->property_nodes_); |
| data->properties_nodes = vector_as_array(&storage->properties_nodes_); |
| + data->restriction_nodes = vector_as_array(&storage->restriction_nodes_); |
| + data->int_enums = vector_as_array(&storage->int_enums_); |
| + data->string_enums = vector_as_array(&storage->string_enums_); |
| return storage; |
| } |
| @@ -275,6 +317,20 @@ void Schema::InternalStorage::DetermineStorageSizes( |
| sizes->property_nodes++; |
| } |
| } |
| + } else if (schema.HasKey(schema::kEnum)) { |
| + const base::ListValue* possible_values; |
|
Joao da Silva
2014/01/16 10:56:34
= NULL
binjin
2014/01/17 14:29:01
Done.
|
| + if (schema.GetList(schema::kEnum, &possible_values)) { |
| + if (type == base::Value::TYPE_INTEGER) { |
| + sizes->int_enums += possible_values->GetSize(); |
| + } else if (type == base::Value::TYPE_STRING) { |
| + sizes->string_enums += possible_values->GetSize(); |
| + sizes->strings += possible_values->GetSize(); |
| + } |
| + sizes->restriction_nodes++; |
| + } |
| + } else if (type == base::Value::TYPE_INTEGER) { |
| + if (schema.HasKey(schema::kMinimum) || schema.HasKey(schema::kMaximum)) |
| + sizes->restriction_nodes++; |
| } |
| } |
| @@ -318,6 +374,14 @@ bool Schema::InternalStorage::Parse(const base::DictionaryValue& schema, |
| } else if (type == base::Value::TYPE_LIST) { |
| if (!ParseList(schema, schema_node, id_map, reference_list, error)) |
| return false; |
| + } else if (schema.HasKey(schema::kEnum)) { |
| + if (!ParseEnum(schema, type, schema_node, error)) |
| + return false; |
| + } else if (type == base::Value::TYPE_INTEGER && |
| + (schema.HasKey(schema::kMinimum) || |
| + schema.HasKey(schema::kMaximum))) { |
| + if (!ParseRangedInt(schema, schema_node, error)) |
| + return false; |
|
Joao da Silva
2014/01/16 10:56:34
This is ignoring the 'minimum' and 'maximum' field
binjin
2014/01/17 14:29:01
Done.
|
| } |
| std::string id_string; |
| @@ -394,6 +458,77 @@ bool Schema::InternalStorage::ParseList(const base::DictionaryValue& schema, |
| return Parse(*dict, &schema_node->extra, id_map, reference_list, error); |
| } |
| +bool Schema::InternalStorage::ParseEnum(const base::DictionaryValue& schema, |
| + base::Value::Type type, |
| + SchemaNode* schema_node, |
| + std::string* error) { |
| + const base::ListValue *possible_values; |
|
Joao da Silva
2014/01/16 10:56:34
= NULL
binjin
2014/01/17 14:29:01
Done.
|
| + if (!schema.GetList(schema::kEnum, &possible_values)) { |
| + *error = "Enum attribute must be a list value"; |
| + return false; |
| + } |
| + if (possible_values->GetSize() == 0) { |
|
Joao da Silva
2014/01/16 10:56:34
possible_values->empty()
binjin
2014/01/17 14:29:01
Done.
|
| + *error = "Enum attribute must be non-empty"; |
| + return false; |
| + } |
| + int offset_begin, offset_end; |
|
Joao da Silva
2014/01/16 10:56:34
One declaration per line
binjin
2014/01/17 14:29:01
Done.
|
| + if (type == base::Value::TYPE_INTEGER) { |
| + offset_begin = static_cast<int>(int_enums_.size()); |
| + int value; |
| + for (base::ListValue::const_iterator it = possible_values->begin(); |
| + it != possible_values->end(); ++it) { |
|
Joao da Silva
2014/01/16 10:56:34
One more space of indentation
binjin
2014/01/17 14:29:01
Done.
|
| + if (!(*it)->GetAsInteger(&value)) { |
| + *error = "Invalid enumeration member type"; |
| + return false; |
| + } |
| + int_enums_.push_back(value); |
| + } |
| + offset_begin = static_cast<int>(int_enums_.size()); |
|
Joao da Silva
2014/01/16 10:56:34
offset_end
binjin
2014/01/17 14:29:01
Done.
|
| + } else if (type == base::Value::TYPE_STRING) { |
| + offset_begin = static_cast<int>(string_enums_.size()); |
| + std::string value; |
| + for (base::ListValue::const_iterator it = possible_values->begin(); |
| + it != possible_values->end(); ++it) { |
|
Joao da Silva
2014/01/16 10:56:34
One more space of indentation
binjin
2014/01/17 14:29:01
Done.
|
| + if (!(*it)->GetAsString(&value)) { |
| + *error = "Invalid enumeration member type"; |
| + return false; |
| + } |
| + strings_.push_back(value); |
| + string_enums_.push_back(strings_.back().c_str()); |
| + } |
| + offset_end = static_cast<int>(string_enums_.size()); |
| + } else { |
| + *error = "Enumeration is only supported for integer and string."; |
| + return false; |
|
Joao da Silva
2014/01/16 10:56:34
2 spaces less in indentation
binjin
2014/01/17 14:29:01
Done.
|
| + } |
| + schema_node->extra = static_cast<int>(restriction_nodes_.size()); |
| + restriction_nodes_.push_back(RestrictionNode()); |
| + restriction_nodes_.back().enumeration_restriction.offset_begin = offset_begin; |
| + restriction_nodes_.back().enumeration_restriction.offset_end = offset_end; |
| + return true; |
| +} |
| + |
| +bool Schema::InternalStorage::ParseRangedInt( |
| + const base::DictionaryValue& schema, |
| + SchemaNode* schema_node, |
| + std::string* error) { |
| + int min_value = INT_MIN, max_value = INT_MAX; |
|
Joao da Silva
2014/01/16 10:56:34
One declaration per line
binjin
2014/01/17 14:29:01
Done.
|
| + int value; |
| + if (schema.GetInteger(schema::kMinimum, &value)) |
| + min_value = value; |
| + if (schema.GetInteger(schema::kMaximum, &value)) |
| + max_value = value; |
| + if (min_value > max_value) { |
| + *error = "Invalid Range restriction for int type."; |
|
Joao da Silva
2014/01/16 10:56:34
range (lower R)
binjin
2014/01/17 14:29:01
Done.
|
| + return false; |
| + } |
| + schema_node->extra = static_cast<int>(restriction_nodes_.size()); |
| + restriction_nodes_.push_back(RestrictionNode()); |
| + restriction_nodes_.back().ranged_restriction.max_value = max_value; |
| + restriction_nodes_.back().ranged_restriction.min_value = min_value; |
| + return true; |
| +} |
| + |
| // static |
| bool Schema::InternalStorage::ResolveReferences( |
| const IdMap& id_map, |