OmniSciDB  8a228a1076
StringTransform.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
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 
17 #ifndef SHARED_STRINGTRANSFORM_H
18 #define SHARED_STRINGTRANSFORM_H
19 
20 #ifndef __CUDACC__
21 #include <boost/config.hpp>
22 #include <boost/regex.hpp>
23 #include <optional>
24 #include <string_view>
25 #endif // __CUDACC__
26 
27 #include <algorithm>
28 #include <iomanip>
29 #include <sstream>
30 #include <string>
31 #include <vector>
32 
33 #ifndef __CUDACC__
34 void apply_shim(std::string& result,
35  const boost::regex& reg_expr,
36  const std::function<void(std::string&, const boost::smatch&)>& shim_fn);
37 
38 // cat - Concatenate values of arbitrary types into a string.
39 template <typename... Ts>
40 std::string cat(Ts&&... args) {
41  std::ostringstream oss;
42 #ifdef BOOST_NO_CXX17_FOLD_EXPRESSIONS
43  (void)(int[]){0, ((void)(oss << std::forward<Ts>(args)), 0)...};
44 #else
45  (oss << ... << std::forward<Ts>(args));
46 #endif
47  return oss.str();
48 }
49 #endif // __CUDACC__
50 
51 std::vector<std::pair<size_t, size_t>> find_string_literals(const std::string& query);
52 
53 // Replace passwords, keys, etc. in a sql query with 'XXXXXXXX'.
54 std::string hide_sensitive_data_from_query(std::string const& query_str);
55 
56 #ifndef __CUDACC__
57 std::optional<size_t> inside_string_literal(
58  const size_t start,
59  const size_t length,
60  const std::vector<std::pair<size_t, size_t>>& literal_positions);
61 #endif // __CUDACC__
62 
63 template <typename T>
64 std::string join(T const& container, std::string const& delim) {
65  std::stringstream ss;
66  if (!container.empty()) {
67  ss << container.front();
68  for (auto itr = std::next(container.cbegin()); itr != container.cend(); ++itr) {
69  ss << delim << *itr;
70  }
71  }
72  return ss.str();
73 }
74 
75 template <typename T>
76 std::string to_string(T&& v) {
77  std::ostringstream oss;
78  oss << v;
79  return oss.str();
80 }
81 
82 template <>
83 std::string to_string(char const*&& v);
84 
85 template <>
86 std::string to_string(std::string&& v);
87 
88 // NOTE(sy): to_upper/to_lower: As of Feb 2020, this is a solution recommended by Stack
89 // Overflow. Boost's to_upper_copy() is many times slower, maybe because it uses
90 // locale-aware std::toupper. Probably don't bother converting the input parameters to
91 // std::string_view because testing gave a small slowdown for std::string inputs and a
92 // small speedup for c-style string inputs for this usage.
93 
94 inline std::string to_upper(const std::string& str) {
95  auto str_uc = str;
96  std::transform(str_uc.begin(), str_uc.end(), str_uc.begin(), ::toupper);
97  return str_uc;
98 }
99 
100 inline std::string to_lower(const std::string& str) {
101  auto str_lc = str;
102  std::transform(str_lc.begin(), str_lc.end(), str_lc.begin(), ::tolower);
103  return str_lc;
104 }
105 
106 std::string generate_random_string(const size_t len);
107 
108 #ifndef __CUDACC__
109 std::vector<std::string> split(std::string_view str,
111  std::string_view delim = {},
112  std::optional<size_t> maxsplit = std::nullopt);
113 
115 std::string strip(std::string_view str);
116 #endif // __CUDACC__
117 
120  std::string& str) noexcept;
121 
122 #ifndef __CUDACC__
123 std::string get_quoted_string(const std::string& filename,
125  char quote = '"',
126  char escape = '\\');
127 
129 void filename_security_check(const std::string& filename);
130 #endif // __CUDACC__
131 
132 #ifndef __CUDACC__
133 namespace {
134 
135 template <typename T>
136 inline decltype(auto) stringlike(T&& parm) {
137  // String.
138  if constexpr (std::is_base_of_v<std::string, std::remove_reference_t<decltype(parm)>>) {
139  return std::forward<T>(parm);
140  }
141 
142  // Char Array.
143  else if constexpr (std::is_array_v<std::remove_reference_t<decltype(parm)>>) {
144  return std::forward<T>(parm);
145  }
146 
147  // Char String.
148  else if constexpr (std::is_same_v<std::remove_reference_t<decltype(parm)>,
149  const char*> ||
150  std::is_same_v<std::remove_reference_t<decltype(parm)>, char*>) {
151  return std::forward<T>(parm);
152  }
153 
154  // Integer or Floating Point.
155  else if constexpr (std::is_integral_v<std::remove_reference_t<decltype(parm)>> ||
156  std::is_floating_point_v<std::remove_reference_t<decltype(parm)>>) {
157  return std::to_string(std::forward<T>(parm));
158  }
159 
160  // Unsupported type that will fail at compile-time.
161  else {
162  static_assert(std::is_base_of_v<void, decltype(parm)>);
163  return std::string(); // unreachable, but needed to avoid extra error messages
164  }
165 }
166 
167 } // anonymous namespace
168 
169 template <typename... Types>
170 std::string concat(Types&&... parms) {
171  struct Joiner {
172  Joiner() {}
173 
174  std::string txt;
175 
176  void append(std::string_view moretxt) { txt += moretxt; }
177  }; // struct Joiner
178  Joiner j{};
179  (j.append(stringlike(std::forward<Types>(parms))), ...);
180  return std::move(j.txt);
181 }
182 
183 template <typename... Types>
184 std::string concat_with(std::string_view with, Types&&... parms) {
185  struct JoinerWith {
186  JoinerWith(std::string_view join) : join(join), first(true) {}
187 
188  std::string_view join;
189  bool first;
190  std::string txt;
191 
192  void append(std::string_view moretxt) {
193  if (!first) {
194  txt += join;
195  } else {
196  first = false;
197  }
198  txt += moretxt;
199  }
200  }; // struct JoinerWith
201  JoinerWith j{with};
202  (j.append(stringlike(std::forward<Types>(parms))), ...);
203  return std::move(j.txt);
204 }
205 #endif // __CUDACC__
206 
207 #endif // SHARED_STRINGTRANSFORM_H
std::string to_lower(const std::string &str)
std::string filename(char const *path)
Definition: Logger.cpp:62
std::string get_quoted_string(const std::string &filename, char quote='"', char escape = '\)
Quote a string while escaping any existing quotes in the string.
void apply_shim(std::string &result, const boost::regex &reg_expr, const std::function< void(std::string &, const boost::smatch &)> &shim_fn)
std::optional< size_t > inside_string_literal(const size_t start, const size_t length, const std::vector< std::pair< size_t, size_t >> &literal_positions)
std::string join(T const &container, std::string const &delim)
std::string hide_sensitive_data_from_query(std::string const &query_str)
std::string to_string(T &&v)
std::string generate_random_string(const size_t len)
std::string concat(Types &&... parms)
std::string cat(Ts &&... args)
std::vector< std::pair< size_t, size_t > > find_string_literals(const std::string &query)
size_t append(FILE *f, const size_t size, int8_t *buf)
Appends the specified number of bytes to the end of the file f from buf.
Definition: File.cpp:140
bool remove_unquoted_newlines_linefeeds_and_tabs_from_sql_string(std::string &str) noexcept
sanitize an SQL string
std::string to_upper(const std::string &str)
std::string strip(std::string_view str)
trim any whitespace from the left and right ends of a string
std::vector< std::string > split(std::string_view str, std::string_view delim={}, std::optional< size_t > maxsplit=std::nullopt)
split apart a string into a vector of substrings
std::string concat_with(std::string_view with, Types &&... parms)
void filename_security_check(const std::string &filename)
Throw exception if security problems found in a filename.