2017-03-11 22:16:12 +01:00
|
|
|
/*
|
|
|
|
* Puppeteer - A Motion Capture Mapping Tool
|
|
|
|
* Copyright (c) 2013-2015 Martin Felis <martin.felis@iwr.uni-heidelberg.de>.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
|
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE*
|
2016-08-29 22:31:11 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _STRING_UTILS_H
|
|
|
|
#define _STRING_UTILS_H
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
const std::string whitespaces_std (" \t\n\r");
|
|
|
|
const std::string invalid_name_characters = "{}[],;: \r\n\t#";
|
|
|
|
|
|
|
|
inline std::string strip_comments (const std::string &line) {
|
|
|
|
return line.substr (0, line.find ('#'));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string strip_whitespaces (const std::string &line, std::string whitespaces = whitespaces_std) {
|
|
|
|
std::string result (line);
|
|
|
|
if (result.find_first_of (whitespaces) != std::string::npos) {
|
|
|
|
result = result.substr (result.find_first_not_of (whitespaces), result.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
while (whitespaces.find (result[result.size() - 1]) != std::string::npos) {
|
|
|
|
result = result.substr (0, result.size() - 1);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string tolower (const std::string &line) {
|
|
|
|
std::string result (line);
|
2017-03-11 22:16:12 +01:00
|
|
|
for (size_t i = 0; i < line.size(); i++)
|
2016-08-29 22:31:11 +02:00
|
|
|
result[i] = tolower(result[i]);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string trim_line (const std::string &line) {
|
|
|
|
return tolower (strip_whitespaces (strip_comments (line)));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::vector<std::string> tokenize (const std::string &line_in, std::string delimiter=whitespaces_std) {
|
|
|
|
std::vector<std::string> result;
|
|
|
|
std::string line = line_in;
|
|
|
|
|
|
|
|
while (line.find_first_of (delimiter) != std::string::npos) {
|
|
|
|
std::string token = line.substr (0, line.find_first_of (delimiter));
|
|
|
|
|
|
|
|
line = line.substr (token.size() + 1, line.size());
|
|
|
|
result.push_back (token);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.size() > 0)
|
|
|
|
result.push_back (line);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::vector<std::string> tokenize_strip_whitespaces (const std::string &line_in, std::string delimiter=",\t\r\n", std::string whitespaces=whitespaces_std) {
|
|
|
|
std::vector<std::string> result;
|
|
|
|
std::string line = line_in;
|
|
|
|
|
|
|
|
while (line.find_first_of (delimiter) != std::string::npos) {
|
|
|
|
std::string token = line.substr (0, line.find_first_of (delimiter));
|
|
|
|
|
|
|
|
line = line.substr (token.size() + 1, line.size());
|
|
|
|
result.push_back (strip_whitespaces(token, whitespaces));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.size() > 0)
|
|
|
|
result.push_back (strip_whitespaces(line, whitespaces));
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::vector<std::string> tokenize_csv_strip_whitespaces (const std::string &line_in, const std::string whitespaces=whitespaces_std) {
|
|
|
|
std::vector<std::string> result;
|
|
|
|
std::string line = line_in;
|
|
|
|
|
|
|
|
size_t search_start = 0;
|
|
|
|
|
|
|
|
// first replace all whitespaces by regular spaces to simplify things
|
|
|
|
search_start = line.find_first_of (whitespaces);
|
|
|
|
while (search_start != std::string::npos) {
|
|
|
|
line[search_start] = ' ';
|
|
|
|
search_start = line.find_first_of (whitespaces, search_start + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
search_start = 0;
|
|
|
|
|
|
|
|
while (line.size() > 0) {
|
|
|
|
size_t separator_pos = std::string::npos;
|
|
|
|
|
|
|
|
separator_pos = line.find (", ");
|
|
|
|
// std::cout << " search '" << ", " << "' in '" << search_start << "' found at " << separator_pos << std::endl;
|
|
|
|
|
|
|
|
if (separator_pos == std::string::npos) {
|
|
|
|
separator_pos = line.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string token = line.substr (0, separator_pos);
|
|
|
|
// std::cout << "token = '" << token << "' separator_pos = " << separator_pos << std::endl;
|
|
|
|
token = strip_whitespaces (token, whitespaces);
|
|
|
|
if (token[token.size() - 1] == ',')
|
|
|
|
token = token.substr (0, token.size() - 1);
|
|
|
|
result.push_back (token);
|
|
|
|
|
|
|
|
if (line.size() <= separator_pos + 2)
|
|
|
|
break;
|
|
|
|
|
|
|
|
line = line.substr (separator_pos + 2, line.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Counts the number of occurrences of a list of characters.
|
|
|
|
*
|
|
|
|
* \param line_in The hay-stack to search for.
|
|
|
|
* \param characters The needles.
|
|
|
|
* \return The sum of occurrences of all needles found in the hay-stack.
|
|
|
|
*/
|
|
|
|
inline int count_char (const std::string &line_in, const std::string characters) {
|
|
|
|
int count = 0;
|
|
|
|
size_t index = 0;
|
|
|
|
size_t char_pos = line_in.find_first_of (characters, index);
|
|
|
|
|
|
|
|
while (char_pos != std::string::npos) {
|
|
|
|
index = char_pos + 1;
|
|
|
|
count ++;
|
|
|
|
char_pos = line_in.find_first_of (characters, index) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool is_numeric (const std::string &line) {
|
|
|
|
for (unsigned int i = 0; i < line.size(); i++) {
|
|
|
|
if (!isdigit(line[i]))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string sanitize_name (const std::string &name) {
|
|
|
|
std::string name_sanitized = name;
|
|
|
|
if (is_numeric(name)) {
|
|
|
|
std::cerr << "Warning invalid name '" << name << "': name should not be numeric only!" << std::endl;
|
|
|
|
name_sanitized = std::string("_") + name;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check for invalid characters
|
|
|
|
if (name.find_first_of (invalid_name_characters) != std::string::npos) {
|
|
|
|
std::cerr << "Error: Found invalid character '"
|
|
|
|
<< name[name.find_first_of (invalid_name_characters)]
|
|
|
|
<< "' in name '" << name << "'!" << std::endl;
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
return name_sanitized;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|