mirror of
https://github.com/reactos/reactos.git
synced 2025-05-19 00:54:18 +00:00

Imported from https://www.nuget.org/packages/Microsoft.Windows.SDK.CRTSource/10.0.22621.3 License: MIT
369 lines
10 KiB
C++
369 lines
10 KiB
C++
//
|
|
// _ctype.cpp
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// Functions for converting integers to strings.
|
|
//
|
|
#include <corecrt_internal.h>
|
|
#include <corecrt_internal_securecrt.h>
|
|
#include <limits.h>
|
|
#include <stdlib.h>
|
|
|
|
#pragma warning(disable:__WARNING_NOT_SATISFIED) // 28020 Prefast thinks that 18446744073709551615 < 1.
|
|
#pragma warning(disable:__WARNING_RANGE_PRECONDITION_VIOLATION) // 26060 Prefast thinks that 18446744073709551615 < 1.
|
|
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
//
|
|
// Common Conversion Implementation
|
|
//
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
namespace
|
|
{
|
|
template <typename T> struct make_signed;
|
|
template <> struct make_signed<unsigned long> { typedef long type; };
|
|
template <> struct make_signed<unsigned __int64> { typedef __int64 type; };
|
|
}
|
|
|
|
|
|
|
|
template <typename UnsignedInteger, typename Character>
|
|
_Success_(return == 0)
|
|
static errno_t __cdecl common_xtox(
|
|
UnsignedInteger const original_value,
|
|
_Out_writes_z_(buffer_count) Character* const buffer,
|
|
_When_(is_negative == true, _In_range_(>=, 2)) _In_range_(>=, 1)
|
|
size_t const buffer_count,
|
|
unsigned const radix,
|
|
bool const is_negative
|
|
) throw()
|
|
{
|
|
// OACR isn't able to track that p stays within the bounds of [buffer, buffer + buffer_count) so manually verified and disabled warning
|
|
#pragma warning(push)
|
|
#pragma warning(disable:26014)
|
|
Character* p = buffer; // pointer to traverse the string
|
|
size_t length = 0; // current length of string
|
|
|
|
UnsignedInteger remaining_value = original_value;;
|
|
|
|
if (is_negative)
|
|
{
|
|
*p++ = '-';
|
|
++length;
|
|
|
|
remaining_value = static_cast<UnsignedInteger>(
|
|
-static_cast<typename make_signed<UnsignedInteger>::type>(remaining_value)
|
|
);
|
|
}
|
|
|
|
Character* first_digit = p;
|
|
|
|
do
|
|
{
|
|
unsigned const digit = static_cast<unsigned>(remaining_value % radix);
|
|
remaining_value /= radix;
|
|
|
|
// Convert to ASCII and store:
|
|
if (digit > 9)
|
|
{
|
|
*p++ = static_cast<Character>(digit - 10 + 'a');
|
|
}
|
|
else
|
|
{
|
|
*p++ = static_cast<Character>(digit + '0');
|
|
}
|
|
|
|
++length;
|
|
}
|
|
while (remaining_value > 0 && length < buffer_count);
|
|
|
|
if (length >= buffer_count)
|
|
{
|
|
buffer[0] = '\0';
|
|
_VALIDATE_RETURN_ERRCODE(length < buffer_count, ERANGE);
|
|
}
|
|
|
|
// We now have the digits of the number in the buffer, but in reverse order.
|
|
// Reverse the order, but first terminate the string:
|
|
*p-- = '\0';
|
|
|
|
do
|
|
{
|
|
Character const t = *p;
|
|
*p = *first_digit;
|
|
*first_digit = t;
|
|
--p;
|
|
++first_digit;
|
|
}
|
|
while (first_digit < p);
|
|
|
|
return 0;
|
|
#pragma warning(pop)
|
|
}
|
|
|
|
template <typename UnsignedInteger, typename Character>
|
|
_Success_(return == 0)
|
|
static errno_t __cdecl common_xtox_s(
|
|
UnsignedInteger const value,
|
|
_Out_writes_z_(buffer_count) Character* const buffer,
|
|
size_t const buffer_count,
|
|
unsigned const radix,
|
|
bool const is_negative
|
|
) throw()
|
|
{
|
|
_VALIDATE_RETURN_ERRCODE(buffer != nullptr, EINVAL);
|
|
_VALIDATE_RETURN_ERRCODE(buffer_count > 0, EINVAL);
|
|
_RESET_STRING(buffer, buffer_count);
|
|
_VALIDATE_RETURN_ERRCODE(buffer_count > static_cast<size_t>(is_negative ? 2 : 1), ERANGE);
|
|
_VALIDATE_RETURN_ERRCODE(2 <= radix && radix <= 36, EINVAL);
|
|
|
|
return common_xtox(value, buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
|
|
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
//
|
|
// 32-bit Integers => Narrow Strings
|
|
//
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
extern "C" errno_t __cdecl _itoa_s(
|
|
int const value,
|
|
char* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
extern "C" errno_t __cdecl _ltoa_s(
|
|
long const value,
|
|
char* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
extern "C" errno_t __cdecl _ultoa_s(
|
|
unsigned long const value,
|
|
char* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
return common_xtox_s(value, buffer, buffer_count, radix, false);
|
|
}
|
|
|
|
|
|
|
|
extern "C" char* __cdecl _itoa(
|
|
int const value,
|
|
char* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
|
|
return buffer;
|
|
}
|
|
|
|
extern "C" char* __cdecl _ltoa(
|
|
long const value,
|
|
char* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
|
|
return buffer;
|
|
}
|
|
|
|
extern "C" char* __cdecl _ultoa(
|
|
unsigned long const value,
|
|
char* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
|
|
return buffer;
|
|
}
|
|
|
|
|
|
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
//
|
|
// 64-bit Integers => Narrow Strings
|
|
//
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
extern "C" errno_t __cdecl _i64toa_s(
|
|
__int64 const value,
|
|
char* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
return common_xtox_s(static_cast<unsigned __int64>(value), buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
extern "C" errno_t __cdecl _ui64toa_s(
|
|
unsigned __int64 const value,
|
|
char* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
return common_xtox_s(value, buffer, buffer_count, radix, false);
|
|
}
|
|
|
|
|
|
|
|
extern "C" char* __cdecl _i64toa(
|
|
__int64 const value,
|
|
char* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
common_xtox(static_cast<unsigned __int64>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
|
|
return buffer;
|
|
}
|
|
|
|
extern "C" char* __cdecl _ui64toa(
|
|
unsigned __int64 const value,
|
|
char* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
|
|
return buffer;
|
|
}
|
|
|
|
|
|
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
//
|
|
// 32-bit Integers => Wide Strings
|
|
//
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
extern "C" errno_t __cdecl _itow_s(
|
|
int const value,
|
|
wchar_t* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
extern "C" errno_t __cdecl _ltow_s(
|
|
long const value,
|
|
wchar_t* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
extern "C" errno_t __cdecl _ultow_s(
|
|
unsigned long const value,
|
|
wchar_t* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
return common_xtox_s(value, buffer, buffer_count, radix, false);
|
|
}
|
|
|
|
|
|
|
|
extern "C" wchar_t* __cdecl _itow(
|
|
int const value,
|
|
wchar_t* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
|
|
return buffer;
|
|
}
|
|
|
|
extern "C" wchar_t* __cdecl _ltow(
|
|
long const value,
|
|
wchar_t* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
|
|
return buffer;
|
|
}
|
|
|
|
extern "C" wchar_t* __cdecl _ultow(
|
|
unsigned long const value,
|
|
wchar_t* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
|
|
return buffer;
|
|
}
|
|
|
|
|
|
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
//
|
|
// 64-bit Integers => Wide Strings
|
|
//
|
|
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
extern "C" errno_t __cdecl _i64tow_s(
|
|
__int64 const value,
|
|
wchar_t* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
return common_xtox_s(static_cast<unsigned __int64>(value), buffer, buffer_count, radix, is_negative);
|
|
}
|
|
|
|
extern "C" errno_t __cdecl _ui64tow_s(
|
|
unsigned __int64 const value,
|
|
wchar_t* const buffer,
|
|
size_t const buffer_count,
|
|
int const radix
|
|
)
|
|
{
|
|
return common_xtox_s(value, buffer, buffer_count, radix, false);
|
|
}
|
|
|
|
|
|
|
|
extern "C" wchar_t* __cdecl _i64tow(
|
|
__int64 const value,
|
|
wchar_t* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
bool const is_negative = radix == 10 && value < 0;
|
|
common_xtox(static_cast<unsigned __int64>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
|
|
return buffer;
|
|
}
|
|
|
|
extern "C" wchar_t* __cdecl _ui64tow(
|
|
unsigned __int64 const value,
|
|
wchar_t* const buffer,
|
|
int const radix
|
|
)
|
|
{
|
|
common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
|
|
return buffer;
|
|
}
|