1 #pragma once 2 3 #include "MCTPEndpoint.hpp" 4 5 #include <algorithm> 6 #include <format> 7 #include <map> 8 #include <memory> 9 #include <optional> 10 #include <string> 11 #include <system_error> 12 13 class MCTPDeviceRepository 14 { 15 private: 16 // FIXME: Ugh, hack. Figure out a better data structure? 17 std::map<std::string, std::shared_ptr<MCTPDevice>> devices; 18 lookup(const std::shared_ptr<MCTPDevice> & device)19 auto lookup(const std::shared_ptr<MCTPDevice>& device) 20 { 21 auto pred = [&device](const auto& it) { return it.second == device; }; 22 return std::ranges::find_if(devices, pred); 23 } 24 25 public: 26 MCTPDeviceRepository() = default; 27 MCTPDeviceRepository(const MCTPDeviceRepository&) = delete; 28 MCTPDeviceRepository(MCTPDeviceRepository&&) = delete; 29 ~MCTPDeviceRepository() = default; 30 31 MCTPDeviceRepository& operator=(const MCTPDeviceRepository&) = delete; 32 MCTPDeviceRepository& operator=(MCTPDeviceRepository&&) = delete; 33 add(const std::string & inventory,const std::shared_ptr<MCTPDevice> & device)34 void add(const std::string& inventory, 35 const std::shared_ptr<MCTPDevice>& device) 36 { 37 auto [entry, fresh] = devices.emplace(inventory, device); 38 if (!fresh && entry->second.get() != device.get()) 39 { 40 throw std::system_error( 41 std::make_error_code(std::errc::device_or_resource_busy), 42 std::format("Tried to add entry for existing device: {}", 43 device->describe())); 44 } 45 } 46 remove(const std::shared_ptr<MCTPDevice> & device)47 void remove(const std::shared_ptr<MCTPDevice>& device) 48 { 49 auto entry = lookup(device); 50 if (entry == devices.end()) 51 { 52 throw std::system_error( 53 std::make_error_code(std::errc::no_such_device), 54 std::format("Trying to remove unknown device: {}", 55 entry->second->describe())); 56 } 57 devices.erase(entry); 58 } 59 contains(const std::shared_ptr<MCTPDevice> & device)60 bool contains(const std::shared_ptr<MCTPDevice>& device) 61 { 62 return lookup(device) != devices.end(); 63 } 64 inventoryFor(const std::shared_ptr<MCTPDevice> & device)65 std::optional<std::string> inventoryFor( 66 const std::shared_ptr<MCTPDevice>& device) 67 { 68 auto entry = lookup(device); 69 if (entry == devices.end()) 70 { 71 return {}; 72 } 73 return entry->first; 74 } 75 deviceFor(const std::string & inventory)76 std::shared_ptr<MCTPDevice> deviceFor(const std::string& inventory) 77 { 78 auto entry = devices.find(inventory); 79 if (entry == devices.end()) 80 { 81 return {}; 82 } 83 return entry->second; 84 } 85 }; 86