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