xref: /openbmc/phosphor-hwmon/env.hpp (revision bd9bc00b)
1 #pragma once
2 
3 #include "sensorset.hpp"
4 
5 #include <fstream>
6 #include <string>
7 
8 namespace env
9 {
10 
11 /** @class Env
12  *  @brief Overridable std::getenv interface
13  */
14 struct Env
15 {
16     virtual ~Env() = default;
17 
18     virtual const char* get(const char* key) const = 0;
19 };
20 
21 /** @class EnvImpl
22  *  @brief Concrete implementation that calls std::getenv
23  */
24 struct EnvImpl : public Env
25 {
26     const char* get(const char* key) const override;
27 };
28 
29 /** @brief Default instantiation of Env */
30 extern EnvImpl env_impl;
31 
32 /** @brief Reads an environment variable
33  *
34  *  Reads the environment for that key
35  *
36  *  @param[in] key - the key
37  *  @param[in] env - env interface that defaults to calling std::getenv
38  *
39  *  @return string - the env var value
40  */
getEnv(const char * key,const Env * env=& env_impl)41 inline std::string getEnv(const char* key, const Env* env = &env_impl)
42 {
43     // Be aware value could be nullptr
44     auto value = env->get(key);
45     return (value) ? std::string(value) : std::string();
46 }
47 
48 /** @brief Reads an environment variable
49  *
50  *  Reads <prefix>_<sensor.first><sensor.second>
51  *
52  *  @param[in] prefix - the variable prefix
53  *  @param[in] sensor - Sensor details
54  *  @param[in] env - env interface that defaults to calling std::getenv
55  *
56  *  @return string - the env var value
57  */
getEnv(const char * prefix,const SensorSet::key_type & sensor,const Env * env=& env_impl)58 inline std::string getEnv(const char* prefix, const SensorSet::key_type& sensor,
59                           const Env* env = &env_impl)
60 {
61     std::string key;
62 
63     key.assign(prefix);
64     key.append(1, '_');
65     key.append(sensor.first);
66     key.append(sensor.second);
67 
68     return getEnv(key.c_str(), env);
69 }
70 
71 /** @brief Reads an environment variable, and takes type and id separately
72  *
73  *  @param[in] prefix - the variable prefix
74  *  @param[in] type - sensor type, like 'temp'
75  *  @param[in] id - sensor ID, like '5'
76  *  @param[in] env - env interface that defaults to calling std::getenv
77  *
78  *  @return string - the env var value
79  */
getEnv(const char * prefix,const std::string & type,const std::string & id,const Env * env=& env_impl)80 inline std::string getEnv(const char* prefix, const std::string& type,
81                           const std::string& id, const Env* env = &env_impl)
82 {
83     SensorSet::key_type sensor{type, id};
84     return getEnv(prefix, sensor, env);
85 }
86 
87 /** @brief Gets the ID for the sensor with a level of indirection
88  *
89  *  Read the ID from the <path>/<item><X>_<suffix> file.
90  *  <item> & <X> are populated from the sensor key.
91  *
92  *  @param[in] path - Directory path of the label file
93  *  @param[in] fileSuffix - The file suffix
94  *  @param[in] sensor - Sensor details
95  */
getIndirectID(std::string path,const std::string & fileSuffix,const SensorSet::key_type & sensor)96 inline std::string getIndirectID(std::string path,
97                                  const std::string& fileSuffix,
98                                  const SensorSet::key_type& sensor)
99 {
100     std::string content;
101 
102     path.append(sensor.first);
103     path.append(sensor.second);
104     path.append(1, '_');
105     path.append(fileSuffix);
106 
107     std::ifstream handle(path.c_str());
108     if (!handle.fail())
109     {
110         content.assign((std::istreambuf_iterator<char>(handle)),
111                        (std::istreambuf_iterator<char>()));
112 
113         if (!content.empty())
114         {
115             // remove the newline
116             content.pop_back();
117         }
118     }
119 
120     return content;
121 }
122 
123 } // namespace env
124