| // Copyright 2017 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/cmx.h" |
| |
| #include <lib/trace/event.h> |
| |
| #include <algorithm> |
| #include <regex> |
| #include <sstream> |
| #include <string> |
| |
| #include "rapidjson/document.h" |
| #include "src/lib/fxl/strings/substitute.h" |
| #include "src/lib/pkg_url/fuchsia_pkg_url.h" |
| |
| namespace component { |
| |
| constexpr char kSandbox[] = "sandbox"; |
| constexpr char kProgram[] = "program"; |
| |
| CmxMetadata::CmxMetadata() = default; |
| CmxMetadata::~CmxMetadata() = default; |
| |
| bool CmxMetadata::ParseDocument(const rapidjson::Document& document, |
| json::JSONParser* json_parser) { |
| if (json_parser->HasError()) { |
| return false; |
| } |
| if (!document.IsObject()) { |
| json_parser->ReportError("File is not a JSON object."); |
| return false; |
| } |
| ParseSandboxMetadata(document, json_parser); |
| runtime_meta_.ParseFromDocument(document, json_parser); |
| ParseProgramMetadata(document, json_parser); |
| facet_parser_.Parse(document, json_parser); |
| return !json_parser->HasError(); |
| } |
| |
| bool CmxMetadata::ParseFromFileAt(int dirfd, const std::string& file, |
| json::JSONParser* json_parser) { |
| TRACE_DURATION("cmx", "CmxMetadata::ParseFromFileAt", "file", file); |
| rapidjson::Document document = json_parser->ParseFromFileAt(dirfd, file); |
| return ParseDocument(document, json_parser); |
| } |
| |
| bool CmxMetadata::ParseFromString(const std::string& data, const std::string& filename, |
| json::JSONParser* json_parser) { |
| TRACE_DURATION("cmx", "CmxMetadata::ParseFromString"); |
| rapidjson::Document document = json_parser->ParseFromString(data, filename); |
| return ParseDocument(document, json_parser); |
| } |
| |
| const rapidjson::Value& CmxMetadata::GetFacet(const std::string& key) { |
| return facet_parser_.GetSection(key); |
| } |
| |
| void CmxMetadata::ParseSandboxMetadata(const rapidjson::Document& document, |
| json::JSONParser* json_parser) { |
| auto sandbox = document.FindMember(kSandbox); |
| if (sandbox == document.MemberEnd()) { |
| // Valid syntax, but no value. Pass empty object. |
| rapidjson::Value sandbox_obj = rapidjson::Value(rapidjson::kObjectType); |
| sandbox_meta_.Parse(sandbox_obj, json_parser); |
| } else if (!sandbox->value.IsObject()) { |
| json_parser->ReportError("'sandbox' is not an object."); |
| return; |
| } else { |
| sandbox_meta_.Parse(sandbox->value, json_parser); |
| } |
| } |
| |
| void CmxMetadata::ParseProgramMetadata(const rapidjson::Document& document, |
| json::JSONParser* json_parser) { |
| auto program = document.FindMember(kProgram); |
| if (program == document.MemberEnd()) { |
| // Valid syntax, but no value. |
| return; |
| } |
| if (!program->value.IsObject()) { |
| json_parser->ReportError("'program' is not an object."); |
| return; |
| } |
| program_meta_.Parse(program->value, json_parser); |
| } |
| |
| } // namespace component |