• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef ANDROID_HARDWARE_VIBRATOR_UTILS_H
17 #define ANDROID_HARDWARE_VIBRATOR_UTILS_H
18 
19 #include <android-base/macros.h>
20 #include <android-base/properties.h>
21 #include <log/log.h>
22 
23 #include <fstream>
24 
25 namespace android {
26 namespace hardware {
27 namespace vibrator {
28 namespace utils {
29 
30 template <typename T>
31 class Is_Iterable {
32   private:
33     template <typename U>
34     static std::true_type test(typename U::iterator *u);
35 
36     template <typename U>
37     static std::false_type test(U *u);
38 
39   public:
40     static const bool value = decltype(test<T>(0))::value;
41 };
42 
43 template <typename T, bool B>
44 using Enable_If_Iterable = std::enable_if_t<Is_Iterable<T>::value == B>;
45 
46 template <typename T, typename U = void>
47 using Enable_If_Signed = std::enable_if_t<std::is_signed_v<T>, U>;
48 
49 template <typename T, typename U = void>
50 using Enable_If_Unsigned = std::enable_if_t<std::is_unsigned_v<T>, U>;
51 
52 // override for default behavior of printing as a character
53 inline std::ostream &operator<<(std::ostream &stream, const int8_t value) {
54     return stream << +value;
55 }
56 // override for default behavior of printing as a character
57 inline std::ostream &operator<<(std::ostream &stream, const uint8_t value) {
58     return stream << +value;
59 }
60 
61 template <typename T>
toUnderlying(const T value)62 inline auto toUnderlying(const T value) {
63     return static_cast<std::underlying_type_t<T>>(value);
64 }
65 
66 template <typename T>
unpack(std::istream & stream,T * value)67 inline Enable_If_Iterable<T, true> unpack(std::istream &stream, T *value) {
68     for (auto &entry : *value) {
69         stream >> entry;
70     }
71 }
72 
73 template <typename T>
unpack(std::istream & stream,T * value)74 inline Enable_If_Iterable<T, false> unpack(std::istream &stream, T *value) {
75     stream >> *value;
76 }
77 
78 template <>
79 inline void unpack<std::string>(std::istream &stream, std::string *value) {
80     *value = std::string(std::istreambuf_iterator(stream), {});
81     stream.setstate(std::istream::eofbit);
82 }
83 
84 template <typename T>
getProperty(const std::string & key,const T def)85 inline Enable_If_Signed<T, T> getProperty(const std::string &key, const T def) {
86     return base::GetIntProperty(key, def);
87 }
88 
89 template <typename T>
getProperty(const std::string & key,const T def)90 inline Enable_If_Unsigned<T, T> getProperty(const std::string &key, const T def) {
91     return base::GetUintProperty(key, def);
92 }
93 
94 template <>
95 inline bool getProperty<bool>(const std::string &key, const bool def) {
96     return base::GetBoolProperty(key, def);
97 }
98 
99 template <typename T>
openNoCreate(const std::string & file,T * outStream)100 static void openNoCreate(const std::string &file, T *outStream) {
101     auto mode = std::is_base_of_v<std::ostream, T> ? std::ios_base::out : std::ios_base::in;
102 
103     // Force 'in' mode to prevent file creation
104     outStream->open(file, mode | std::ios_base::in);
105     if (!*outStream) {
106         ALOGE("Failed to open %s (%d): %s", file.c_str(), errno, strerror(errno));
107     }
108 }
109 
110 template <typename T>
111 static void fileFromEnv(const char *env, T *outStream, std::string *outName = nullptr) {
112     auto file = std::getenv(env);
113 
114     if (file == nullptr) {
115         ALOGE("Failed get env %s", env);
116         return;
117     }
118 
119     if (outName != nullptr) {
120         *outName = std::string(file);
121     }
122 
123     openNoCreate(file, outStream);
124 }
125 
126 static ATTRIBUTE_UNUSED auto pathsFromEnv(const char *env, const std::string &prefix = "") {
127     std::map<std::string, std::ifstream> ret;
128     auto value = std::getenv(env);
129 
130     if (value == nullptr) {
131         return ret;
132     }
133 
134     std::istringstream paths{value};
135     std::string path;
136 
137     while (paths >> path) {
138         ret[path].open(prefix + path);
139     }
140 
141     return ret;
142 }
143 
144 static ATTRIBUTE_UNUSED std::string trim(const std::string &str,
145                                          const std::string &whitespace = " \t") {
146     const auto str_begin = str.find_first_not_of(whitespace);
147     if (str_begin == std::string::npos) {
148         return "";
149     }
150 
151     const auto str_end = str.find_last_not_of(whitespace);
152     const auto str_range = str_end - str_begin + 1;
153 
154     return str.substr(str_begin, str_range);
155 }
156 
157 }  // namespace utils
158 }  // namespace vibrator
159 }  // namespace hardware
160 }  // namespace android
161 
162 #endif  // ANDROID_HARDWARE_VIBRATOR_UTILS_H
163