-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathUtil.hh
335 lines (282 loc) · 12.7 KB
/
Util.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/*
* Copyright (C) 2016 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef IGNITION_COMMON_UTIL_HH_
#define IGNITION_COMMON_UTIL_HH_
#include <cassert>
#include <chrono>
#include <future>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include <ignition/common/Export.hh>
#include <ignition/common/Filesystem.hh>
#include <ignition/common/SystemPaths.hh>
#include <ignition/common/URI.hh>
/////////////////////////////////////////////////
// Defines
#ifdef _WIN32
# define IGN_HOMEDIR "USERPROFILE"
#else
# define IGN_HOMEDIR "HOME"
#endif
/// \brief Seconds in one nano second.
#define IGN_NANO_TO_SEC 1e-9
/// \brief Nano seconds in one second.
#define IGN_SEC_TO_NANO 1000000000
/// \brief Nano seconds in one millisecond.
#define IGN_MS_TO_NANO 1000000
/// \brief Nano seconds in one microsecond.
#define IGN_US_TO_NANO 1000
/// \brief Speed of light.
#define IGN_SPEED_OF_LIGHT = 299792458.0
/// \brief Sleep for the specifed number of seconds
#define IGN_SLEEP_S(_s) (std::this_thread::sleep_for(\
std::chrono::seconds(_s)))
/// \brief Sleep for the specifed number of microseconds
#define IGN_SLEEP_US(_us) (std::this_thread::sleep_for(\
std::chrono::microseconds(_us)))
/// \brief Sleep for the specifed number of milliseconds
#define IGN_SLEEP_MS(_ms) (std::this_thread::sleep_for(\
std::chrono::milliseconds(_ms)))
/// \brief Sleep for the specifed number of nanoseconds
#define IGN_SLEEP_NS(_ns) (std::this_thread::sleep_for(\
std::chrono::nanoseconds(_ns)))
/// \brief Get the system time.
#define IGN_SYSTEM_TIME() (std::chrono::system_clock::now())
/// \brief Get the system time in seconds since epoch.
#define IGN_SYSTEM_TIME_S() (std::chrono::duration_cast<std::chrono::seconds>(\
std::chrono::system_clock::now().time_since_epoch()).count())
/// \brief Get the system time in microseconds since epoch.
#define IGN_SYSTEM_TIME_US() (\
std::chrono::duration_cast<std::chrono::microseconds>(\
std::chrono::system_clock::now().time_since_epoch()).count())
/// \brief Get the system time in milliseconds since epoch.
#define IGN_SYSTEM_TIME_MS() (\
std::chrono::duration_cast<std::chrono::milliseconds>(\
std::chrono::system_clock::now().time_since_epoch()).count())
/// \brief Get the system time in nanoseconds since epoch.
#define IGN_SYSTEM_TIME_NS() (\
std::chrono::duration_cast<std::chrono::nanoseconds>(\
std::chrono::system_clock::now().time_since_epoch()).count())
/// \brief This macro defines the standard way of launching an exception
/// inside ignition.
#define IGN_ASSERT(_expr, _msg) assert((_msg, _expr))
/// \brief Forward declarations for the common classes
namespace ignition
{
namespace common
{
/// \brief Enumeration of the transform types
enum NodeTransformType {TRANSLATE, ROTATE, SCALE, MATRIX};
/// \brief A runtime error.
typedef std::runtime_error exception;
/// \brief Please use systemTimeIso() as this function will be deprecated
/// in Ignition Common 4.
/// Get the wall time as an ISO string: YYYY-MM-DDTHH:MM:SS.NS
/// \return The current wall time as an ISO string.
/// \sa systemTimeIso();
std::string IGNITION_COMMON_VISIBLE systemTimeISO();
/// \brief Get the wall time as an ISO string: YYYY-MM-DDTHH:MM:SS.NS
/// \return The current wall time as an ISO string.
std::string IGNITION_COMMON_VISIBLE systemTimeIso();
/// \brief Converts a time point to an ISO string: YYYY-MM-DDTHH:MM:SS.NS
/// \param[in] _time A time point, such as one created by
/// IGN_SYSTEM_TIME().
/// \return An ISO string that represents the given _time.
std::string IGNITION_COMMON_VISIBLE timeToIso(
const std::chrono::time_point<std::chrono::system_clock> &_time);
/// \brief Get the log path
/// \return the log path
std::string IGNITION_COMMON_VISIBLE logPath();
/// \brief add path suffix to common::SystemPaths
/// \param[in] _suffix The suffix to add.
void IGNITION_COMMON_VISIBLE addSearchPathSuffix(
const std::string &_suffix);
/// \brief search for file in common::SystemPaths
/// \param[in] _file Name of the file to find.
/// \return The path containing the file.
std::string IGNITION_COMMON_VISIBLE findFile(const std::string &_file);
/// \brief search for file in common::SystemPaths
/// \param[in] _file Name of the file to find.
/// \param[in] _searchLocalPath True to search in the current working
/// directory.
/// \return The path containing the file.
std::string IGNITION_COMMON_VISIBLE findFile(const std::string &_file,
bool _searchLocalPath);
/// \brief search for a file in common::SystemPaths
/// \param[in] _file the file name to look for.
/// \return The path containing the file.
std::string IGNITION_COMMON_VISIBLE findFilePath(const std::string &_file);
/// \brief Add a callback to use when findFile() can't find a file that is
/// a valid URI.
/// The callback should return a full local path to the requested file, or
/// and empty string if the file was not found in the callback.
/// Callbacks will be called in the order they were added until a path is
/// found.
/// \param[in] _cb The callback function, which takes a file path or URI
/// and returns the full local path.
void IGNITION_COMMON_VISIBLE addFindFileURICallback(
std::function<std::string(const URI &)> _cb);
/// \brief Get a pointer to the global system paths that is used by all
/// the findFile functions.
/// The returned instance has global shared state for a given process.
/// Care should be taken when manipulating global system paths
/// Caller should not assume ownership of the pointer.
/// \return A mutable reference to the system paths object.
common::SystemPaths IGNITION_COMMON_VISIBLE *systemPaths();
/// \brief Compute the SHA1 hash of an array of bytes.
/// \param[in] _buffer Input sequence. The permitted data types for this
/// function are std::string and any STL container.
/// \return The string representation (40 character) of the SHA1 hash.
template<typename T>
std::string sha1(const T &_buffer);
/// \brief Compute the SHA1 hash of an array of bytes. Use std::string
/// sha1(const T &_buffer) instead of this function
/// \param[in] _buffer Input sequence. The permitted data types for this
/// function are std::string and any STL container.
/// \return The string representation (40 character) of the SHA1 hash.
/// \sa sha1(const T &_buffer)
std::string IGNITION_COMMON_VISIBLE sha1(
void const *_buffer, std::size_t _byteCount);
/// \brief fnv1a algorithm for 64-bit platforms.
/// \param[in] _key The input string.
/// \return A 64-bit unsigned hash value.
/// \ref https://notes.underscorediscovery.com/constexpr-fnv1a/
constexpr uint64_t IGNITION_COMMON_VISIBLE hash64(std::string_view _key)
{
const char *data = _key.data();
const auto len = _key.size();
const uint64_t prime = 0x100000001b3;
uint64_t hash = 0xcbf29ce484222325;
for (auto i = 0u; i < len; ++i)
{
uint8_t value = static_cast<uint8_t>(data[i]);
hash = hash ^ value;
hash *= prime;
}
return hash;
}
/// \brief Find the environment variable '_name' and return its value.
///
/// \TODO(mjcarroll): Deprecate and remove in tick-tock.
///
/// \param[in] _name Name of the environment variable.
/// \param[out] _value Value if the variable was found.
/// \return True if the variable was found or false otherwise.
bool IGNITION_COMMON_VISIBLE env(
const std::string &_name, std::string &_value);
/// \brief Find the environment variable '_name' and return its value.
/// \param[in] _name Name of the environment variable.
/// \param[out] _value Value if the variable was found.
/// \param[in] _allowEmpty Allow set-but-empty variables.
/// (Unsupported on Windows)
/// \return True if the variable was found or false otherwise.
bool IGNITION_COMMON_VISIBLE env(
const std::string &_name, std::string &_value,
bool _allowEmpty);
/// \brief Set the environment variable '_name'.
///
/// Note that on Windows setting an empty string (_value=="")
/// is the equivalent of unsetting the variable.
///
/// \param[in] _name Name of the environment variable.
/// \param[in] _value Value of the variable to be set.
/// \return True if the variable was set or false otherwise.
bool IGNITION_COMMON_VISIBLE setenv(
const std::string &_name, const std::string &_value);
/// \brief Unset the environment variable '_name'.
/// \param[in] _name Name of the environment variable.
/// \return True if the variable was unset or false otherwise.
bool IGNITION_COMMON_VISIBLE unsetenv(const std::string &_name);
/// \brief Get a UUID
/// \return A UUID string
std::string IGNITION_COMMON_VISIBLE uuid();
/// \brief Splits a string into tokens.
/// \param[in] _str Input string.
/// \param[in] _delim Token delimiter.
/// \return Vector of tokens.
std::vector<std::string> IGNITION_COMMON_VISIBLE split(
const std::string &_str, const std::string &_delim);
/// \brief In place left trim
/// \param[in,out] _s String to trim
void IGNITION_COMMON_VISIBLE ltrim(std::string &_s);
/// \brief In place right trim
/// \param[in,out] _s String to trim
void IGNITION_COMMON_VISIBLE rtrim(std::string &_s);
/// \brief In place trim from both ends
/// \param[in,out] _s String to trim
void IGNITION_COMMON_VISIBLE trim(std::string &_s);
/// \brief Copying left trim
/// \param[in] _s String to trim
/// \return Trimmed string
std::string IGNITION_COMMON_VISIBLE ltrimmed(std::string _s);
/// \brief Copying right trim
/// \param[in] _s String to trim
/// \return Trimmed string
std::string IGNITION_COMMON_VISIBLE rtrimmed(std::string _s);
/// \brief Copying trim from both ends
/// \param[in] _s String to trim
/// \return Trimmed string
std::string IGNITION_COMMON_VISIBLE trimmed(std::string _s);
/// \brief Transforms a string to its lowercase equivalent
/// \param[in] _in String to convert to lowercase
/// \return Lowercase equilvalent of _in.
std::string IGNITION_COMMON_VISIBLE lowercase(const std::string &_in);
/// \brief Transforms a string to its lowercase equivalent
/// \param[in] _in String to convert to lowercase
/// \return Lowercase equilvalent of _in.
std::string IGNITION_COMMON_VISIBLE lowercase(const char *_in);
/// \brief Replace all occurances of _key with _replacement.
/// \param[out] _result The new string that has had _key replaced
/// with _replacement.
/// \param[in] _orig Original string.
/// \param[in] _key String to replace.
/// \param[in] _replacement The string that replaces _key.
/// \sa std::string replaceAll(const std::string &_orig,
/// const std::string &_key, const std::string &_replacement)
void IGNITION_COMMON_VISIBLE replaceAll(std::string &_result,
const std::string &_orig,
const std::string &_key,
const std::string &_replacement);
/// \brief Replace all occurances of _key with _replacement.
/// \param[in] _orig Original string.
/// \param[in] _key String to replace.
/// \param[in] _replacement The string that replaces _key.
/// \return The new string that has had _key replaced with _replacement.
/// \sa void common::replaceAll(std::string &_result,
/// const std::string &_orig, const std::string &_key,
/// const std::string &_replacement)
std::string IGNITION_COMMON_VISIBLE replaceAll(const std::string &_orig,
const std::string &_key,
const std::string &_replacement);
}
}
///////////////////////////////////////////////
// Implementation of get_sha1
template<typename T>
std::string ignition::common::sha1(const T &_buffer)
{
if (_buffer.size() == 0)
return ignition::common::sha1(NULL, 0);
else
{
return ignition::common::sha1(
&(_buffer[0]), _buffer.size() * sizeof(_buffer[0]));
}
}
#endif