Chromium Code Reviews| Index: services/catalog/public/cpp/manifest_parsing_util.cc |
| diff --git a/services/catalog/public/cpp/manifest_parsing_util.cc b/services/catalog/public/cpp/manifest_parsing_util.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c56cd5c33d6e6c4009b82edde13ade9b7af773c3 |
| --- /dev/null |
| +++ b/services/catalog/public/cpp/manifest_parsing_util.cc |
| @@ -0,0 +1,106 @@ |
| +// Copyright 2017 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. |
| + |
| +#include "services/catalog/public/cpp/manifest_parsing_util.h" |
| + |
| +#include "base/values.h" |
| +#include "services/catalog/store.h" |
| + |
| +namespace catalog { |
| + |
| +namespace { |
| + |
| +bool IsValidPlatformName(const std::string& name) { |
| + return name == Store::kRequiredFilesKey_PlatformValue_Windows || |
| + name == Store::kRequiredFilesKey_PlatformValue_Linux || |
| + name == Store::kRequiredFilesKey_PlatformValue_MacOSX || |
| + name == Store::kRequiredFilesKey_PlatformValue_Android; |
| +} |
| + |
| +bool IsCurrentPlatform(const std::string& name) { |
| +#if defined(OS_WIN) |
| + return name == Store::kRequiredFilesKey_PlatformValue_Windows; |
| +#elif defined(OS_LINUX) |
| + return name == Store::kRequiredFilesKey_PlatformValue_Linux; |
| +#elif defined(OS_MACOSX) |
| + return name == Store::kRequiredFilesKey_PlatformValue_MacOSX; |
| +#elif defined(OS_ANDROID) |
| + return name == Store::kRequiredFilesKey_PlatformValue_Android; |
| +#else |
| +#error This architecture is not supported. |
| +#endif |
| +} |
| + |
| +} // namespace |
| + |
| +bool PopulateRequiredFiles(const base::Value& manifest_value, |
|
dcheng
2017/02/15 08:05:27
Would it make sense to return a base::Optional<Req
Jay Civelli
2017/02/15 19:53:48
Good idea. (I didn't know about Optional)
|
| + RequiredFileMap* required_files) { |
| + const base::DictionaryValue* manifest_dictionary = nullptr; |
| + if (!manifest_value.GetAsDictionary(&manifest_dictionary)) { |
| + LOG(ERROR) << "Entry::Deserialize: manifest node is not a dictionary."; |
| + return false; |
| + } |
| + |
| + if (!manifest_dictionary->HasKey(Store::kRequiredFilesKey)) |
| + return true; |
| + |
| + const base::DictionaryValue* required_files_value = nullptr; |
| + if (!manifest_dictionary->GetDictionary(Store::kRequiredFilesKey, |
| + &required_files_value)) { |
| + LOG(ERROR) << "Entry::Deserialize: RequiredFiles not a dictionary."; |
| + return false; |
| + } |
| + |
| + base::DictionaryValue::Iterator it(*required_files_value); |
| + for (; !it.IsAtEnd(); it.Advance()) { |
| + const std::string& entry_name = it.key(); |
| + const base::ListValue* all_platform_values = nullptr; |
| + if (!it.value().GetAsList(&all_platform_values)) { |
| + LOG(ERROR) << "Entry::Deserialize: value of RequiredFiles for key: " |
| + << entry_name << " not a list."; |
| + return false; |
| + } |
| + |
| + for (size_t i = 0; i < all_platform_values->GetSize(); i++) { |
|
dcheng
2017/02/15 08:05:28
It's possible to use range-based for loops with ba
Jay Civelli
2017/02/15 19:53:48
But then I'd lose the index value which I use in t
|
| + const base::DictionaryValue* file_descriptor_value = nullptr; |
| + if (!all_platform_values->GetDictionary(i, &file_descriptor_value)) { |
| + LOG(ERROR) << "Entry::Deserialize: value of entry at index " << i |
| + << " of RequiredFiles for key: " << entry_name |
| + << " not a dictionary."; |
| + return false; |
| + } |
| + std::string platform; |
| + if (file_descriptor_value->GetString(Store::kRequiredFilesKey_PlatformKey, |
| + &platform)) { |
| + if (!IsValidPlatformName(platform)) { |
| + LOG(ERROR) << "Entry::Deserialize: value of platform for " |
| + << "required file entry entry is invalid " << platform; |
| + return false; |
| + } |
| + } |
| + if (!IsCurrentPlatform(platform)) { |
| + continue; |
| + } |
| + std::string path; |
| + if (!file_descriptor_value->GetString(Store::kRequiredFilesKey_PathKey, |
| + &path)) { |
| + LOG(ERROR) << "Entry::Deserialize: value of RequiredFiles entry for " |
| + << "key: " << entry_name |
| + << " missing: " << Store::kRequiredFilesKey_PathKey |
| + << " value."; |
| + return false; |
| + } |
| + if (required_files->count(entry_name) > 0) { |
| + LOG(ERROR) << "Entry::Deserialize: value of RequiredFiles entry for " |
| + << "key: " << entry_name << " has more than one value for " |
| + << "platform: " << platform; |
| + return false; |
| + } |
| + (*required_files)[entry_name] = path; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +} // namespace content |