fileserver/lib/restbed-4.8/source/corvusoft/restbed/string.cpp

179 lines
4.7 KiB
C++

/*
* Copyright 2013-2020, Corvusoft Ltd, All Rights Reserved.
*/
//System Includes
#include <regex>
#include <memory>
#include <ciso646>
#include <algorithm>
//Project Includes
#include "corvusoft/restbed/string.hpp"
//External Includes
//System Namespaces
using std::regex;
using std::string;
using std::vector;
using std::smatch;
using std::multimap;
using std::transform;
using std::unique_ptr;
using std::regex_match;
using std::regex_replace;
using std::regex_constants::icase;
//Project Namespaces
//External Namespaces
namespace restbed
{
const string String::empty = "";
Bytes String::to_bytes( const string& value )
{
return Bytes( value.begin( ), value.end( ) );
}
string String::to_string( const Bytes& value )
{
return string( value.begin( ), value.end( ) );
}
string String::lowercase( const string& value )
{
string result = "";
transform( value.begin( ), value.end( ), back_inserter( result ), [ ]( const char value ) { return static_cast< char >( tolower( value ) ); } );
return result;
}
string String::uppercase( const string& value )
{
string result = "";
transform( value.begin( ), value.end( ), back_inserter( result ), [ ]( const char value ) { return static_cast< char >( toupper( value ) ); } );
return result;
}
string String::format( const char* format, ... )
{
va_list arguments;
va_start( arguments, format );
string formatted = "";
string::size_type length = FORMAT_BUFFER_INITIAL_LENGTH;
string::size_type required_length = String::format( formatted, length, format, arguments );
va_end( arguments );
if ( required_length > length )
{
va_start( arguments, format );
String::format( formatted, required_length, format, arguments );
va_end( arguments );
}
return formatted;
}
vector< string > String::split( const string& value, const char delimiter )
{
vector< string > tokens;
string::size_type start = 0;
string::size_type end = 0;
while ( ( end = value.find( delimiter, start ) ) not_eq string::npos )
{
const auto text = value.substr( start, end - start );
if ( not text.empty( ) )
{
tokens.push_back( text );
}
start = end + 1;
}
const auto token = value.substr( start );
if ( not token.empty( ) )
{
tokens.push_back( token );
}
return tokens;
}
string String::join( const multimap< string, string >& values, const string& pair_delimiter, const string& delimiter )
{
string result = "";
for ( auto value : values )
{
result += value.first + pair_delimiter + value.second + delimiter;
}
if ( not result.empty( ) )
{
const size_t position = result.find_last_not_of( delimiter );
if ( string::npos not_eq position )
{
result = result.substr( 0, position + 1 );
}
}
return result;
}
string String::remove( const string& target, const string& value, const Option option )
{
return replace( target, "", value, option );
}
string String::replace( const string& target, const string& substitute, const string& value, const Option option )
{
if ( target.empty( ) )
{
return value;
}
static const regex escape( "([.^$|()\\[\\]{}*+?\\\\])" );
const auto expression = regex_replace( target, escape, "\\$1" );
auto pattern = regex( expression );
if ( option & String::Option::CASE_INSENSITIVE )
{
pattern.assign( expression, icase );
}
smatch match;
string result = value;
while ( regex_search( result, match, pattern ) )
{
result = regex_replace( result, pattern, substitute );
}
return result;
}
string::size_type String::format( string& output, const string::size_type length, const char* format, va_list arguments )
{
unique_ptr< char[ ] > formatted( new char[ length + 1 ] );
int required_length = vsnprintf( formatted.get( ), length + 1, format, arguments );
if ( required_length == -1 )
{
required_length = 0;
}
output = formatted.get( );
return required_length;
}
}