in source/shared/core_results.cpp [161:232]
SQLRETURN number_to_string( _In_ Number* number_data, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Inout_ sqlsrv_error_auto_ptr& last_error )
{
size_t precision = 0;
#ifdef _WIN32
std::basic_ostringstream<Char> os;
precision = get_float_precision( buffer_length, sizeof( Char ));
os.precision( precision );
std::locale loc;
os.imbue(loc);
std::use_facet< std::num_put< Char > >( loc ).put( std::basic_ostream<Char>::_Iter( os.rdbuf()), os, ' ', *number_data );
std::basic_string<Char>& str_num = os.str();
if ( os.fail() ) {
last_error = new ( sqlsrv_malloc(sizeof( sqlsrv_error ))) sqlsrv_error(( SQLCHAR* ) "IMSSP", (SQLCHAR*) "Failed to convert number to string", -1 );
return SQL_ERROR;
}
if ( str_num.size() * sizeof( Char ) > ( size_t )buffer_length ) {
last_error = new ( sqlsrv_malloc(sizeof( sqlsrv_error ))) sqlsrv_error(( SQLCHAR* ) "HY090", ( SQLCHAR* ) "Buffer length too small to hold number as string", -1 );
return SQL_ERROR;
}
*out_buffer_length = str_num.size() * sizeof( Char ); // str_num.size() already include the NULL terminator
memcpy_s( buffer, buffer_length, str_num.c_str(), *out_buffer_length );
return SQL_SUCCESS;
#else
std::basic_string<char> str_num;
SQLRETURN r;
if ( std::is_integral<Number>::value )
{
long num_data = *number_data;
r = get_string_from_stream<long>( num_data, str_num, precision, last_error );
}
else
{
precision = get_float_precision( buffer_length, sizeof( Char ));
r = get_string_from_stream<double>( *number_data, str_num, precision, last_error );
}
if ( r == SQL_ERROR ) return SQL_ERROR;
if ( std::is_same<Char, char16_t>::value )
{
std::basic_string<char16_t> str;
for (const auto &mb : str_num )
{
size_t cch = SystemLocale::NextChar( CP_ACP, &mb ) - &mb;
if ( cch > 0 )
{
WCHAR ch16;
DWORD rc;
size_t cchActual = SystemLocale::ToUtf16( CP_ACP, &mb, cch, &ch16, 1, &rc);
if (cchActual > 0)
{
str.push_back ( ch16 );
}
}
}
return copy_buffer<char16_t>( buffer, buffer_length, out_buffer_length, str, last_error );
}
return copy_buffer<char>( buffer, buffer_length, out_buffer_length, str_num, last_error );
#endif // _WIN32
}