| // Copyright 2018 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 "src/lib/cmx/program.h" | |
| #include <algorithm> | |
| #include "rapidjson/document.h" | |
| #include "src/lib/json_parser/json_parser.h" | |
| namespace component { | |
| constexpr char kBinary[] = "binary"; | |
| constexpr char kArgs[] = "args"; | |
| constexpr char kEnvVars[] = "env_vars"; | |
| constexpr char kData[] = "data"; | |
| bool ProgramMetadata::Parse(const rapidjson::Value& program_value, json::JSONParser* json_parser) { | |
| binary_.clear(); | |
| args_.clear(); | |
| data_.clear(); | |
| binary_null_ = true; | |
| data_null_ = true; | |
| unknown_attributes_ = {}; | |
| if (!program_value.IsObject()) { | |
| json_parser->ReportError("Program is not an object."); | |
| return false; | |
| } | |
| const bool parsed_binary = ParseBinary(program_value, json_parser); | |
| const bool parsed_data = ParseData(program_value, json_parser); | |
| if (!parsed_binary && !parsed_data) { | |
| json_parser->ReportError("Both 'binary' and 'data' in program are missing."); | |
| return false; | |
| } | |
| const auto args = program_value.FindMember(kArgs); | |
| if (args != program_value.MemberEnd()) { | |
| json_parser->CopyStringArray("args", args->value, &args_); | |
| args_null_ = false; | |
| } | |
| for (const auto& member : program_value.GetObject()) { | |
| if (IsWellKnownAttributeName(member.name.GetString())) { | |
| continue; | |
| } | |
| if (!member.value.IsString()) { | |
| json_parser->ReportError("Extra attributes in 'program' must have string values."); | |
| return false; | |
| } | |
| unknown_attributes_.push_back({member.name.GetString(), member.value.GetString()}); | |
| } | |
| return !json_parser->HasError(); | |
| } | |
| bool ProgramMetadata::ParseBinary(const rapidjson::Value& program_value, | |
| json::JSONParser* json_parser) { | |
| const auto binary = program_value.FindMember(kBinary); | |
| if (binary == program_value.MemberEnd()) { | |
| return false; | |
| } | |
| if (!binary->value.IsString()) { | |
| json_parser->ReportError("'binary' in program is not a string."); | |
| return false; | |
| } | |
| binary_ = binary->value.GetString(); | |
| binary_null_ = false; | |
| const auto env_vars = program_value.FindMember(kEnvVars); | |
| if (env_vars != program_value.MemberEnd()) { | |
| json_parser->CopyStringArray("env_vars", env_vars->value, &env_vars_); | |
| env_vars_null_ = false; | |
| } | |
| return !json_parser->HasError(); | |
| } | |
| bool ProgramMetadata::ParseData(const rapidjson::Value& program_value, | |
| json::JSONParser* json_parser) { | |
| const auto data = program_value.FindMember(kData); | |
| if (data == program_value.MemberEnd()) { | |
| return false; | |
| } | |
| if (!data->value.IsString()) { | |
| json_parser->ReportError("'data' in program is not a string."); | |
| return false; | |
| } | |
| data_ = data->value.GetString(); | |
| data_null_ = false; | |
| return true; | |
| } | |
| bool ProgramMetadata::IsWellKnownAttributeName(std::string_view name) const { | |
| return name == kData || name == kBinary || name == kArgs || name == kEnvVars; | |
| } | |
| } // namespace component |