1275f7c39SAndrew Jeffery #pragma once 2275f7c39SAndrew Jeffery 3275f7c39SAndrew Jeffery #include "MCTPEndpoint.hpp" 4275f7c39SAndrew Jeffery 518b6186eSEd Tanous #include <algorithm> 618b6186eSEd Tanous #include <format> 718b6186eSEd Tanous #include <map> 818b6186eSEd Tanous #include <memory> 918b6186eSEd Tanous #include <optional> 1018b6186eSEd Tanous #include <string> 1118b6186eSEd Tanous #include <system_error> 1218b6186eSEd Tanous 13275f7c39SAndrew Jeffery class MCTPDeviceRepository 14275f7c39SAndrew Jeffery { 15275f7c39SAndrew Jeffery private: 16275f7c39SAndrew Jeffery // FIXME: Ugh, hack. Figure out a better data structure? 17275f7c39SAndrew Jeffery std::map<std::string, std::shared_ptr<MCTPDevice>> devices; 18275f7c39SAndrew Jeffery lookup(const std::shared_ptr<MCTPDevice> & device)19275f7c39SAndrew Jeffery auto lookup(const std::shared_ptr<MCTPDevice>& device) 20275f7c39SAndrew Jeffery { 21275f7c39SAndrew Jeffery auto pred = [&device](const auto& it) { return it.second == device; }; 22275f7c39SAndrew Jeffery return std::ranges::find_if(devices, pred); 23275f7c39SAndrew Jeffery } 24275f7c39SAndrew Jeffery 25275f7c39SAndrew Jeffery public: 26275f7c39SAndrew Jeffery MCTPDeviceRepository() = default; 27275f7c39SAndrew Jeffery MCTPDeviceRepository(const MCTPDeviceRepository&) = delete; 28275f7c39SAndrew Jeffery MCTPDeviceRepository(MCTPDeviceRepository&&) = delete; 29275f7c39SAndrew Jeffery ~MCTPDeviceRepository() = default; 30275f7c39SAndrew Jeffery 31275f7c39SAndrew Jeffery MCTPDeviceRepository& operator=(const MCTPDeviceRepository&) = delete; 32275f7c39SAndrew Jeffery MCTPDeviceRepository& operator=(MCTPDeviceRepository&&) = delete; 33275f7c39SAndrew Jeffery add(const std::string & inventory,const std::shared_ptr<MCTPDevice> & device)34275f7c39SAndrew Jeffery void add(const std::string& inventory, 35275f7c39SAndrew Jeffery const std::shared_ptr<MCTPDevice>& device) 36275f7c39SAndrew Jeffery { 37275f7c39SAndrew Jeffery auto [entry, fresh] = devices.emplace(inventory, device); 38275f7c39SAndrew Jeffery if (!fresh && entry->second.get() != device.get()) 39275f7c39SAndrew Jeffery { 40275f7c39SAndrew Jeffery throw std::system_error( 41275f7c39SAndrew Jeffery std::make_error_code(std::errc::device_or_resource_busy), 42275f7c39SAndrew Jeffery std::format("Tried to add entry for existing device: {}", 43275f7c39SAndrew Jeffery device->describe())); 44275f7c39SAndrew Jeffery } 45275f7c39SAndrew Jeffery } 46275f7c39SAndrew Jeffery remove(const std::shared_ptr<MCTPDevice> & device)47275f7c39SAndrew Jeffery void remove(const std::shared_ptr<MCTPDevice>& device) 48275f7c39SAndrew Jeffery { 49275f7c39SAndrew Jeffery auto entry = lookup(device); 50275f7c39SAndrew Jeffery if (entry == devices.end()) 51275f7c39SAndrew Jeffery { 52275f7c39SAndrew Jeffery throw std::system_error( 53275f7c39SAndrew Jeffery std::make_error_code(std::errc::no_such_device), 54275f7c39SAndrew Jeffery std::format("Trying to remove unknown device: {}", 55275f7c39SAndrew Jeffery entry->second->describe())); 56275f7c39SAndrew Jeffery } 57275f7c39SAndrew Jeffery devices.erase(entry); 58275f7c39SAndrew Jeffery } 59275f7c39SAndrew Jeffery contains(const std::shared_ptr<MCTPDevice> & device)60275f7c39SAndrew Jeffery bool contains(const std::shared_ptr<MCTPDevice>& device) 61275f7c39SAndrew Jeffery { 62275f7c39SAndrew Jeffery return lookup(device) != devices.end(); 63275f7c39SAndrew Jeffery } 64275f7c39SAndrew Jeffery inventoryFor(const std::shared_ptr<MCTPDevice> & device)65*556e04b8SPatrick Williams std::optional<std::string> inventoryFor( 66*556e04b8SPatrick Williams const std::shared_ptr<MCTPDevice>& device) 67275f7c39SAndrew Jeffery { 68275f7c39SAndrew Jeffery auto entry = lookup(device); 69275f7c39SAndrew Jeffery if (entry == devices.end()) 70275f7c39SAndrew Jeffery { 71275f7c39SAndrew Jeffery return {}; 72275f7c39SAndrew Jeffery } 73275f7c39SAndrew Jeffery return entry->first; 74275f7c39SAndrew Jeffery } 75275f7c39SAndrew Jeffery deviceFor(const std::string & inventory)76275f7c39SAndrew Jeffery std::shared_ptr<MCTPDevice> deviceFor(const std::string& inventory) 77275f7c39SAndrew Jeffery { 78275f7c39SAndrew Jeffery auto entry = devices.find(inventory); 79275f7c39SAndrew Jeffery if (entry == devices.end()) 80275f7c39SAndrew Jeffery { 81275f7c39SAndrew Jeffery return {}; 82275f7c39SAndrew Jeffery } 83275f7c39SAndrew Jeffery return entry->second; 84275f7c39SAndrew Jeffery } 85275f7c39SAndrew Jeffery }; 86