2013-11-06 22:52:00 +01:00
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Utility Collection of Miscellanious Handy Functions
|
|
|
|
|
// <20> Dan Andersson 2013
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#include "Utilities.h"
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
using ::std::vector;
|
|
|
|
|
using ::std::string;
|
2013-11-09 23:36:38 +01:00
|
|
|
|
using ::std::wstring;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
|
|
|
|
namespace Utility
|
|
|
|
|
{
|
|
|
|
|
// PRIVATE STATIC ////////////////////////////////////////////////////
|
|
|
|
|
namespace PrivateStatic
|
|
|
|
|
{
|
2013-11-09 23:36:38 +01:00
|
|
|
|
const ::std::locale system_default_locale = ::std::locale();
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// STRING ////////////////////////////////////////////////////////////
|
|
|
|
|
namespace String
|
|
|
|
|
{
|
2013-11-09 23:36:38 +01:00
|
|
|
|
// string
|
|
|
|
|
|
|
|
|
|
vector<string> & Split( vector<string> &output, const string &str, char delim, string::size_type offset )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
if( str.length() > 0 )
|
|
|
|
|
{
|
|
|
|
|
while( offset < str.length() ) // trim
|
|
|
|
|
{
|
|
|
|
|
if( str[offset] == delim )
|
|
|
|
|
++offset;
|
|
|
|
|
else break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string::size_type delimPos = str.find_first_of( delim, offset );
|
|
|
|
|
if( delimPos == string::npos )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > offset )
|
|
|
|
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( delimPos > offset )
|
|
|
|
|
output.push_back( str.substr( offset, delimPos - offset ) );
|
2013-11-09 23:36:38 +01:00
|
|
|
|
String::Split( output, str, delim, delimPos + 1 );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
vector<string> & Split( vector<string> &output, const string &str, const string &delim, string::size_type offset )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
if( str.length() > 0 )
|
|
|
|
|
{
|
|
|
|
|
string::size_type delimPos = str.find_first_of( delim, offset );
|
|
|
|
|
if( delimPos == string::npos )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > offset )
|
|
|
|
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( delimPos > offset )
|
|
|
|
|
output.push_back( str.substr( offset, delimPos - offset ) );
|
2013-11-09 23:36:38 +01:00
|
|
|
|
String::Split( output, str, delim, delimPos + delim.length() );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
vector<string> & Split( vector<string> &output, const string &str, const vector<string> &delim, string::size_type offset )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
if( str.length() > 0 )
|
|
|
|
|
{
|
|
|
|
|
string::size_type firstDelimPos = str.length(), delimPos;
|
|
|
|
|
|
|
|
|
|
vector<string>::size_type numDelims = delim.size(), delimRef = 0;
|
|
|
|
|
for( vector<string>::size_type i = 0; i < numDelims ; ++i )
|
|
|
|
|
{
|
|
|
|
|
delimPos = str.find_first_of( delim[i], offset );
|
|
|
|
|
if( delimPos != string::npos ) if( delimPos < firstDelimPos )
|
|
|
|
|
{
|
|
|
|
|
delimRef = i;
|
|
|
|
|
firstDelimPos = delimPos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( firstDelimPos == str.length() )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > offset )
|
|
|
|
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( firstDelimPos > offset )
|
|
|
|
|
output.push_back( str.substr( offset, firstDelimPos - offset ) );
|
2013-11-09 23:36:38 +01:00
|
|
|
|
String::Split( output, str, delim, firstDelimPos + delim[delimRef].length() );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string Trim( const string &str )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
string::size_type first = 0,
|
|
|
|
|
last = str.length();
|
|
|
|
|
|
|
|
|
|
if( last == 0 ) return str;
|
|
|
|
|
|
|
|
|
|
while( first < last )
|
|
|
|
|
{
|
|
|
|
|
if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
|
|
|
|
|
++first;
|
|
|
|
|
else break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
--last;
|
|
|
|
|
while( last > first )
|
|
|
|
|
{
|
|
|
|
|
if( str[last] == ' ' || str[last] == '\t' || str[last] == '\r' || str[last] == '\n' )
|
|
|
|
|
--last;
|
|
|
|
|
else break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( first == last ) if( str[first] == ' ' || str[first] == '\t' || str[first] == '\r' || str[first] == '\n' )
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
return str.substr( first, (++last) - first );
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ToLowerCase( string &output, const string &str )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
int length = (int)str.length();
|
|
|
|
|
output.resize( length );
|
|
|
|
|
for( int i = 0; i < length; ++i )
|
|
|
|
|
output[i] = ::std::tolower( str[i], ::std::locale() );
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ToLowerCase( string &str )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
int length = (int)str.length();
|
|
|
|
|
for( int i = 0; i < length; ++i )
|
|
|
|
|
str[i] = ::std::tolower( str[i], ::std::locale() );
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ToUpperCase( string &output, const string &str )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
int length = (int)str.length();
|
|
|
|
|
output.resize( length );
|
|
|
|
|
for( int i = 0; i < length; ++i )
|
|
|
|
|
output[i] = ::std::toupper( str[i], ::std::locale() );
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ToUpperCase( string &str )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
int length = (int)str.length();
|
|
|
|
|
for( int i = 0; i < length; ++i )
|
|
|
|
|
str[i] = ::std::toupper( str[i], ::std::locale() );
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ExtractDirPath( string &output, const string &file, char dirDelimeter )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
string d = " ";
|
|
|
|
|
d[0] = dirDelimeter;
|
2013-11-09 23:36:38 +01:00
|
|
|
|
return String::ExtractDirPath( output, file, d );
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ExtractDirPath( string &output, const string &file, const string &dirDelimeter )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
string::size_type end = file.find_last_of( dirDelimeter );
|
|
|
|
|
if( end == string::npos )
|
|
|
|
|
output = "";
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
++end;
|
|
|
|
|
output.resize( end );
|
|
|
|
|
for( string::size_type i = 0; i < end; ++i )
|
|
|
|
|
output[i] = file[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-09 23:36:38 +01:00
|
|
|
|
string & ReplaceCharacters( string &str, char characterToReplace, char newCharacter, const string::size_type &offset, const string::size_type &end )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
string::size_type i = offset;
|
|
|
|
|
while( true )
|
|
|
|
|
{
|
|
|
|
|
i = str.find_first_of( characterToReplace, i );
|
|
|
|
|
if( i >= end ) break;
|
|
|
|
|
|
|
|
|
|
str[i++] = newCharacter;
|
|
|
|
|
}
|
|
|
|
|
return str;
|
|
|
|
|
}
|
2013-11-09 23:36:38 +01:00
|
|
|
|
|
|
|
|
|
// wstring
|
|
|
|
|
|
|
|
|
|
vector<wstring> & Split( vector<wstring> &output, const wstring &str, char delim, wstring::size_type offset )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > 0 )
|
|
|
|
|
{
|
|
|
|
|
while( offset < str.length() ) // trim
|
|
|
|
|
{
|
|
|
|
|
if( str[offset] == delim )
|
|
|
|
|
++offset;
|
|
|
|
|
else break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wstring::size_type delimPos = str.find_first_of( delim, offset );
|
|
|
|
|
if( delimPos == wstring::npos )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > offset )
|
|
|
|
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( delimPos > offset )
|
|
|
|
|
output.push_back( str.substr( offset, delimPos - offset ) );
|
|
|
|
|
String::Split( output, str, delim, delimPos + 1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector<wstring> & Split( vector<wstring> &output, const wstring &str, const wstring &delim, wstring::size_type offset )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > 0 )
|
|
|
|
|
{
|
|
|
|
|
wstring::size_type delimPos = str.find_first_of( delim, offset );
|
|
|
|
|
if( delimPos == wstring::npos )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > offset )
|
|
|
|
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( delimPos > offset )
|
|
|
|
|
output.push_back( str.substr( offset, delimPos - offset ) );
|
|
|
|
|
String::Split( output, str, delim, delimPos + delim.length() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vector<wstring> & Split( vector<wstring> &output, const wstring &str, const vector<wstring> &delim, wstring::size_type offset )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > 0 )
|
|
|
|
|
{
|
|
|
|
|
wstring::size_type firstDelimPos = str.length(), delimPos;
|
|
|
|
|
|
|
|
|
|
vector<wstring>::size_type numDelims = delim.size(), delimRef = 0;
|
|
|
|
|
for( vector<wstring>::size_type i = 0; i < numDelims ; ++i )
|
|
|
|
|
{
|
|
|
|
|
delimPos = str.find_first_of( delim[i], offset );
|
|
|
|
|
if( delimPos != wstring::npos ) if( delimPos < firstDelimPos )
|
|
|
|
|
{
|
|
|
|
|
delimRef = i;
|
|
|
|
|
firstDelimPos = delimPos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( firstDelimPos == str.length() )
|
|
|
|
|
{
|
|
|
|
|
if( str.length() > offset )
|
|
|
|
|
output.push_back( str.substr( offset, str.length() - offset ) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( firstDelimPos > offset )
|
|
|
|
|
output.push_back( str.substr( offset, firstDelimPos - offset ) );
|
|
|
|
|
String::Split( output, str, delim, firstDelimPos + delim[delimRef].length() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-06 22:52:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// STREAM ////////////////////////////////////////////////////////////
|
|
|
|
|
namespace Stream
|
|
|
|
|
{
|
2013-11-09 23:36:38 +01:00
|
|
|
|
float* ReadFloats( float *output, ::std::istream &input, unsigned int numFloats )
|
2013-11-06 22:52:00 +01:00
|
|
|
|
{
|
|
|
|
|
string str;
|
|
|
|
|
for( unsigned int i = 0; i < numFloats; ++i )
|
|
|
|
|
{
|
|
|
|
|
input >> str;
|
|
|
|
|
output[i] = (float)::std::atof( str.c_str() );
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|