ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Helper.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "Helper.h"
9 
10 #include <fmt/chrono.h>
11 
12 #include <algorithm>
13 #include <cctype>
14 #include <cstdarg>
15 #include <sstream>
16 #include <unordered_set>
17 
18 #ifdef _WIN32
19 #include <windows.h>
20 #else
21 #include <unistd.h>
22 #endif // _WIN32
23 
24 namespace cloudViewer {
25 namespace utility {
26 
27 namespace {
28 // The StringAppendV function is borrowed from Google under the BSD license:
29 //
30 // Copyright 2012 Google Inc. All rights reserved.
31 // https://developers.google.com/protocol-buffers/
32 //
33 // Redistribution and use in source and binary forms, with or without
34 // modification, are permitted provided that the following conditions are met:
35 //
36 // * Redistributions of source code must retain the above copyright
37 // notice, this list of conditions and the following disclaimer.
38 // * Redistributions in binary form must reproduce the above
39 // copyright notice, this list of conditions and the following disclaimer
40 // in the documentation and/or other materials provided with the
41 // distribution.
42 // * Neither the name of Google Inc. nor the names of its
43 // contributors may be used to endorse or promote products derived from
44 // this software without specific prior written permission.
45 //
46 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
49 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
50 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 
58 void StringAppendV(std::string *dst, const char *format, va_list ap) {
59  // First try with a small fixed size buffer.
60  static const int kFixedBufferSize = 1024;
61  char fixed_buffer[kFixedBufferSize];
62 
63  // It is possible for methods that use a va_list to invalidate
64  // the data in it upon use. The fix is to make a copy
65  // of the structure before using it and use that copy instead.
66  va_list backup_ap;
67  va_copy(backup_ap, ap);
68  int result = vsnprintf(fixed_buffer, kFixedBufferSize, format, backup_ap);
69  va_end(backup_ap);
70 
71  if (result < kFixedBufferSize) {
72  if (result >= 0) {
73  // Normal case - everything fits.
74  dst->append(fixed_buffer, result);
75  return;
76  }
77 
78 #ifdef _MSC_VER
79  // Error or MSVC running out of space. MSVC 8.0 and higher
80  // can be asked about space needed with the special idiom below:
81  va_copy(backup_ap, ap);
82  result = vsnprintf(nullptr, 0, format, backup_ap);
83  va_end(backup_ap);
84 #endif
85  }
86 
87  // Increase the buffer size to the size requested by vsnprintf,
88  // plus one for the closing \0.
89  const int variable_buffer_size = result + 1;
90  std::unique_ptr<char[]> variable_buffer(new char[variable_buffer_size]);
91 
92  // Restore the va_list before we use it again.
93  va_copy(backup_ap, ap);
94  result = vsnprintf(variable_buffer.get(), variable_buffer_size, format,
95  backup_ap);
96  va_end(backup_ap);
97 
98  if (result >= 0 && result < variable_buffer_size) {
99  dst->append(variable_buffer.get(), result);
100  }
101 }
102 
103 bool IsNotWhiteSpace(const int character) {
104  return character != ' ' && character != '\n' && character != '\r' &&
105  character != '\t';
106 }
107 
108 } // namespace
109 
110 std::string StringPrintf(const char *format, ...) {
111  va_list ap;
112  va_start(ap, format);
113  std::string result;
114  StringAppendV(&result, format, ap);
115  va_end(ap);
116  return result;
117 }
118 
119 std::string StringReplace(const std::string &str,
120  const std::string &old_str,
121  const std::string &new_str) {
122  if (old_str.empty()) {
123  return str;
124  }
125  size_t position = 0;
126  std::string mod_str = str;
127  while ((position = mod_str.find(old_str, position)) != std::string::npos) {
128  mod_str.replace(position, old_str.size(), new_str);
129  position += new_str.size();
130  }
131  return mod_str;
132 }
133 
134 std::string StringReplaceFirst(const std::string &str,
135  const std::string &old_str,
136  const std::string &new_str) {
137  std::string mod_str = str;
138  size_t start_pos = mod_str.find(old_str);
139  if (start_pos == std::string::npos) return mod_str;
140  mod_str.replace(start_pos, old_str.length(), new_str);
141  return mod_str;
142 }
143 
144 std::string StringReplaceLast(const std::string &str,
145  const std::string &old_str,
146  const std::string &new_str) {
147  std::string mod_str = str;
148  size_t start_pos = mod_str.rfind(old_str);
149  if (start_pos == std::string::npos) return mod_str;
150  mod_str.replace(start_pos, old_str.length(), new_str);
151  return mod_str;
152 }
153 
154 bool StringContains(const std::string &src, const std::string &dst) {
155  return src.find(dst) != std::string::npos;
156 }
157 
158 bool StringStartsWith(const std::string &str, const std::string &prefix) {
159  return !prefix.empty() && prefix.size() <= str.size() &&
160  str.substr(0, prefix.size()) == prefix;
161 }
162 
163 bool StringEndsWith(const std::string &str, const std::string &postfix) {
164  return !postfix.empty() && postfix.size() <= str.size() &&
165  str.substr(str.size() - postfix.size(), str.size()) == postfix;
166 }
167 
168 std::string JoinStrings(const std::vector<std::string> &strs,
169  const std::string &delimiter) {
170  std::ostringstream oss;
171  for (size_t i = 0; i < strs.size(); ++i) {
172  oss << strs[i];
173  if (i != strs.size() - 1) {
174  oss << delimiter;
175  }
176  }
177  return oss.str();
178 }
179 
180 std::vector<std::string> StringSplit(const std::string &str,
181  const std::string &delimiters /* = " "*/,
182  bool trim_empty_str /* = true*/) {
183  std::vector<std::string> tokens;
184  std::string::size_type pos = 0, last_pos = 0;
185  std::string::size_type new_pos;
186  while (pos != std::string::npos) {
187  pos = str.find_first_of(delimiters, last_pos);
188  new_pos = (pos == std::string::npos ? str.length() : pos);
189  if (new_pos != last_pos || !trim_empty_str) {
190  tokens.push_back(str.substr(last_pos, new_pos - last_pos));
191  }
192  last_pos = new_pos + 1;
193  }
194  return tokens;
195 }
196 
197 void SplitString(std::vector<std::string> &tokens,
198  const std::string &str,
199  const std::string &delimiters /* = " "*/,
200  bool trim_empty_str /* = true*/) {
201  std::string::size_type pos = 0, new_pos = 0, last_pos = 0;
202  while (pos != std::string::npos) {
203  pos = str.find_first_of(delimiters, last_pos);
204  new_pos = (pos == std::string::npos ? str.length() : pos);
205  if (new_pos != last_pos || !trim_empty_str) {
206  tokens.push_back(str.substr(last_pos, new_pos - last_pos));
207  }
208  last_pos = new_pos + 1;
209  }
210 }
211 
212 std::vector<std::string> SplitString(const std::string &str,
213  const std::string &delimiters /* = " "*/,
214  bool trim_empty_str /* = true*/) {
215  std::vector<std::string> tokens;
216  std::string::size_type pos = 0, new_pos = 0, last_pos = 0;
217  while (pos != std::string::npos) {
218  pos = str.find_first_of(delimiters, last_pos);
219  new_pos = (pos == std::string::npos ? str.length() : pos);
220  if (new_pos != last_pos || !trim_empty_str) {
221  tokens.push_back(str.substr(last_pos, new_pos - last_pos));
222  }
223  last_pos = new_pos + 1;
224  }
225  return tokens;
226 }
227 
228 std::string &LeftStripString(std::string &str, const std::string &chars) {
229  str.erase(0, str.find_first_not_of(chars));
230  return str;
231 }
232 
233 std::string &RightStripString(std::string &str, const std::string &chars) {
234  str.erase(str.find_last_not_of(chars) + 1);
235  return str;
236 }
237 
238 std::string &StripString(std::string &str, const std::string &chars) {
239  return LeftStripString(RightStripString(str, chars), chars);
240 }
241 
242 std::string ToLower(const std::string &str) {
243  std::string out = str;
244  std::transform(str.begin(), str.end(), out.begin(),
245  [](unsigned char c) { return std::tolower(c); });
246  return out;
247 }
248 
249 std::string ToUpper(const std::string &str) {
250  std::string out = str;
251  std::transform(str.begin(), str.end(), out.begin(),
252  [](unsigned char c) { return std::toupper(c); });
253  return out;
254 }
255 
256 // Count the length of current word starting from start_pos
257 size_t WordLength(const std::string &doc,
258  size_t start_pos,
259  const std::string &valid_chars) {
260  std::unordered_set<char> valid_chars_set;
261  for (const char &c : valid_chars) {
262  valid_chars_set.insert(c);
263  }
264  auto is_word_char = [&valid_chars_set](const char &c) {
265  return std::isalnum(c) ||
266  valid_chars_set.find(c) != valid_chars_set.end();
267  };
268  size_t length = 0;
269  for (size_t pos = start_pos; pos < doc.size(); ++pos) {
270  if (!is_word_char(doc[pos])) {
271  break;
272  }
273  length++;
274  }
275  return length;
276 }
277 
278 void Sleep(int milliseconds) {
279 #ifdef _WIN32
280  ::Sleep(milliseconds);
281 #else
282  usleep(milliseconds * 1000);
283 #endif // _WIN32
284 }
285 
286 std::string GetCurrentTimeStamp() {
287  std::time_t t = std::time(nullptr);
288  return fmt::format("{:%Y-%m-%d-%H-%M-%S}", *std::localtime(&t));
289 }
290 
291 } // namespace utility
292 } // namespace cloudViewer
filament::Texture::InternalFormat format
math::float3 position
core::Tensor result
Definition: VtkUtils.cpp:76
__host__ __device__ float length(float2 v)
Definition: cutil_math.h:1162
Helper functions for the ml ops.
size_t WordLength(const std::string &doc, size_t start_pos, const std::string &valid_chars="_")
Definition: Helper.cpp:257
std::string StringPrintf(const char *format,...)
Definition: Helper.cpp:110
void SplitString(std::vector< std::string > &tokens, const std::string &str, const std::string &delimiters=" ", bool trim_empty_str=true)
Definition: Helper.cpp:197
std::string & StripString(std::string &str, const std::string &chars="\t\n\v\f\r ")
Definition: Helper.cpp:238
bool StringEndsWith(const std::string &str, const std::string &postfix)
Definition: Helper.cpp:163
std::string ToLower(const std::string &s)
Convert string to the lower case.
Definition: Helper.cpp:242
std::string JoinStrings(const std::vector< std::string > &strs, const std::string &delimiter=", ")
Definition: Helper.cpp:168
std::string & RightStripString(std::string &str, const std::string &chars="\t\n\v\f\r ")
Definition: Helper.cpp:233
std::string StringReplaceLast(const std::string &str, const std::string &old_str, const std::string &new_str)
Definition: Helper.cpp:144
bool StringContains(const std::string &src, const std::string &dst)
Definition: Helper.cpp:154
void Sleep(int milliseconds)
Definition: Helper.cpp:278
std::string ToUpper(const std::string &s)
Convert string to the upper case.
Definition: Helper.cpp:249
std::string GetCurrentTimeStamp()
Returns current time stamp.
Definition: Helper.cpp:286
std::string & LeftStripString(std::string &str, const std::string &chars="\t\n\v\f\r ")
Definition: Helper.cpp:228
std::vector< std::string > StringSplit(const std::string &str, const std::string &delimiters=" ", bool trim_empty_str=true)
Definition: Helper.cpp:180
std::string StringReplace(const std::string &str, const std::string &old_str, const std::string &new_str)
Definition: Helper.cpp:119
std::string StringReplaceFirst(const std::string &str, const std::string &old_str, const std::string &new_str)
Definition: Helper.cpp:134
bool StringStartsWith(const std::string &str, const std::string &prefix)
Definition: Helper.cpp:158
Generic file read and write utility for python interface.