/*
Copyright© 2021 John Sennesael
UsenetSearch is Free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UsenetSearch is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with UsenetSearch. If not, see .
*/
#include "usenetsearch/StringUtils.h"
#include "usenetsearch/Logger.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace usenetsearch {
static std::wstring_convert> conv;
std::string CharToHex(const char c)
{
const int val = c;
std::ostringstream result;
result << std::setw(2) << std::setfill('0') << std::hex;
result << val;
return result.str();
}
std::string StringFromWideString(const std::wstring& input)
{
std::string result;
try
{
result = conv.to_bytes(input);
}
catch(const std::range_error&)
{
return "";
}
return result;
}
std::string StringHash(const std::string& input)
{
unsigned char result[MD5_DIGEST_LENGTH];
MD5(
reinterpret_cast(const_cast(input.c_str())),
input.size(),
result
);
std::ostringstream sout;
sout << std::hex << std::setfill('0');
for(long long c: result)
{
sout << std::setw(2) << reinterpret_cast(c);
}
return sout.str();
}
std::array StringHashBytes(const std::string& input)
{
unsigned char buff[MD5_DIGEST_LENGTH];
MD5(
reinterpret_cast(const_cast(input.c_str())),
input.size(),
buff
);
std::array result;
std::copy(std::begin(buff), std::end(buff), result.begin());
return result;
}
std::string HashBytesToString(const std::array& input)
{
std::ostringstream sout;
sout << std::hex << std::setfill('0');
for(std::uint8_t c: input)
{
sout << std::setw(2) << static_cast(c);
}
return sout.str();
}
bool StringStartsWith(const std::string& needle, const std::string& haystack)
{
return (std::strncmp(haystack.c_str(),needle.c_str(),needle.size()) == 0);
}
bool StringStartsWith(const std::wstring& needle, const std::wstring& haystack)
{
return (std::wcsncmp(haystack.c_str(),needle.c_str(),needle.size()) == 0);
}
bool StringToBoolean(const std::string& str)
{
const std::string lstr = StringTrim(StringToLower(str));
if ((lstr == "true") || (lstr == "yes") || (lstr == "1")) return true;
if ((lstr == "false") || (lstr == "no") || (lstr == "0")) return false;
Logger::Get().Fatal(
LOGID("StringUtils"),
"The string \"" + str + "\" is not a valid boolean value."
);
return false;
}
bool StringToBoolean(const std::wstring& str)
{
const std::wstring lstr = StringTrim(StringToLower(str));
if ((lstr == L"true") || (lstr == L"yes") || (lstr == L"1")) return true;
if ((lstr == L"false") || (lstr == L"no") || (lstr == L"0")) return false;
std::wstring_convert> conv;
Logger::Get().Fatal(
LOGID("StringUtils"),
"The string \"" + conv.to_bytes(str)
+ "\" is not a valid boolean value."
);
return false;
}
void StringTreeOperation(
const std::string& searchString,
const std::string& splitBy,
size_t maxDepth,
std::function Fn)
{
const auto tokens = StringSplit(searchString, splitBy);
std::vector tokenList;
for (auto outerIt = tokens.begin(); outerIt != tokens.end(); outerIt++)
{
for (size_t depth = 1; depth != maxDepth + 1; ++depth)
{
const auto endIt = outerIt + depth;
const auto subset = std::vector(outerIt, endIt);
const auto subToken = StringJoin(subset, splitBy);
// Check if we already have this token.
//
// For phrases like "we went here and then we went there" this would
// avoid indexing the tokens 'we' and 'went' and 'we went' twice.
if (std::find(tokenList.begin(), tokenList.end(), subToken)
== tokenList.end())
{
Fn(subToken, searchString);
tokenList.emplace_back(subToken);
}
if (endIt == tokens.end()) break;
}
}
}
std::wstring WideStringFromString(const std::string& input)
{
std::wstring result;
try
{
result = conv.from_bytes(input);
}
catch(const std::range_error&)
{
return L"";
}
return result;
}
} // namespace usenetsearch