xref: /openbmc/entity-manager/src/utils.hpp (revision dbf95b2c54c5a40d1ea44d650eb6aab2a4c34ba5)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2017 Intel Corporation
3 
4 #pragma once
5 
6 #include <nlohmann/json.hpp>
7 #include <sdbusplus/asio/connection.hpp>
8 #include <sdbusplus/exception.hpp>
9 
10 #include <charconv>
11 #include <filesystem>
12 #include <flat_map>
13 
14 using DBusValueVariant =
15     std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
16                  int16_t, uint16_t, uint8_t, bool, std::vector<uint8_t>>;
17 using DBusInterface = std::flat_map<std::string, DBusValueVariant, std::less<>>;
18 using DBusObject = std::flat_map<std::string, DBusInterface, std::less<>>;
19 using MapperGetSubTreeResponse =
20     std::flat_map<std::string, DBusObject, std::less<>>;
21 using FirstIndex = size_t;
22 using LastIndex = size_t;
23 
24 bool findFiles(const std::filesystem::path& dirPath,
25                const std::string& matchString,
26                std::vector<std::filesystem::path>& foundPaths);
27 bool findFiles(const std::vector<std::filesystem::path>& dirPaths,
28                const std::string& matchString,
29                std::vector<std::filesystem::path>& foundPaths);
30 
31 bool getI2cDevicePaths(const std::filesystem::path& dirPath,
32                        std::flat_map<size_t, std::filesystem::path>& busPaths);
33 
34 struct DBusInternalError final : public sdbusplus::exception_t
35 {
nameDBusInternalError36     const char* name() const noexcept override
37     {
38         return "org.freedesktop.DBus.Error.Failed";
39     }
descriptionDBusInternalError40     const char* description() const noexcept override
41     {
42         return "internal error";
43     }
whatDBusInternalError44     const char* what() const noexcept override
45     {
46         return "org.freedesktop.DBus.Error.Failed: "
47                "internal error";
48     }
49 
get_errnoDBusInternalError50     int get_errno() const noexcept override
51     {
52         return EACCES;
53     }
54 };
55 
deviceHasLogging(const nlohmann::json & json)56 inline bool deviceHasLogging(const nlohmann::json& json)
57 {
58     auto logging = json.find("Logging");
59     if (logging != json.end())
60     {
61         const auto* ptr = logging->get_ptr<const std::string*>();
62         if (ptr != nullptr)
63         {
64             if (*ptr == "Off")
65             {
66                 return false;
67             }
68         }
69     }
70     return true;
71 }
72 
73 /// \brief Match a Dbus property against a probe statement.
74 /// \param probe the probe statement to match against.
75 /// \param dbusValue the property value being matched to a probe.
76 /// \return true if the dbusValue matched the probe otherwise false.
77 bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue);
78 
asciiToLower(char c)79 inline char asciiToLower(char c)
80 {
81     // Converts a character to lower case without relying on std::locale
82     if ('A' <= c && c <= 'Z')
83     {
84         c -= static_cast<char>('A' - 'a');
85     }
86     return c;
87 }
88 
89 template <typename T>
iFindFirst(T && str,std::string_view sub)90 auto iFindFirst(T&& str, std::string_view sub)
91 {
92     return std::ranges::search(str, sub, [](char a, char b) {
93         return asciiToLower(a) == asciiToLower(b);
94     });
95 }
96 
97 std::vector<std::string> split(std::string_view str, char delim);
98 
99 void iReplaceAll(std::string& str, std::string_view search,
100                  std::string_view replace);
101 
102 void replaceAll(std::string& str, std::string_view search,
103                 std::string_view replace);
104 
105 std::string toLowerCopy(std::string_view str);
106 
107 template <typename T>
fromCharsWrapper(const std::string_view & str,T & out,bool & fullMatch,int base=10)108 std::from_chars_result fromCharsWrapper(const std::string_view& str, T& out,
109                                         bool& fullMatch, int base = 10)
110 {
111     auto result = std::from_chars(
112         str.data(), std::next(str.begin(), str.size()), out, base);
113 
114     fullMatch = result.ptr == std::next(str.begin(), str.size());
115 
116     return result;
117 }
118