winamp/Src/Plugins/DSP/sc_serv3/nmrCommon/stl/stringUtils.h
2024-09-24 14:54:57 +02:00

384 lines
8.9 KiB
C++

#pragma once
#ifndef _stringUtils_H_
#define _stringUtils_H_
#include <sstream>
#include <string>
#include <functional>
#include <vector>
#include <locale>
#include <ctype.h>
namespace stringUtil
{
#ifdef _WIN32
inline std::string eol() throw() { return "\r\n"; }
#elif MACINTOSH
inline std::string eol() throw() { return "\r"; }
#else
inline std::string eol() throw() { return "\n"; }
#endif
//////////////////////////////////////////////////////////////////
//////////////////// String Conversion ///////////////////////////
//////////////////////////////////////////////////////////////////
// the 'safe' functions are to avoid bad_cast exceptions when the
// passed in type does not have a facet, or the facet indicates that
// the value is out of range. Since I may be running this against Unicode
// strings, I need to deal with this. Most likely there's a way to set the
// proper locale and facet so the error doesn't occur, but this is beyond
// me right now - NMR
template<typename T>
bool safe_is_alpha(T v)
{
if (((unsigned int)v) > 0x7f) return false;
return std::isalpha((char)v,std::locale());
}
template<typename T>
bool safe_is_digit(T v)
{
if (((unsigned int)v) > 0x7f) return false;
return std::isdigit((char)v,std::locale());
}
template<typename T>
bool safe_is_space(T v)
{
if (((unsigned int)v) > 0x7f) return false;
return std::isspace((char)v,std::locale());
}
template<typename T>
T safe_to_lower(T v)
{
if (((unsigned int)v) > 0x7f) return v;
return std::tolower((char)v,std::locale());
}
template<typename T>
T safe_to_upper(T v)
{
if (((unsigned int)v) > 0x7f) return v;
return std::toupper((char)v,std::locale());
}
template<typename S>
S toLower(const S &s) throw()
{
S result;
for (typename S::const_iterator i = s.begin(); i != s.end(); ++i)
{
result += (stringUtil::safe_is_alpha(*i) ? stringUtil::safe_to_lower(*i) : *i);
}
return result;
}
template<typename S>
S toUpper(const S &s) throw()
{
S result;
for (typename S::const_iterator i = s.begin(); i != s.end(); ++i)
{
result += (stringUtil::safe_is_alpha(*i) ? stringUtil::safe_to_upper(*i) : *i);
}
return result;
}
template<typename S>
inline bool compareStringsWithoutCase(const S &s1,const S &s2) throw()
{
S s1c(toLower(s1));
S s2c(toLower(s2));
return (s1c == s2c);
}
inline std::string dosToUnix(const std::string &s) throw()
{
std::string result;
bool r(false);
for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
{
if ((*i) == '\n')
{
if (r)
{
result += '\n';
}
else
{
result.push_back(*i);
}
r = false;
}
else if ((*i) == '\r')
{
if (r)
result.push_back('\r');
r = true;
}
else
{
if (r)
result.push_back('\r');
r = false;
result.push_back(*i);
}
}
return result;
}
inline std::string unixToDos(const std::string &s) throw()
{
std::string result;
for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
{
if ((*i) == '\n')
result += "\r\n";
else
result.push_back(*i);
}
return result;
}
//***************************************************************
//* tos, tows
//*
//* These templates and overloaded functions allow you to convert
//* any streamable value to a string or wide-string. It can be a
//* great convenience to be able to do
//*
//* string("test five ") + tos(5);
//*
//* instead of
//*
//* ostringstream o;
//* o << "test five " << 5;
//* o.str()
//*
//* tows is just like tos, but for wide strings. You can also use these
//* to convert standard strings to wide strings and vice-versa
//*
//* for example:
//*
//* wstring ws = tows(string("hello"));
//* string s = tos(wstring(L"goodbye"));
//*
//************************************************************************
template<typename S,typename T>
S tobs(T v) // to basic string
{
std::basic_ostringstream<typename S::value_type> o;
o << v;
return o.str();
}
template<typename S>
S tobs(const S v) { return v; }
template<typename S>
S tobs(const typename S::value_type *v) { return S(v); }
template<typename t>
std::string tos(t v)
{
std::ostringstream o;
o << v;
return o.str();
}
inline std::string tos(const std::string &v) { return v; }
inline std::string tos(const char *v) { return std::string(v); }
template<typename t>
std::string tohex(t v)
{
std::ostringstream o;
o << std::hex << v;
return o.str();
}
#ifdef _WIN32
template<typename t>
std::wstring tows(t v)
{
std::wostringstream o;
o << v;
return o.str();
}
inline std::string tos(const wchar_t *value)
{
if (!value) return "";
size_t len = ::wcslen(value);
char *s = new char[len + 1];
::wcstombs(s,value,len);
s[len] = '\0';
std::string result(s);
delete [] s;
return result;
}
inline std::string tos(const std::wstring &s)
{
return tos(s.c_str());
}
inline std::wstring tows(const char *value)
{
if (!value) return L"";
size_t len = ::strlen(value);
wchar_t *s = new wchar_t[len + 1];
::mbstowcs(s,value,len);
s[len] = 0;
std::wstring result(s);
delete [] s;
return result;
}
inline std::wstring tows(const std::string &value)
{
return tows(value.c_str());
}
#endif
////////////////////////////////////////////////////////////////////
////////////////////// String stripping ////////////////////////////
////////////////////////////////////////////////////////////////////
//******************************************************************
//* A collection of templates and functions to allow stripping of
//* leading and trailing items from a string
//*
//* --- stripItem
//*
//* Strip leading and trailing items from a container
//* template parameters are the container type, and a function which returns
//* true if we have the value to strip
//*
//*
//* ---- stripChar
//* strips characters off a string by either a function (which returns
//* true if the character is found), or by an actual character mathc.
//* There are also forms for wide strings
//*
//* ---- stripWhitespace
//* removes leading and trailing spaces from a string using isspace()
//*************************************************************************
template <typename S,typename F>
S stripItem(const S &s,F func,bool stripLeading = true, bool stripTrailing = true)
{
typename S::const_iterator leftit = s.begin();
typename S::const_reverse_iterator rightit = s.rbegin();
if (s.length() < 1 )
return s;
if (stripLeading)
{
while (leftit != s.end() && func(*leftit))
{
++leftit;
}
}
if (leftit == s.end()) return S();
if (stripTrailing)
{
while (rightit != s.rend() && func(*rightit))
{
++rightit;
}
}
if (rightit == s.rend()) return S();
typename S::const_iterator endpnt = (++rightit).base();
if (leftit > endpnt)
return S();
return s.substr( (leftit - s.begin()) ,(endpnt-leftit) +1);
}
template<typename S,typename FUNC>
S stripChar(const S &s,FUNC f,bool stripLeading = true,bool stripTrailing = true)
{ return stripItem(s,f,stripLeading,stripTrailing); }
template<typename S>
inline S stripChar(const S &s,typename S::value_type c,bool stripLeading = true,bool stripTrailing = true)
{ return stripItem(s,bind1st(std::equal_to<typename S::value_type>(),c),stripLeading,stripTrailing); }
template<typename S>
bool myspace(S c) { return safe_is_space(c); }
template<typename S>
inline S stripWhitespace(const S &s) { return stripChar(s,stringUtil::myspace<typename S::value_type>); }
template<typename S>
bool myalphadigit(S c) { return !(safe_is_alpha(c) || safe_is_digit(c)); }
template<typename S>
inline S stripAlphaDigit(const S &s) { return stripChar(s,stringUtil::myalphadigit<typename S::value_type>); }
//*****************************************************************
//* tokenizer
//*
//* break up a string into substrings based on a delimiter item.
//******************************************************************
template<typename S,typename F>
std::vector<S> tokenizer_if(const S &ins,F isdelimiter) throw()
{
std::vector<S> result;
S accum;
for (typename S::const_iterator i = ins.begin(); i != ins.end(); ++i)
{
if (!isdelimiter(*i))
{
accum.push_back(*i);// was +=
}
else
{
if (!accum.empty())
{
result.push_back(accum);
accum = S();
}
}
}
if (!accum.empty())
{
result.push_back(accum);
}
return result;
}
template<typename S>
inline std::vector<S> tokenizer(const S &ins,typename S::value_type delim) throw()
{ return tokenizer_if(ins,bind1st(std::equal_to<typename S::value_type>(),delim)); }
inline std::string escapeBackslashes(const std::string &s) throw()
{
std::string result;
for (std::string::const_iterator i = s.begin(); i != s.end(); ++i)
{
result += (*i);
if ((*i) == '\\')
result += (*i);
}
return result;
}
//////////////////////////////////////////////////////////////////////////
}
#endif