blob: 64456985bd8e75f12584b70c99b8d3e6eb5bc256 [file] [log] [blame]
// 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/sysmgr/config.h"
#include <utility>
#include "lib/fxl/files/file.h"
#include "third_party/rapidjson/rapidjson/document.h"
namespace sysmgr {
namespace {
constexpr char kAppLoaders[] = "loaders";
constexpr char kApps[] = "apps";
constexpr char kServices[] = "services";
component::ApplicationLaunchInfoPtr GetLaunchInfo(
const rapidjson::Document::ValueType& value) {
auto launch_info = component::ApplicationLaunchInfo::New();
if (value.IsString()) {
launch_info->url = value.GetString();
} else if (value.IsArray()) {
const auto& array = value.GetArray();
if (array.Empty() || !array[0].IsString())
return nullptr;
launch_info->url = array[0].GetString();
for (size_t i = 1; i < array.Size(); ++i) {
if (!array[i].IsString())
return nullptr;
launch_info->arguments.push_back(array[i].GetString());
}
} else {
return nullptr;
}
return launch_info;
}
bool ParseServiceMap(const rapidjson::Document& document,
const std::string& key,
Config::ServiceMap* services) {
auto it = document.FindMember(key);
if (it != document.MemberEnd()) {
const auto& value = it->value;
if (!value.IsObject())
return false;
for (const auto& reg : value.GetObject()) {
if (!reg.name.IsString())
return false;
std::string service_key = reg.name.GetString();
auto launch_info = GetLaunchInfo(reg.value);
if (!launch_info)
return false;
services->emplace(service_key, std::move(launch_info));
}
}
return true;
}
} // namespace
Config::Config() = default;
Config::~Config() = default;
bool Config::ReadFrom(const std::string& config_file) {
std::string data;
return files::ReadFileToString(config_file, &data) &&
Parse(data, config_file);
}
bool Config::Parse(const std::string& string, const std::string& config_file) {
rapidjson::Document document;
document.Parse(string);
FXL_CHECK(!document.HasParseError())
<< "Could not parse file at " << config_file;
if (!(document.IsObject() &&
ParseServiceMap(document, kServices, &services_) &&
ParseServiceMap(document, kAppLoaders, &app_loaders_)))
return false;
auto apps_it = document.FindMember(kApps);
if (apps_it != document.MemberEnd()) {
const auto& value = apps_it->value;
if (!value.IsArray())
return false;
for (const auto& app : value.GetArray()) {
auto launch_info = GetLaunchInfo(app);
if (!launch_info)
return false;
apps_.push_back(std::move(launch_info));
}
}
return true;
}
} // namespace sysmgr