/* * Copyright 2013-2020, Corvusoft Ltd, All Rights Reserved. */ //System Includes #include #include #include #include //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; } }