/* * Copyright (c) 2023, Liav A. * Copyright (c) 2023, kleines Filmröllchen * * SPDX-License-Identifier: BSD-2-Clause */ #include "InstalledPort.h" #include #include #include #include Optional InstalledPort::type_from_string(StringView type) { if (type == "auto"sv) return Type::Auto; if (type == "manual"sv) return Type::Manual; return {}; } ErrorOr> InstalledPort::read_ports_database() { auto file = TRY(Core::File::open(ports_database, Core::File::OpenMode::Read)); auto buffered_file = TRY(Core::InputBufferedFile::create(move(file))); auto buffer = TRY(ByteBuffer::create_uninitialized(PAGE_SIZE)); HashMap ports; while (TRY(buffered_file->can_read_line())) { auto line = TRY(buffered_file->read_line(buffer)); if (line.is_empty()) continue; auto parts = line.split_view(' '); if (parts.size() < 2) { dbgln("Invalid database entry {} (only {} parts)", line, parts.size()); // FIXME: Skip over invalid entries instead? return Error::from_string_view("Database entry too short"sv); } auto install_type_string = parts[0]; auto port_name = TRY(String::from_utf8(parts[1])); if (auto maybe_type = type_from_string(install_type_string); maybe_type.has_value()) { auto const type = maybe_type.release_value(); if (parts.size() < 3) return Error::from_string_view("Port is missing a version specification"sv); ports.ensure(port_name, [=] { return InstalledPort { port_name, MUST(String::from_utf8(parts[2])), type }; }); } else if (install_type_string == "dependency"sv) { Vector dependencies; TRY(dependencies.try_ensure_capacity(parts.size() - 2)); for (auto const& dependency : parts.span().slice(2)) { dependencies.unchecked_append(TRY(String::from_utf8(dependency))); } // Assume the port as automatically installed if the "dependency" line occurs before the "manual"/"auto" line. // This is fine since these entries override the port type in any case. auto& port = ports.ensure(port_name, [&] { return InstalledPort { port_name, {}, Type::Auto }; }); port.m_dependencies = move(dependencies); } else { return Error::from_string_literal("Unknown installed port type"); } } return ports; } ErrorOr InstalledPort::for_each_by_type(HashMap& ports_database, InstalledPort::Type type, Function(InstalledPort const&)> callback) { for (auto& port : ports_database) { if (type == port.value.type()) TRY(callback(port.value)); } return {}; }