blob: 7f332608a23d80bd1ab201507d067f71139c999a [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 LIBMINIFI_INCLUDE_IO_STRINGUTILS_H_
#define LIBMINIFI_INCLUDE_IO_STRINGUTILS_H_
#include <iostream>
#include <algorithm>
#include <sstream>
#include <vector>
#include <map>
#include "utils/FailurePolicy.h"
namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace utils {
/**
* Stateless String utility class.
*
* Design: Static class, with no member variables
*
* Purpose: Houses many useful string utilities.
*/
class StringUtils {
public:
/**
* Converts a string to a boolean
* Better handles mixed case.
* @param input input string
* @param output output string.
*/
static bool StringToBool(std::string input, bool &output) {
std::transform(input.begin(), input.end(), input.begin(), ::tolower);
std::istringstream(input) >> std::boolalpha >> output;
return output;
}
// Trim String utils
/**
* Trims a string left to right
* @param s incoming string
* @returns modified string
*/
static std::string trim(std::string s) {
return trimRight(trimLeft(s));
}
/**
* Trims left most part of a string
* @param s incoming string
* @returns modified string
*/
static inline std::string trimLeft(std::string s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::pointer_to_unary_function<int, int>(std::isspace))));
return s;
}
/**
* Trims a string on the right
* @param s incoming string
* @returns modified string
*/
static inline std::string trimRight(std::string s) {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::pointer_to_unary_function<int, int>(std::isspace))).base(), s.end());
return s;
}
/**
* Compares strings by lower casing them.
*/
static inline bool equalsIgnoreCase(const std::string &left, const std::string right) {
if (left.length() == right.length()) {
return std::equal(right.begin(), right.end(), left.begin(), [](unsigned char lc, unsigned char rc) {return std::tolower(lc) == std::tolower(rc);});
} else {
return false;
}
}
static std::vector<std::string> split(const std::string &str, const std::string &delimiter) {
std::vector<std::string> result;
auto curr = str.begin();
auto end = str.end();
auto is_func = [delimiter](int s) {
return delimiter.at(0) == s;
};
while (curr != end) {
curr = std::find_if_not(curr, end, is_func);
if (curr == end) {
break;
}
auto next = std::find_if(curr, end, is_func);
result.push_back(std::string(curr, next));
curr = next;
}
return result;
}
/**
* Converts a string to a float
* @param input input string
* @param output output float
* @param cp failure policy
*/
static bool StringToFloat(std::string input, float &output, FailurePolicy cp = RETURN) {
try {
output = std::stof(input);
} catch (const std::invalid_argument &ie) {
switch (cp) {
case RETURN:
case NOTHING:
return false;
case EXIT:
exit(1);
case EXCEPT:
throw ie;
}
} catch (const std::out_of_range &ofr) {
switch (cp) {
case RETURN:
case NOTHING:
return false;
case EXIT:
exit(1);
case EXCEPT:
throw ofr;
}
}
return true;
}
static std::string replaceEnvironmentVariables(std::string& original_string) {
int32_t beg_seq = 0;
int32_t end_seq = 0;
std::string source_string = original_string;
do {
beg_seq = source_string.find("${", beg_seq);
if (beg_seq > 0 && source_string.at(beg_seq - 1) == '\\') {
beg_seq += 2;
continue;
}
if (beg_seq < 0)
break;
end_seq = source_string.find("}", beg_seq + 2);
if (end_seq < 0)
break;
if (end_seq - (beg_seq + 2) < 0) {
beg_seq += 2;
continue;
}
const std::string env_field = source_string.substr(beg_seq + 2, end_seq - (beg_seq + 2));
const std::string env_field_wrapped = source_string.substr(beg_seq, end_seq + 1);
if (env_field.empty()) {
continue;
}
const auto strVal = std::getenv(env_field.c_str());
std::string env_value;
if (strVal != nullptr)
env_value = strVal;
source_string = replaceAll(source_string, env_field_wrapped, env_value);
beg_seq = 0; // restart
} while (beg_seq >= 0);
source_string = replaceAll(source_string, "\\$", "$");
return source_string;
}
static std::string& replaceAll(std::string& source_string, const std::string &from_string, const std::string &to_string) {
std::size_t loc = 0;
std::size_t lastFound;
while ((lastFound = source_string.find(from_string, loc)) != std::string::npos) {
source_string.replace(lastFound, from_string.size(), to_string);
loc = lastFound + to_string.size();
}
return source_string;
}
inline static bool endsWithIgnoreCase(const std::string &value, const std::string & endString) {
if (endString.size() > value.size())
return false;
return std::equal(endString.rbegin(), endString.rend(), value.rbegin(), [](unsigned char lc, unsigned char rc) {return std::tolower(lc) == std::tolower(rc);});
}
inline static bool endsWith(const std::string &value, const std::string & endString) {
if (endString.size() > value.size())
return false;
return std::equal(endString.rbegin(), endString.rend(), value.rbegin());
}
static std::string replaceMap(std::string source_string, const std::map<std::string, std::string> &replace_map) {
auto result_string = source_string;
std::vector<std::pair<size_t, std::pair<size_t, std::string>>> replacements;
for (const auto &replace_pair : replace_map) {
size_t replace_pos = 0;
while ((replace_pos = source_string.find(replace_pair.first, replace_pos)) != std::string::npos) {
replacements.emplace_back(std::make_pair(replace_pos,
std::make_pair(replace_pair.first.length(), replace_pair.second)));
replace_pos += replace_pair.first.length();
}
}
std::sort(replacements.begin(), replacements.end(), [](const std::pair<size_t, std::pair<size_t, std::string>> a,
const std::pair<size_t, std::pair<size_t, std::string>> &b) {
return a.first > b.first;
});
for (const auto &replacement : replacements) {
result_string = source_string.replace(replacement.first, replacement.second.first, replacement.second.second);
}
return result_string;
}
};
} /* namespace utils */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */
#endif /* LIBMINIFI_INCLUDE_IO_STRINGUTILS_H_ */