| // Copyright 2016 The Fuchsia 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 "garnet/bin/trace_manager/config.h" |
| |
| #include <fstream> |
| |
| #include <rapidjson/document.h> |
| #include <rapidjson/error/en.h> |
| #include <rapidjson/istreamwrapper.h> |
| |
| #include "src/lib/fxl/logging.h" |
| |
| namespace tracing { |
| namespace { |
| |
| constexpr char kCategories[] = "categories"; |
| constexpr char kProviders[] = "providers"; |
| |
| } // namespace |
| |
| Config::Config() = default; |
| |
| Config::~Config() = default; |
| |
| bool Config::ReadFrom(const std::string& config_file) { |
| std::ifstream in(config_file); |
| rapidjson::IStreamWrapper isw(in); |
| rapidjson::Document document; |
| |
| if (!document.ParseStream<rapidjson::kParseCommentsFlag>(isw).IsObject()) { |
| FX_LOGS(ERROR) << "Failed to parse JSON object from: " << config_file; |
| if (document.HasParseError()) { |
| FX_LOGS(ERROR) << "Parse error " << GetParseError_En(document.GetParseError()) << " (" |
| << document.GetErrorOffset() << ")"; |
| } |
| return false; |
| } |
| |
| auto categories_it = document.FindMember(kCategories); |
| if (categories_it != document.MemberEnd()) { |
| const auto& value = categories_it->value; |
| if (!value.IsObject()) { |
| FX_LOGS(ERROR) << "Expecting " << kCategories << " to be an object"; |
| return false; |
| } |
| for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) { |
| if (!(it->name.IsString() && it->value.IsString())) { |
| FX_LOGS(ERROR) << "Expecting both name and value to be strings"; |
| return false; |
| } |
| known_categories_[it->name.GetString()] = it->value.GetString(); |
| } |
| } |
| |
| auto provider_it = document.FindMember(kProviders); |
| if (provider_it != document.MemberEnd()) { |
| const auto& value = provider_it->value; |
| if (!value.IsObject()) |
| return false; |
| for (const auto& reg : value.GetObject()) { |
| if (!reg.name.IsString()) |
| return false; |
| |
| auto launch_info = fuchsia::sys::LaunchInfo::New(); |
| if (reg.value.IsString()) { |
| launch_info->url = reg.value.GetString(); |
| } else if (reg.value.IsArray()) { |
| const auto& array = reg.value.GetArray(); |
| if (array.Empty() || !array[0].IsString()) |
| return false; |
| launch_info->url = array[0].GetString(); |
| launch_info->arguments.emplace(); |
| for (size_t i = 1; i < array.Size(); ++i) { |
| if (!array[i].IsString()) |
| return false; |
| launch_info->arguments->push_back(array[i].GetString()); |
| } |
| } else { |
| return false; |
| } |
| providers_.emplace(reg.name.GetString(), std::move(launch_info)); |
| } |
| } |
| |
| return true; |
| } |
| |
| } // namespace tracing |