| // Copyright 2020 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. |
| |
| #ifndef LIB_DRIVER2_START_ARGS_H_ |
| #define LIB_DRIVER2_START_ARGS_H_ |
| |
| #include <fidl/fuchsia.component.runner/cpp/wire.h> |
| #include <fidl/fuchsia.data/cpp/wire.h> |
| #include <fidl/fuchsia.driver.framework/cpp/wire.h> |
| #include <lib/zx/status.h> |
| |
| #include <vector> |
| |
| namespace driver { |
| |
| template <typename T> |
| zx::status<T> SymbolValue(const fuchsia_driver_framework::wire::DriverStartArgs& args, |
| std::string_view name) { |
| if (!args.has_symbols()) { |
| return zx::error(ZX_ERR_NOT_FOUND); |
| } |
| const fidl::VectorView<fuchsia_driver_framework::wire::NodeSymbol>& symbols = args.symbols(); |
| static_assert(sizeof(T) == sizeof(zx_vaddr_t), "T must match zx_vaddr_t in size"); |
| for (auto& symbol : symbols) { |
| if (std::equal(name.begin(), name.end(), symbol.name().begin())) { |
| T value; |
| memcpy(&value, &symbol.address(), sizeof(zx_vaddr_t)); |
| return zx::ok(value); |
| } |
| } |
| return zx::error(ZX_ERR_NOT_FOUND); |
| } |
| |
| template <typename T> |
| T GetSymbol(const fuchsia_driver_framework::wire::DriverStartArgs& args, std::string_view name, |
| T default_value = nullptr) { |
| auto value = driver::SymbolValue<T>(args, name); |
| return value.is_ok() ? *value : default_value; |
| } |
| |
| inline zx::status<std::string> ProgramValue(const fuchsia_data::wire::Dictionary& program, |
| std::string_view key) { |
| if (program.has_entries()) { |
| for (auto& entry : program.entries()) { |
| if (!std::equal(key.begin(), key.end(), entry.key.begin())) { |
| continue; |
| } |
| if (!entry.value.is_str()) { |
| return zx::error(ZX_ERR_WRONG_TYPE); |
| } |
| auto& value = entry.value.str(); |
| return zx::ok(std::string{value.data(), value.size()}); |
| } |
| } |
| return zx::error(ZX_ERR_NOT_FOUND); |
| } |
| |
| // Returns the list of values for |key| as a vector of strings. |
| inline zx::status<std::vector<std::string>> ProgramValueAsVector( |
| const fuchsia_data::wire::Dictionary& program, std::string_view key) { |
| if (program.has_entries()) { |
| for (auto& entry : program.entries()) { |
| if (!std::equal(key.begin(), key.end(), entry.key.begin())) { |
| continue; |
| } |
| if (!entry.value.is_str_vec()) { |
| return zx::error(ZX_ERR_WRONG_TYPE); |
| } |
| auto& values = entry.value.str_vec(); |
| std::vector<std::string> result; |
| result.reserve(values.count()); |
| for (auto& value : values) { |
| result.emplace_back(std::string{value.data(), value.size()}); |
| } |
| return zx::ok(result); |
| } |
| } |
| return zx::error(ZX_ERR_NOT_FOUND); |
| } |
| |
| inline zx::status<fidl::UnownedClientEnd<fuchsia_io::Directory>> NsValue( |
| const fidl::VectorView<fuchsia_component_runner::wire::ComponentNamespaceEntry>& entries, |
| std::string_view path) { |
| for (auto& entry : entries) { |
| if (std::equal(path.begin(), path.end(), entry.path().begin())) { |
| return zx::ok<fidl::UnownedClientEnd<fuchsia_io::Directory>>(entry.directory()); |
| } |
| } |
| return zx::error(ZX_ERR_NOT_FOUND); |
| } |
| |
| } // namespace driver |
| |
| #endif // LIB_DRIVER2_START_ARGS_H_ |