/* $Revision: 27 $ $Date: 25/07/06 17:37 $ Copyright © 1999-2006, FSL Technologies Limited. Contact "http://fost3.fsltech.com". */ #include "stdafx.h" #include #include using namespace FSLib; namespace { FSLib::Revision c_revision( L"$Archive: /FOST.3/F3Util/string.cpp $", __DATE__, L"$Revision: 27 $", L"$Date: 25/07/06 17:37 $" ); FSLib::string substring( const FSLib::string &text, FSLib::string::size_type start, FSLib::string::size_type end ) { if ( end == std::string::npos ) { return text.substr( start ); } else { return text.substr( start, end - start ); } } FSLib::wstring substring( const FSLib::wstring &text, FSLib::wstring::size_type start, FSLib::wstring::size_type end ) { if ( end == std::wstring::npos ) { return text.substr( start ); } else { return text.substr( start, end - start ); } } const char *c_whitespace_utf8 = " \n\r\t"; const wchar_t *c_whitespace_utf16 = L" \n\r\t"; } inline FSLib::string FSLib::trim( const FSLib::string &text ) { if ( text.size() == 0 ) return text; FSLib::string::size_type end = text.find_last_not_of( c_whitespace_utf8 ); if ( end == std::string::npos ) { return text.substr( text.find_first_not_of( c_whitespace_utf8) ); } else { return substring( text, text.find_first_not_of( c_whitespace_utf8 ), end + 1 ); } } inline FSLib::Nullable< FSLib::string > FSLib::trim( const FSLib::Nullable< FSLib::string > &text ) { if ( text.isnull() ) { return Null; } else { return trim( text.value() ); } } inline FSLib::wstring FSLib::trim( const FSLib::wstring &text ) { if ( text.size() == 0 ) return text; FSLib::wstring::size_type end = text.find_last_not_of( c_whitespace_utf16 ); if ( end == std::wstring::npos ) { return text.substr( text.find_first_not_of( c_whitespace_utf16 ) ); } else { return substring( text, text.find_first_not_of( c_whitespace_utf16 ), end + 1 ); } } inline FSLib::Nullable< FSLib::wstring > FSLib::trim( const FSLib::Nullable< FSLib::wstring > &text ) { if ( text.isnull() ) { return Null; } else { return trim( text.value() ); } } inline FSLib::wstring FSLib::widen( const FSLib::string &str ) { return FSLib::wstring( reinterpret_cast< const utf8 * >( str.c_str() ) ); } inline FSLib::string FSLib::narrow( const FSLib::wstring &str ) { FSLib::string ret; ret.reserve( str.length() * 2 ); try { utf8 buffer[ utf::utf32_utf8_max_length ]; for ( FSLib::wstring::const_iterator it( str.begin() ); it != str.end(); ++it ) { utf32 c( *it ); try { ret.append( buffer, buffer + utf::encode( c, buffer, buffer + utf::utf32_utf8_max_length ) ); } catch ( FSLib::Exceptions::Exception &e ) { e.info() << L"Character: " << toString( unsigned int( c ) ) << std::endl; throw; } } } catch ( FSLib::Exceptions::Exception &e ) { e.info() << L"Narrowed sequence: " << widen( ret ) << std::endl; throw; } return ret; } inline FSLib::wstring FSLib::guid() { GUID g; if ( CoCreateGuid( &g ) == S_OK ) { wchar_t *guid; if ( UuidToString( &g, reinterpret_cast< unsigned short ** >( &guid ) ) == RPC_S_OK ) { FSLib::wstring val = guid; RpcStringFree( reinterpret_cast< unsigned short ** >( &guid ) ); return val; } else { throw Exceptions::ComError( L"UuidToString failed whilst trying to create a GUID" ); } } else { throw Exceptions::ComError( L"CoCreateGUID failed whilst trying to create a GUID" );; } } inline FSLib::string FSLib::replaceAll( const FSLib::string &text, const FSLib::string &what, const FSLib::string &with ) { FSLib::string ret = text; for ( FSLib::string::size_type p( ret.find( what ) ); p != std::string::npos; p = ret.find( what, p + with.length() ) ) { ret = ret.substr( 0, p ) + with + ret.substr( p + what.length() ); } return ret; } inline FSLib::string FSLib::replaceAll( const FSLib::string &text, const FSLib::string &findThis, const FSLib::Nullable< FSLib::string > &replaceWith ) { if ( replaceWith.isnull() ) { return replaceAll( text, findThis, FSLib::string() ); } else { return replaceAll( text, findThis, replaceWith.value() ); } } inline FSLib::wstring FSLib::replaceAll( const FSLib::wstring &text, const FSLib::wstring &what, const FSLib::wstring &with ) { FSLib::wstring ret = text; for ( FSLib::wstring::size_type p( ret.find( what ) ); p != std::wstring::npos; p = ret.find( what, p + with.length() ) ) { ret = ret.substr( 0, p ) + with + ret.substr( p + what.length() ); } return ret; } inline FSLib::wstring FSLib::replaceAll( const FSLib::wstring &text, const FSLib::wstring &findThis, const FSLib::Nullable< FSLib::wstring > &replaceWith ) { if ( replaceWith.isnull() ) { return replaceAll( text, findThis, FSLib::wstring() ); } else { return replaceAll( text, findThis, replaceWith.value() ); } } inline std::pair< FSLib::string, Nullable< FSLib::string > > FSLib::partition( const FSLib::string &text, const FSLib::string &bound ) { FSLib::string first; Nullable< FSLib::string > second; FSLib::string::size_type start = text.find( bound ); if ( start == std::string::npos ) { first = trim( text ); } else { first = trim( substring( text, 0, start ) ); second = trim( substring( text, start + bound.size(), std::wstring::npos ) ); } return make_pair( first, second ); } inline std::pair< FSLib::string, Nullable< FSLib::string > > FSLib::partition( const Nullable< FSLib::string > &text, const FSLib::string &bound ) { if ( text.isnull() ) return std::make_pair( FSLib::string(), Null ); else return partition( text.value(), bound ); } inline std::pair< FSLib::string, Nullable< FSLib::string > > FSLib::partition( const FSLib::string &text ) { FSLib::string first; Nullable< FSLib::string > second; FSLib::string::size_type start = text.find_first_of( c_whitespace_utf8 ); if ( start == std::string::npos ) { first = trim( text ); } else { first = trim( substring( text, 0, start ) ); second = trim( substring( text, start + 1, std::string::npos ) ); } return std::make_pair( first, second ); } inline std::pair< FSLib::string, Nullable< FSLib::string > > FSLib::partition( const Nullable< FSLib::string > &text ) { if ( text.isnull() ) return std::make_pair( FSLib::string(), Null ); else return partition( text.value() ); } inline std::pair< FSLib::wstring, Nullable< FSLib::wstring > > FSLib::partition( const FSLib::wstring &text, const FSLib::wstring &bound ) { FSLib::wstring first; Nullable< FSLib::wstring > second; FSLib::wstring::size_type start = text.find( bound ); if ( start == std::wstring::npos ) { first = trim( text ); } else { first = trim( substring( text, 0, start ) ); second = trim( substring( text, start + bound.size(), std::wstring::npos ) ); } return make_pair( first, second ); } inline std::pair< FSLib::wstring, Nullable< FSLib::wstring > > FSLib::partition( const Nullable< FSLib::wstring > &text, const FSLib::wstring &bound ) { if ( text.isnull() ) return std::make_pair( FSLib::wstring(), Null ); else return partition( text.value(), bound ); } inline std::pair< FSLib::wstring, Nullable< FSLib::wstring > > FSLib::partition( const FSLib::wstring &text ) { FSLib::wstring first; Nullable< FSLib::wstring > second; FSLib::wstring::size_type start = text.find_first_of( c_whitespace_utf16 ); if ( start == std::wstring::npos ) { first = trim( text ); } else { first = trim( substring( text, 0, start ) ); second = trim( substring( text, start + 1, std::wstring::npos ) ); } return std::make_pair( first, second ); } inline std::pair< FSLib::wstring, Nullable< FSLib::wstring > > FSLib::partition( const Nullable< FSLib::wstring > &text ) { if ( text.isnull() ) return std::make_pair( FSLib::wstring(), Null ); else return partition( text.value() ); } inline std::pair< FSLib::wstring, Nullable< FSLib::wstring > > FSLib::crack( const FSLib::wstring &text, const FSLib::wstring &open, const FSLib::wstring &close ) { FSLib::wstring nut = trim( text ); FSLib::wstring::size_type spos = nut.find( open ); if ( spos == std::wstring::npos ) { return std::make_pair( nut, Null ); } else { FSLib::wstring::size_type epos = nut.find( close, spos + open.length() ); if ( epos == std::wstring::npos ) { return std::make_pair( nut, Null ); } else { if ( open != close ) { FSLib::wstring::size_type mpos = nut.find( open, spos + open.length() ); while ( mpos <= epos ) { epos = nut.find( close, epos + close.length() ); mpos = nut.find( open, mpos + open.length() ); } } return std::make_pair( trim( substring( nut, 0, spos ) ), trim( substring( nut, spos + open.length(), epos ) ) ); } } } /* FSLib::wstring Constructors */ FSLib::wstring::wstring() : m_utf16( 0 ), m_utf32( 0 ), m_buffer( 0 ) { } FSLib::wstring::wstring( const utf8 *utf8Sequence ) : m_utf16( 0 ), m_utf32( 0 ), m_buffer( 0 ) { assign( utf8Sequence ); } FSLib::wstring::wstring( const utf16 *utf16Sequence ) : m_utf16( 0 ), m_utf32( 0 ), m_buffer( 0 ) { assign( utf16Sequence ); } FSLib::wstring::wstring( const std::wstring &str ) : m_utf16( 0 ), m_utf32( 0 ), m_buffer( 0 ) { assign( str.c_str() ); } FSLib::wstring::wstring( const wstring &s ) : m_utf16( s.m_utf16 ), m_utf32( s.m_utf32 ), m_buffer( s.m_buffer ), m_string( s.m_string.get() ? new wchar_t[ s.m_buffer ] : NULL ) { if ( s.m_string.get() ) std::memcpy( m_string.get(), s.m_string.get(), sizeof( utf16 ) * ( m_utf16 + 1 ) ); } FSLib::wstring::wstring( const wstring &str, size_type off, size_type count ) : m_utf16( 0 ), m_utf32( 0 ), m_buffer( 0 ) { if ( count ) { if ( str.m_utf16 == str.m_utf32 ) { if ( off < str.m_utf16 ) { size_type len( std::min( str.m_utf16 - off, count ) ); grow( len, false ); ::memcpy( m_string.get(), str.m_string.get() + off, len * sizeof( utf16 ) ); m_string[ len ] = 0; m_utf16 = len; m_utf32 = len; } } else assign( str.offset( off ), str.end(), count ); } } FSLib::wstring::wstring( size_type count, utf32 ch ) : m_utf16( 0 ), m_utf32( 0 ), m_buffer( 0 ) { assign( ch, count ); } FSLib::wstring::~wstring() { } /* FSLib::wstring Conversions */ const wchar_t *FSLib::wstring::c_str() const { static const wchar_t *c_empty = L""; if ( m_string.get() ) return m_string.get(); else return c_empty; } std::wstring FSLib::wstring::std_str() const { return std::wstring( c_str() ); } /* FSLib::wstring Operators */ bool FSLib::wstring::operator ==( const wstring &rhs ) const { return ::wcscmp( c_str(), rhs.c_str() ) == 0; } bool FSLib::wstring::operator ==( const utf16 *seq ) const { return ::wcscmp( c_str(), seq ) == 0; } bool FSLib::wstring::operator <( const wstring &rhs ) const { const_iterator l = begin(), r = rhs.begin(); while ( l != end() && r != rhs.end() ) { if ( *l < *r ) return true; else if ( *l > *r ) return false; ++l; ++r; } return l == end() && r != rhs.end(); } bool FSLib::wstring::operator <( const utf16 *seq ) const { return *this < wstring( seq ); } bool FSLib::wstring::operator >( const wstring &rhs ) const { const_iterator l = begin(), r = rhs.begin(); while ( l != end() && r != rhs.end() ) { if ( *l > *r ) return true; else if ( *l < *r ) return false; ++l; ++r; } return l != end() && r == rhs.end(); } bool FSLib::wstring::operator >( const utf16 *seq ) const { return *this > wstring( seq ); } wstring FSLib::wstring::operator +( const wstring &s ) const { return wstring( *this ) += s; } wstring FSLib::wstring::operator +( const wchar_t *utf16Sequence ) const { return wstring( *this ) += utf16Sequence; } wstring FSLib::wstring::operator +( const utf32 ch ) const { return wstring( *this ) += ch; } wstring &FSLib::wstring::operator =( const wstring &str ) { if ( str.empty() ) { clear(); } else if ( this != &str ) { boost::scoped_array< utf16 > nbuf( new utf16[ str.m_buffer ] ); std::memcpy( nbuf.get(), str.m_string.get(), sizeof( utf16 ) * ( str.m_utf16 + 1 ) ); m_string.swap( nbuf ); m_buffer = str.m_buffer; m_utf16 = str.m_utf16; m_utf32 = str.m_utf32; } return *this; } wstring &FSLib::wstring::operator =( const wchar_t *utf16Sequence ) { return assign( utf16Sequence ); } wstring &FSLib::wstring::operator =( const utf32 ch ) { return assign( ch, 1 ); } wstring &FSLib::wstring::operator +=( const wstring &str ) { if ( !str.empty() ) { grow( m_utf16 + str.m_utf16, true ); std::memcpy( m_string.get() + m_utf16, str.m_string.get(), sizeof( utf16 ) * ( str.m_utf16 + 1 ) ); m_utf16 += str.m_utf16; m_utf32 += str.m_utf32; } return *this; } wstring &FSLib::wstring::operator +=( const wchar_t *utf16Sequence ) { wstring s( utf16Sequence ); return *this += s; } wstring &FSLib::wstring::operator +=( const utf32 ch ) { size_type l = utf::utf16length( ch ); grow( m_utf16 + l, true ); utf::encode( ch, m_string.get() + m_utf16, m_string.get() + m_utf16 + l + 1 ); m_utf16 += l; m_utf32 += 1; m_string[ m_utf16 ] = 0; return *this; } /* FSLib::wstring Accessors */ utf32 FSLib::wstring::at( size_type pos ) const { return *( offset( pos ) ); } /* FSLib::wstring::const_iterator */ inline FSLib::wstring::const_iterator &FSLib::wstring::const_iterator::operator++() { utf32 ch = **this; if ( ch != 0 ) m_pointer += utf::utf16length( ch ); return *this; } inline FSLib::wstring::const_iterator &FSLib::wstring::const_iterator::operator +=( size_type off ) { for ( size_type c( 0 ); **this != 0 && c != off; ++c ) ++(*this); return *this; } FSLib::wstring::const_iterator FSLib::wstring::offset( size_type off ) const { if ( m_utf16 == m_utf32 ) return m_string.get() + off; else return begin() + off; } /* FSLib::wstring Members */ wstring &FSLib::wstring::assign( const utf8 *seq ) { if ( seq ) { grow( utf::length( seq ), false ); m_utf16 = m_utf32 = 0; for ( utf16 *pos = m_string.get(); *seq != 0; ) { utf32 ch; try { ch = utf::decode( seq ); } catch ( FSLib::Exceptions::Exception &e ) { m_string[ m_utf16 ] = 0; e.info() << L"Function: FSLib::wstring &FSLib::wstring::assign( const FSLib::utf8 *seq ) at utf::decode" << std::endl; e.info() << L"UTF-8 values: " << unsigned int( seq[ 0 ] ) << L" : " << unsigned int( seq[ 1 ] ) << L" : " << unsigned int( seq[ 2 ] ) << L" : " << unsigned int( seq[ 3 ] ) << std::endl; e.info() << L"Decoded string: " << m_string << std::endl; throw; } utf::encode( ch, pos, pos + 3 ); pos += utf::utf16length( ch ); seq += utf::utf8length( ch ); m_utf16 += utf::utf16length( ch ); m_utf32 += 1; } m_string[ m_utf16 ] = 0; } else clear(); return *this; } wstring &FSLib::wstring::assign( const utf16 *seq ) { if ( seq ) { grow( utf::length( seq ), false ); m_utf16 = m_utf32 = 0; for ( utf16 *pos = m_string.get(); *seq != 0; ) { utf32 ch = utf::decode( seq ); utf::encode( ch, pos, pos + 3 ); pos += utf::utf16length( ch ); seq += utf::utf16length( ch ); m_utf16 += utf::utf16length( ch ); m_utf32 += 1; } m_string[ m_utf16 ] = 0; } else clear(); return *this; } wstring &FSLib::wstring::assign( const utf32 ch, size_type count ) { utf16 codes[ 2 ]; utf::encode( ch, codes, codes + 3 ); size_type used = utf::utf16length( ch ); grow( used * count, false ); for ( size_type c( 0 ); c != count; ++c ) { std::memcpy( m_string.get() + ( used * c ), codes, sizeof( utf16 ) * used ); } m_utf16 = count * used; m_utf32 = count; m_string[ m_utf16 ] = 0; return *this; } wstring &FSLib::wstring::assign( const_iterator pos, const_iterator end, size_type max ) { clear(); for ( size_type c( 0 ); pos != end && c != max; ++pos, ++c ) { *this += *pos; } return *this; } void FSLib::wstring::clear() { m_utf16 = 0; m_utf32 = 0; if ( m_string.get() ) m_string[ 0 ] = 0; } FSLib::wstring &FSLib::wstring::erase( size_type pos, size_type count ) { return *this = substr( 0, pos ) + substr( pos + count ); } FSLib::wstring::size_type FSLib::wstring::find( const utf16 *utf16Sequence, size_type off ) const { if ( empty() ) return std::wstring::npos; const utf16 *f = ::wcsstr( ( offset( off ) ).get(), utf16Sequence ); if ( f == NULL ) return std::wstring::npos; else return utf::length( m_string.get(), f ); } FSLib::wstring::size_type FSLib::wstring::find( const utf32 ch, size_type off ) const { utf16 buf[ 3 ] = { 0, 0, 0 }; utf::encode( ch, buf, buf + 3 ); return find( buf, off ); } FSLib::wstring::size_type FSLib::wstring::rfind( const utf16 *seq, size_type off ) const { if ( empty() ) return std::wstring::npos; utf16 *f = ::wcsstr( m_string.get(), seq ); if ( f == NULL ) return std::wstring::npos; size_type ret = utf::length( m_string.get(), f ); if ( ret >= off ) return std::wstring::npos; size_type u16len = utf::utf16length( seq ); for ( utf16 *n = ::wcsstr( f + u16len, seq ); n != NULL; n = ::wcsstr( n + u16len, seq ) ) { size_type clen = utf::length( m_string.get(), n ); if ( clen >= off ) return ret; else ret = clen; } return ret; } FSLib::wstring::size_type FSLib::wstring::find_first_of( const utf16 *seq, size_type off ) const { size_type p( off ); for ( const_iterator it( offset( off ) ); it != end(); ++it, ++p ) { utf16 buf[ 3 ] = { 0, 0, 0 }; utf::encode( *it, buf, buf + 3 ); if ( ::wcsstr( seq, buf ) != NULL ) return p; } return std::wstring::npos; } FSLib::wstring::size_type FSLib::wstring::find_first_not_of( const utf16 *seq, size_type off ) const { size_type p( off ); for ( const_iterator it( offset( off ) ); it != end(); ++it, ++p ) { utf16 buf[ 3 ] = { 0, 0, 0 }; utf::encode( *it, buf, buf + 3 ); if ( ::wcsstr( seq, buf ) == NULL ) return p; } return std::wstring::npos; } FSLib::wstring::size_type FSLib::wstring::find_first_not_of( const utf32 ch, size_type off ) const { size_type p( off ); for ( const_iterator it( offset( off ) ); it != end(); ++it, ++p ) if ( *it != ch ) return p; return std::wstring::npos; } FSLib::wstring::size_type FSLib::wstring::find_last_of( const utf16 *seq, size_type final ) const { size_type r( std::wstring::npos ); for ( size_type p( find_first_of( seq ) ); p != std::wstring::npos && p < final; p = find_first_of( seq, p + 1 ) ) r = p; return r; } FSLib::wstring::size_type FSLib::wstring::find_last_of( const utf32 ch, size_type final ) const { size_type p( 0 ), r( std::wstring::npos ); for ( const_iterator it( begin() ); it != end() && p < final; ++it, ++p ) if ( *it == ch ) r = p; return r; } FSLib::wstring::size_type FSLib::wstring::find_last_not_of( const utf16 *seq, size_type final ) const { size_type p( 0 ), r( std::wstring::npos ); for ( const_iterator it( begin() ); it != end() && p < final; ++p, ++it ) { utf16 buf[ 3 ] = { 0, 0, 0 }; utf::encode( *it, buf, buf + 3 ); if ( ::wcsstr( seq, buf ) == NULL ) r = p; } return r; } FSLib::wstring::size_type FSLib::wstring::find_last_not_of( const utf32 ch, size_type final ) const { size_type p( 0 ), r( std::wstring::npos ); for ( const_iterator it( begin() ); it != end() && p < final; ++p, ++it ) { if ( *it != ch ) r = p; } return r; } wstring &FSLib::wstring::insert( size_type off, const wstring &str, size_type pos, size_type count ) { return *this = substr( 0, off ) + str.substr( pos, count ) + substr( off ); } wstring &FSLib::wstring::replace( size_type off, size_type count, const wchar_t *utf16Sequence ) { return *this = substr( 0, off ) + wstring( utf16Sequence ) + substr( off + count ); } wstring &FSLib::wstring::replace( size_type pos, size_type count, const wstring &str, size_type pos2, size_type count2 ) { return *this = substr( 0, pos ) + str.substr( pos2, count2 ) + substr( pos + count ); } /* FSLib::wstring Members */ void FSLib::wstring::grow( size_type nsize, bool preserve ) { if ( m_buffer > nsize ) return; if ( nsize < 64 ) nsize = 64; else if ( nsize < 128 ) nsize = 128; else if ( nsize < 256 ) nsize = 256; else if ( nsize < 512 ) nsize = 512; else nsize += nsize / 2; boost::scoped_array< wchar_t > nbuf( new wchar_t[ nsize ] ); if ( preserve ) { #ifdef _DEBUG if ( nbuf.get() == NULL ) throw FSLib::Exceptions::Null( L"FSLib::wstring::grow() - nbuf is NULL and new[] didn't throw an exception" ); #endif if ( m_string.get() ) std::memcpy( nbuf.get(), m_string.get(), sizeof( utf16 ) * ( m_utf16 + 1 ) ); else nbuf[ 0 ] = 0; } else { m_utf16 = 0; m_utf32 = 0; nbuf[ 0 ] = 0; } m_string.swap( nbuf ); m_buffer = nsize; } /* Misc string operators */ /* $History: string.cpp $ * * ***************** Version 27 ***************** * User: Kirit Date: 25/07/06 Time: 17:37 * Updated in $/FOST.3/F3Util * Debugged find_last_of where the last occurance is at position 0. * * ***************** Version 26 ***************** * User: Kirit Date: 28/06/06 Time: 20:55 * Updated in $/FOST.3/F3Util * Some small improvements. Don't seem to make much difference to the * speed though. * * ***************** Version 25 ***************** * User: Kirit Date: 28/06/06 Time: 17:01 * Updated in $/FOST.3/F3Util * Added check to stop self assignment. * * ***************** Version 24 ***************** * User: Kirit Date: 23/02/06 Time: 18:05 * Updated in $/FOST.3/F3Util * Improved Unicode failure diagnostics and debugged UTF-16 encoding of * extended Unicode characters. * * ***************** Version 23 ***************** * User: Kirit Date: 17/01/06 Time: 0:57 * Updated in $/FOST.3/F3Util * Additions to string library and variant casts to handle 8 bit strings. * * ***************** Version 22 ***************** * User: Kirit Date: 20/04/05 Time: 18:20 * Updated in $/FOST.3/F3Util * Expanded wstring interface to move closer to std::wstring * * ***************** Version 21 ***************** * User: Kirit Date: 1/04/05 Time: 17:31 * Updated in $/FOST.3/F3Util * Added more complete toString support for longs and sorted some * related issues. * * ***************** Version 20 ***************** * User: Kirit Date: 5/03/05 Time: 14:27 * Updated in $/FOST.3/F3Util * Altered NULL assignment to use a library member for clearing the * string. * * ***************** Version 19 ***************** * User: Kirit Date: 5/03/05 Time: 14:10 * Updated in $/FOST.3/F3Util * Debugged string handling for NULL assignments. * * ***************** Version 18 ***************** * User: Kirit Date: 13/02/05 Time: 15:46 * Updated in $/FOST.3/F3Util * Added rfind to wstring and finding of utf16 sequence lengths. * * ***************** Version 17 ***************** * User: Kirit Date: 14/01/05 Time: 13:46 * Updated in $/FOST.3/F3Util * UTF-8 sequences with Unicode characters from HTTP POST now works * correctly. * * ***************** Version 16 ***************** * User: Kirit Date: 15/11/04 Time: 9:40 * Updated in $/FOST.3/F3Util * Corrected bugs to do with de-mangling of FOST encoded database fields. * * ***************** Version 15 ***************** * User: Kirit Date: 6/11/04 Time: 21:49 * Updated in $/FOST.3/F3Util * Added basics of new KPI based logging system. * * ***************** Version 14 ***************** * User: Kirit Date: 3/11/04 Time: 21:51 * Updated in $/FOST.3/F3Util * First working version of FSLib::wstring using UTF-16. * * ***************** Version 13 ***************** * User: Kirit Date: 15/07/04 Time: 13:18 * Updated in $/FOST.3/F3Util * Added new partition functions to break up a string around whitespace. * * ***************** Version 12 ***************** * User: Kirit Date: 14/07/04 Time: 15:16 * Updated in $/FOST.3/F3Util * Added version of partition useful for looping constructs. * * ***************** Version 11 ***************** * User: Kirit Date: 12/07/04 Time: 21:54 * Updated in $/FOST.3/F3Util * FSLib::widen now assumes UTF-8 encoding for narrow strings. * * ***************** Version 10 ***************** * User: Kirit Date: 5/07/04 Time: 11:37 * Updated in $/FOST.3/F3Util * Added partition function for strings. * Debugged crack where opening sequence is identical to the closing * sequence. * Added to init_ptr so it can be used in more types of STL container. * * ***************** Version 9 ***************** * User: Kirit Date: 27/06/04 Time: 12:04 * Updated in $/FOST.3/F3Util * Added FSLib::crack to string library. * * ***************** Version 8 ***************** * User: Kirit Date: 5/02/04 Time: 19:19 * Updated in $/FOST.3/F3Util * Added a new replaceAll which takes a Nullable string to replace with * such that the token may be removed. * * ***************** Version 7 ***************** * User: Kirit Date: 12/12/03 Time: 21:31 * Updated in $/FOST.3/F3Util * Added trim function and inlined other string handling functions. * * ***************** Version 6 ***************** * User: Kirit Date: 11/10/03 Time: 15:50 * Updated in $/FOST.3/F3Util * Added new string handling functions from RoseDoc. * * ***************** Version 5 ***************** * User: Kirit Date: 9/10/03 Time: 15:44 * Updated in $/FOST.3/F3Util * Headers re-arranged to give a proper SDK feel and to make determination * of required headers simpler. * * ***************** Version 4 ***************** * User: Kirit Date: 3/10/03 Time: 18:44 * Updated in $/FOST.3/F3Util * * ***************** Version 2 ***************** * User: Kirit Date: 7/05/02 Time: 12:01 * Updated in $/FOST/Cpp/FSCppUtil * Wrapped std::basic_string<> in order to change the copy semantics to * stop the problems with using C++ in the COM layer for IIS. * * ***************** Version 1 ***************** * User: Kirit Date: 3/05/02 Time: 23:34 * Created in $/FOST/Cpp/FSCppUtil */