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