Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
environment.cpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  * Copyright (c) 2020 ZAFENA AB
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #include <cstring>
27 #include <string>
28 #include <algorithm>
29 #include <memory>
30 #include <cstdint>
31 #include <vector>
32 #include <cstdio>
33 
34 #include <jau/environment.hpp>
35 #include <jau/debug.hpp>
36 
37 using namespace jau;
38 
40 
41 bool environment::local_debug = false;
42 
43 static const std::string s_true("true");
44 static const std::string s_false("false");
45 
46 std::string environment::getProperty(const std::string & name) noexcept {
47  const char * value = getenv(name.c_str());
48  if( nullptr != value ) {
49  COND_PRINT(local_debug, "env::getProperty0 '%s': '%s'", name.c_str(), value);
50  return std::string( value );
51  }
52  if( std::string::npos != name.find('.', 0) ) {
53  // Retry with '.' -> '_' to please unix shell
54  std::string alt_name(name);
55  std::replace( alt_name.begin(), alt_name.end(), '.', '_');
56  value = getenv(alt_name.c_str());
57  if( nullptr != value ) {
58  COND_PRINT(local_debug, "env::getProperty0 '%s' -> '%s': '%s'", name.c_str(), alt_name.c_str(), value);
59  return std::string( value );
60  }
61  COND_PRINT(local_debug, "env::getProperty0 '%s' -> '%s': NOT FOUND", name.c_str(), alt_name.c_str());
62  } else {
63  COND_PRINT(local_debug, "env::getProperty0 '%s': NOT FOUND", name.c_str());
64  }
65  // not found: empty string
66  return std::string();
67 }
68 
69 std::string environment::getProperty(const std::string & name, const std::string & default_value) noexcept {
70  const std::string value = getProperty(name);
71  if( 0 == value.length() ) {
72  COND_PRINT(local_debug, "env::getProperty1 %s: null -> %s (default)", name.c_str(), default_value.c_str());
73  return default_value;
74  } else {
75  COND_PRINT(local_debug, "env::getProperty1 %s (default %s): %s", name.c_str(), default_value.c_str(), value.c_str());
76  return value;
77  }
78 }
79 
80 bool environment::getBooleanProperty(const std::string & name, const bool default_value) noexcept {
81  const std::string value = getProperty(name);
82  if( 0 == value.length() ) {
83  COND_PRINT(local_debug, "env::getBooleanProperty %s: null -> %d (default)", name.c_str(), default_value);
84  return default_value;
85  } else {
86  const bool res = "true" == value;
87  COND_PRINT(local_debug, "env::getBooleanProperty %s (default %d): %d/%s", name.c_str(), default_value, res, value.c_str());
88  return res;
89  }
90 }
91 
92 #include <limits.h>
93 
94 int32_t environment::getInt32Property(const std::string & name, const int32_t default_value,
95  const int32_t min_allowed, const int32_t max_allowed) noexcept
96 {
97  const std::string value = getProperty(name);
98  if( 0 == value.length() ) {
99  COND_PRINT(local_debug, "env::getInt32Property %s: null -> %" PRId32 " (default)", name.c_str(), default_value);
100  return default_value;
101  } else {
102  int32_t res = default_value;
103  char *endptr = NULL;
104  const long int res0 = strtol(value.c_str(), &endptr, 10);
105  if( *endptr == '\0' ) {
106  // string value completely valid
107  if( INT32_MIN <= res0 && res0 <= INT32_MAX ) {
108  // matching int32_t value range
109  const int32_t res1 = (int32_t)res0;
110  if( min_allowed <= res1 && res1 <= max_allowed ) {
111  // matching user value range
112  res = res1;
113  COND_PRINT(local_debug, "env::getInt32Property %s (default %" PRId32 "): %" PRId32 "/%s",
114  name.c_str(), default_value, res, value.c_str());
115  } else {
116  // invalid user value range
117  ERR_PRINT("env::getInt32Property %s: %" PRId32 "/%s (invalid user range [% " PRId32 "..%" PRId32 "]) -> %" PRId32 " (default)",
118  name.c_str(), res1, value.c_str(), min_allowed, max_allowed, res);
119  }
120  } else {
121  // invalid int32_t range
122  ERR_PRINT("env::getInt32Property %s: %" PRIu64 "/%s (invalid int32_t range) -> %" PRId32 " (default)",
123  name.c_str(), (uint64_t)res0, value.c_str(), res);
124  }
125  } else {
126  // string value not fully valid
127  ERR_PRINT("env::getInt32Property %s: %s (invalid string) -> %" PRId32 " (default)",
128  name.c_str(), value.c_str(), res);
129  }
130  return res;
131  }
132 }
133 
134 uint32_t environment::getUint32Property(const std::string & name, const uint32_t default_value,
135  const uint32_t min_allowed, const uint32_t max_allowed) noexcept
136 {
137  const std::string value = getProperty(name);
138  if( 0 == value.length() ) {
139  COND_PRINT(local_debug, "env::getUint32Property %s: null -> %" PRIu32 " (default)", name.c_str(), default_value);
140  return default_value;
141  } else {
142  uint32_t res = default_value;
143  char *endptr = NULL;
144  unsigned long int res0 = strtoul(value.c_str(), &endptr, 10);
145  if( *endptr == '\0' ) {
146  // string value completely valid
147  if( res0 <= UINT32_MAX ) {
148  // matching uint32_t value range
149  const uint32_t res1 = (uint32_t)res0;
150  if( min_allowed <= res1 && res1 <= max_allowed ) {
151  // matching user value range
152  res = res1;
153  COND_PRINT(local_debug, "env::getUint32Property %s (default %" PRIu32 "): %" PRIu32 "/%s",
154  name.c_str(), default_value, res, value.c_str());
155  } else {
156  // invalid user value range
157  ERR_PRINT("env::getUint32Property %s: %" PRIu32 "/%s (invalid user range [% " PRIu32 "..%" PRIu32 "]) -> %" PRIu32 " (default)",
158  name.c_str(), res1, value.c_str(), min_allowed, max_allowed, res);
159  }
160  } else {
161  // invalid uint32_t range
162  ERR_PRINT("env::getUint32Property %s: %" PRIu64 "/%s (invalid uint32_t range) -> %" PRIu32 " (default)",
163  name.c_str(), (uint64_t)res0, value.c_str(), res);
164  }
165  } else {
166  // string value not fully valid
167  ERR_PRINT("env::getUint32Property %s: %s (invalid string) -> %" PRIu32 " (default)",
168  name.c_str(), value.c_str(), res);
169  }
170  return res;
171  }
172 }
173 
174 void environment::envSet(std::string prefix_domain, std::string basepair) noexcept {
175  trimInPlace(basepair);
176  if( basepair.length() > 0 ) {
177  size_t pos = 0, start = 0;
178  if( (pos = basepair.find('=', start)) != std::string::npos ) {
179  const size_t elem_len = pos-start; // excluding '='
180  std::string name = prefix_domain+"."+basepair.substr(start, elem_len);
181  std::string value = basepair.substr(pos+1, std::string::npos);
182  trimInPlace(name);
183  trimInPlace(value);
184  if( name.length() > 0 ) {
185  if( value.length() > 0 ) {
186  COND_PRINT(local_debug, "env::setProperty %s -> %s (explode)", name.c_str(), value.c_str());
187  setenv(name.c_str(), value.c_str(), 1 /* overwrite */);
188  } else {
189  COND_PRINT(local_debug, "env::setProperty %s -> true (explode default-1)", name.c_str());
190  setenv(name.c_str(), "true", 1 /* overwrite */);
191  }
192  }
193  } else {
194  const std::string name = prefix_domain+"."+basepair;
195  COND_PRINT(local_debug, "env::setProperty %s -> true (explode default-0)", name.c_str());
196  setenv(name.c_str(), "true", 1 /* overwrite */);
197  }
198  }
199 }
200 
201 void environment::envExplodeProperties(std::string prefix_domain, std::string list) noexcept {
202  size_t pos = 0, start = 0;
203  while( (pos = list.find(',', start)) != std::string::npos ) {
204  const size_t elem_len = pos-start; // excluding ','
205  envSet(prefix_domain, list.substr(start, elem_len));
206  start = pos+1; // skip ','
207  }
208  const size_t elem_len = list.length()-start; // last one
209  if( elem_len > 0 ) {
210  envSet(prefix_domain, list.substr(start, elem_len));
211  }
212  COND_PRINT(local_debug, "env::setProperty %s -> true (explode default)", prefix_domain.c_str());
213  setenv(prefix_domain.c_str(), "true", 1 /* overwrite */);
214 }
215 
216 bool environment::getExplodingPropertiesImpl(const std::string & root_prefix_domain, const std::string & prefix_domain) noexcept {
217  std::string value = environment::getProperty(prefix_domain, s_false);
218  if( s_false == value ) {
219  return false;
220  }
221  if( s_true == value ) {
222  return true;
223  }
224  if( root_prefix_domain.length() > 0 && root_prefix_domain+".debug" == prefix_domain ) {
225  local_debug = true;
226  }
227  envExplodeProperties(prefix_domain, value);
228  return true;
229 }
230 
231 environment::environment(const std::string & root_prefix_domain_) noexcept
232 : root_prefix_domain(root_prefix_domain_),
233  debug( getExplodingPropertiesImpl(root_prefix_domain_, root_prefix_domain_+".debug") ),
234  debug_jni( getBooleanProperty(root_prefix_domain_+".debug.jni", false) ),
235  verbose( getExplodingPropertiesImpl(root_prefix_domain_, root_prefix_domain_+".verbose") || environment::debug )
236 {
237 }
jau::trimInPlace
void trimInPlace(std::string &s) noexcept
trim in place
Definition: basic_types.cpp:77
jau
Definition: basic_algos.hpp:34
jau::environment::debug
const bool debug
Debug logging enabled or disabled.
Definition: environment.hpp:269
s_true
static const std::string s_true("true")
jau::environment::getUint32Property
static uint32_t getUint32Property(const std::string &name, const uint32_t default_value, const uint32_t min_allowed=0, const uint32_t max_allowed=UINT32_MAX) noexcept
Returns the uint32_t value of the environment's variable 'name', or the 'default_value' if the enviro...
Definition: environment.cpp:134
jau::environment::getBooleanProperty
static bool getBooleanProperty(const std::string &name, const bool default_value) noexcept
Returns the boolean value of the environment's variable 'name', or the 'default_value' if the environ...
Definition: environment.cpp:80
s_false
static const std::string s_false("false")
jau::environment::startupTimeMilliseconds
static const uint64_t startupTimeMilliseconds
Module startup time t0 in monotonic time in milliseconds.
Definition: environment.hpp:75
debug.hpp
jau::environment::getInt32Property
static int32_t getInt32Property(const std::string &name, const int32_t default_value, const int32_t min_allowed=INT32_MIN, const int32_t max_allowed=INT32_MAX) noexcept
Returns the int32_t value of the environment's variable 'name', or the 'default_value' if the environ...
Definition: environment.cpp:94
jau::getCurrentMilliseconds
uint64_t getCurrentMilliseconds() noexcept
Returns current monotonic time in milliseconds.
Definition: basic_types.cpp:47
ERR_PRINT
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE: '.
Definition: debug.hpp:132
jau::environment::getProperty
static std::string getProperty(const std::string &name) noexcept
Returns the value of the environment's variable 'name'.
Definition: environment.cpp:46
COND_PRINT
#define COND_PRINT(C,...)
Use for conditional plain messages, prefix '[elapsed_time] '.
Definition: debug.hpp:165
environment.hpp