1*04e0dc4aSTimo Kreuzer //
2*04e0dc4aSTimo Kreuzer // _ctype.cpp
3*04e0dc4aSTimo Kreuzer //
4*04e0dc4aSTimo Kreuzer // Copyright (c) Microsoft Corporation. All rights reserved.
5*04e0dc4aSTimo Kreuzer //
6*04e0dc4aSTimo Kreuzer // Functions for converting integers to strings.
7*04e0dc4aSTimo Kreuzer //
8*04e0dc4aSTimo Kreuzer #include <corecrt_internal.h>
9*04e0dc4aSTimo Kreuzer #include <corecrt_internal_securecrt.h>
10*04e0dc4aSTimo Kreuzer #include <limits.h>
11*04e0dc4aSTimo Kreuzer #include <stdlib.h>
12*04e0dc4aSTimo Kreuzer
13*04e0dc4aSTimo Kreuzer #pragma warning(disable:__WARNING_NOT_SATISFIED) // 28020 Prefast thinks that 18446744073709551615 < 1.
14*04e0dc4aSTimo Kreuzer #pragma warning(disable:__WARNING_RANGE_PRECONDITION_VIOLATION) // 26060 Prefast thinks that 18446744073709551615 < 1.
15*04e0dc4aSTimo Kreuzer
16*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17*04e0dc4aSTimo Kreuzer //
18*04e0dc4aSTimo Kreuzer // Common Conversion Implementation
19*04e0dc4aSTimo Kreuzer //
20*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21*04e0dc4aSTimo Kreuzer namespace
22*04e0dc4aSTimo Kreuzer {
23*04e0dc4aSTimo Kreuzer template <typename T> struct make_signed;
24*04e0dc4aSTimo Kreuzer template <> struct make_signed<unsigned long> { typedef long type; };
25*04e0dc4aSTimo Kreuzer template <> struct make_signed<unsigned __int64> { typedef __int64 type; };
26*04e0dc4aSTimo Kreuzer }
27*04e0dc4aSTimo Kreuzer
28*04e0dc4aSTimo Kreuzer
29*04e0dc4aSTimo Kreuzer
30*04e0dc4aSTimo Kreuzer template <typename UnsignedInteger, typename Character>
31*04e0dc4aSTimo Kreuzer _Success_(return == 0)
32*04e0dc4aSTimo Kreuzer static errno_t __cdecl common_xtox(
33*04e0dc4aSTimo Kreuzer UnsignedInteger const original_value,
34*04e0dc4aSTimo Kreuzer _Out_writes_z_(buffer_count) Character* const buffer,
35*04e0dc4aSTimo Kreuzer _When_(is_negative == true, _In_range_(>=, 2)) _In_range_(>=, 1)
36*04e0dc4aSTimo Kreuzer size_t const buffer_count,
37*04e0dc4aSTimo Kreuzer unsigned const radix,
38*04e0dc4aSTimo Kreuzer bool const is_negative
39*04e0dc4aSTimo Kreuzer ) throw()
40*04e0dc4aSTimo Kreuzer {
41*04e0dc4aSTimo Kreuzer // OACR isn't able to track that p stays within the bounds of [buffer, buffer + buffer_count) so manually verified and disabled warning
42*04e0dc4aSTimo Kreuzer #pragma warning(push)
43*04e0dc4aSTimo Kreuzer #pragma warning(disable:26014)
44*04e0dc4aSTimo Kreuzer Character* p = buffer; // pointer to traverse the string
45*04e0dc4aSTimo Kreuzer size_t length = 0; // current length of string
46*04e0dc4aSTimo Kreuzer
47*04e0dc4aSTimo Kreuzer UnsignedInteger remaining_value = original_value;;
48*04e0dc4aSTimo Kreuzer
49*04e0dc4aSTimo Kreuzer if (is_negative)
50*04e0dc4aSTimo Kreuzer {
51*04e0dc4aSTimo Kreuzer *p++ = '-';
52*04e0dc4aSTimo Kreuzer ++length;
53*04e0dc4aSTimo Kreuzer
54*04e0dc4aSTimo Kreuzer remaining_value = static_cast<UnsignedInteger>(
55*04e0dc4aSTimo Kreuzer -static_cast<typename make_signed<UnsignedInteger>::type>(remaining_value)
56*04e0dc4aSTimo Kreuzer );
57*04e0dc4aSTimo Kreuzer }
58*04e0dc4aSTimo Kreuzer
59*04e0dc4aSTimo Kreuzer Character* first_digit = p;
60*04e0dc4aSTimo Kreuzer
61*04e0dc4aSTimo Kreuzer do
62*04e0dc4aSTimo Kreuzer {
63*04e0dc4aSTimo Kreuzer unsigned const digit = static_cast<unsigned>(remaining_value % radix);
64*04e0dc4aSTimo Kreuzer remaining_value /= radix;
65*04e0dc4aSTimo Kreuzer
66*04e0dc4aSTimo Kreuzer // Convert to ASCII and store:
67*04e0dc4aSTimo Kreuzer if (digit > 9)
68*04e0dc4aSTimo Kreuzer {
69*04e0dc4aSTimo Kreuzer *p++ = static_cast<Character>(digit - 10 + 'a');
70*04e0dc4aSTimo Kreuzer }
71*04e0dc4aSTimo Kreuzer else
72*04e0dc4aSTimo Kreuzer {
73*04e0dc4aSTimo Kreuzer *p++ = static_cast<Character>(digit + '0');
74*04e0dc4aSTimo Kreuzer }
75*04e0dc4aSTimo Kreuzer
76*04e0dc4aSTimo Kreuzer ++length;
77*04e0dc4aSTimo Kreuzer }
78*04e0dc4aSTimo Kreuzer while (remaining_value > 0 && length < buffer_count);
79*04e0dc4aSTimo Kreuzer
80*04e0dc4aSTimo Kreuzer if (length >= buffer_count)
81*04e0dc4aSTimo Kreuzer {
82*04e0dc4aSTimo Kreuzer buffer[0] = '\0';
83*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(length < buffer_count, ERANGE);
84*04e0dc4aSTimo Kreuzer }
85*04e0dc4aSTimo Kreuzer
86*04e0dc4aSTimo Kreuzer // We now have the digits of the number in the buffer, but in reverse order.
87*04e0dc4aSTimo Kreuzer // Reverse the order, but first terminate the string:
88*04e0dc4aSTimo Kreuzer *p-- = '\0';
89*04e0dc4aSTimo Kreuzer
90*04e0dc4aSTimo Kreuzer do
91*04e0dc4aSTimo Kreuzer {
92*04e0dc4aSTimo Kreuzer Character const t = *p;
93*04e0dc4aSTimo Kreuzer *p = *first_digit;
94*04e0dc4aSTimo Kreuzer *first_digit = t;
95*04e0dc4aSTimo Kreuzer --p;
96*04e0dc4aSTimo Kreuzer ++first_digit;
97*04e0dc4aSTimo Kreuzer }
98*04e0dc4aSTimo Kreuzer while (first_digit < p);
99*04e0dc4aSTimo Kreuzer
100*04e0dc4aSTimo Kreuzer return 0;
101*04e0dc4aSTimo Kreuzer #pragma warning(pop)
102*04e0dc4aSTimo Kreuzer }
103*04e0dc4aSTimo Kreuzer
104*04e0dc4aSTimo Kreuzer template <typename UnsignedInteger, typename Character>
105*04e0dc4aSTimo Kreuzer _Success_(return == 0)
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)106*04e0dc4aSTimo Kreuzer static errno_t __cdecl common_xtox_s(
107*04e0dc4aSTimo Kreuzer UnsignedInteger const value,
108*04e0dc4aSTimo Kreuzer _Out_writes_z_(buffer_count) Character* const buffer,
109*04e0dc4aSTimo Kreuzer size_t const buffer_count,
110*04e0dc4aSTimo Kreuzer unsigned const radix,
111*04e0dc4aSTimo Kreuzer bool const is_negative
112*04e0dc4aSTimo Kreuzer ) throw()
113*04e0dc4aSTimo Kreuzer {
114*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(buffer != nullptr, EINVAL);
115*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(buffer_count > 0, EINVAL);
116*04e0dc4aSTimo Kreuzer _RESET_STRING(buffer, buffer_count);
117*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(buffer_count > static_cast<size_t>(is_negative ? 2 : 1), ERANGE);
118*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN_ERRCODE(2 <= radix && radix <= 36, EINVAL);
119*04e0dc4aSTimo Kreuzer
120*04e0dc4aSTimo Kreuzer return common_xtox(value, buffer, buffer_count, radix, is_negative);
121*04e0dc4aSTimo Kreuzer }
122*04e0dc4aSTimo Kreuzer
123*04e0dc4aSTimo Kreuzer
124*04e0dc4aSTimo Kreuzer
125*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126*04e0dc4aSTimo Kreuzer //
127*04e0dc4aSTimo Kreuzer // 32-bit Integers => Narrow Strings
128*04e0dc4aSTimo Kreuzer //
129*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
_itoa_s(int const value,char * const buffer,size_t const buffer_count,int const radix)130*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _itoa_s(
131*04e0dc4aSTimo Kreuzer int const value,
132*04e0dc4aSTimo Kreuzer char* const buffer,
133*04e0dc4aSTimo Kreuzer size_t const buffer_count,
134*04e0dc4aSTimo Kreuzer int const radix
135*04e0dc4aSTimo Kreuzer )
136*04e0dc4aSTimo Kreuzer {
137*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
138*04e0dc4aSTimo Kreuzer return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
139*04e0dc4aSTimo Kreuzer }
140*04e0dc4aSTimo Kreuzer
_ltoa_s(long const value,char * const buffer,size_t const buffer_count,int const radix)141*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _ltoa_s(
142*04e0dc4aSTimo Kreuzer long const value,
143*04e0dc4aSTimo Kreuzer char* const buffer,
144*04e0dc4aSTimo Kreuzer size_t const buffer_count,
145*04e0dc4aSTimo Kreuzer int const radix
146*04e0dc4aSTimo Kreuzer )
147*04e0dc4aSTimo Kreuzer {
148*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
149*04e0dc4aSTimo Kreuzer return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
150*04e0dc4aSTimo Kreuzer }
151*04e0dc4aSTimo Kreuzer
_ultoa_s(unsigned long const value,char * const buffer,size_t const buffer_count,int const radix)152*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _ultoa_s(
153*04e0dc4aSTimo Kreuzer unsigned long const value,
154*04e0dc4aSTimo Kreuzer char* const buffer,
155*04e0dc4aSTimo Kreuzer size_t const buffer_count,
156*04e0dc4aSTimo Kreuzer int const radix
157*04e0dc4aSTimo Kreuzer )
158*04e0dc4aSTimo Kreuzer {
159*04e0dc4aSTimo Kreuzer return common_xtox_s(value, buffer, buffer_count, radix, false);
160*04e0dc4aSTimo Kreuzer }
161*04e0dc4aSTimo Kreuzer
162*04e0dc4aSTimo Kreuzer
163*04e0dc4aSTimo Kreuzer
_itoa(int const value,char * const buffer,int const radix)164*04e0dc4aSTimo Kreuzer extern "C" char* __cdecl _itoa(
165*04e0dc4aSTimo Kreuzer int const value,
166*04e0dc4aSTimo Kreuzer char* const buffer,
167*04e0dc4aSTimo Kreuzer int const radix
168*04e0dc4aSTimo Kreuzer )
169*04e0dc4aSTimo Kreuzer {
170*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
171*04e0dc4aSTimo Kreuzer common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
172*04e0dc4aSTimo Kreuzer return buffer;
173*04e0dc4aSTimo Kreuzer }
174*04e0dc4aSTimo Kreuzer
_ltoa(long const value,char * const buffer,int const radix)175*04e0dc4aSTimo Kreuzer extern "C" char* __cdecl _ltoa(
176*04e0dc4aSTimo Kreuzer long const value,
177*04e0dc4aSTimo Kreuzer char* const buffer,
178*04e0dc4aSTimo Kreuzer int const radix
179*04e0dc4aSTimo Kreuzer )
180*04e0dc4aSTimo Kreuzer {
181*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
182*04e0dc4aSTimo Kreuzer common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
183*04e0dc4aSTimo Kreuzer return buffer;
184*04e0dc4aSTimo Kreuzer }
185*04e0dc4aSTimo Kreuzer
_ultoa(unsigned long const value,char * const buffer,int const radix)186*04e0dc4aSTimo Kreuzer extern "C" char* __cdecl _ultoa(
187*04e0dc4aSTimo Kreuzer unsigned long const value,
188*04e0dc4aSTimo Kreuzer char* const buffer,
189*04e0dc4aSTimo Kreuzer int const radix
190*04e0dc4aSTimo Kreuzer )
191*04e0dc4aSTimo Kreuzer {
192*04e0dc4aSTimo Kreuzer common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
193*04e0dc4aSTimo Kreuzer return buffer;
194*04e0dc4aSTimo Kreuzer }
195*04e0dc4aSTimo Kreuzer
196*04e0dc4aSTimo Kreuzer
197*04e0dc4aSTimo Kreuzer
198*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
199*04e0dc4aSTimo Kreuzer //
200*04e0dc4aSTimo Kreuzer // 64-bit Integers => Narrow Strings
201*04e0dc4aSTimo Kreuzer //
202*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
_i64toa_s(__int64 const value,char * const buffer,size_t const buffer_count,int const radix)203*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _i64toa_s(
204*04e0dc4aSTimo Kreuzer __int64 const value,
205*04e0dc4aSTimo Kreuzer char* const buffer,
206*04e0dc4aSTimo Kreuzer size_t const buffer_count,
207*04e0dc4aSTimo Kreuzer int const radix
208*04e0dc4aSTimo Kreuzer )
209*04e0dc4aSTimo Kreuzer {
210*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
211*04e0dc4aSTimo Kreuzer return common_xtox_s(static_cast<unsigned __int64>(value), buffer, buffer_count, radix, is_negative);
212*04e0dc4aSTimo Kreuzer }
213*04e0dc4aSTimo Kreuzer
_ui64toa_s(unsigned __int64 const value,char * const buffer,size_t const buffer_count,int const radix)214*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _ui64toa_s(
215*04e0dc4aSTimo Kreuzer unsigned __int64 const value,
216*04e0dc4aSTimo Kreuzer char* const buffer,
217*04e0dc4aSTimo Kreuzer size_t const buffer_count,
218*04e0dc4aSTimo Kreuzer int const radix
219*04e0dc4aSTimo Kreuzer )
220*04e0dc4aSTimo Kreuzer {
221*04e0dc4aSTimo Kreuzer return common_xtox_s(value, buffer, buffer_count, radix, false);
222*04e0dc4aSTimo Kreuzer }
223*04e0dc4aSTimo Kreuzer
224*04e0dc4aSTimo Kreuzer
225*04e0dc4aSTimo Kreuzer
_i64toa(__int64 const value,char * const buffer,int const radix)226*04e0dc4aSTimo Kreuzer extern "C" char* __cdecl _i64toa(
227*04e0dc4aSTimo Kreuzer __int64 const value,
228*04e0dc4aSTimo Kreuzer char* const buffer,
229*04e0dc4aSTimo Kreuzer int const radix
230*04e0dc4aSTimo Kreuzer )
231*04e0dc4aSTimo Kreuzer {
232*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
233*04e0dc4aSTimo Kreuzer common_xtox(static_cast<unsigned __int64>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
234*04e0dc4aSTimo Kreuzer return buffer;
235*04e0dc4aSTimo Kreuzer }
236*04e0dc4aSTimo Kreuzer
_ui64toa(unsigned __int64 const value,char * const buffer,int const radix)237*04e0dc4aSTimo Kreuzer extern "C" char* __cdecl _ui64toa(
238*04e0dc4aSTimo Kreuzer unsigned __int64 const value,
239*04e0dc4aSTimo Kreuzer char* const buffer,
240*04e0dc4aSTimo Kreuzer int const radix
241*04e0dc4aSTimo Kreuzer )
242*04e0dc4aSTimo Kreuzer {
243*04e0dc4aSTimo Kreuzer common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
244*04e0dc4aSTimo Kreuzer return buffer;
245*04e0dc4aSTimo Kreuzer }
246*04e0dc4aSTimo Kreuzer
247*04e0dc4aSTimo Kreuzer
248*04e0dc4aSTimo Kreuzer
249*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
250*04e0dc4aSTimo Kreuzer //
251*04e0dc4aSTimo Kreuzer // 32-bit Integers => Wide Strings
252*04e0dc4aSTimo Kreuzer //
253*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
_itow_s(int const value,wchar_t * const buffer,size_t const buffer_count,int const radix)254*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _itow_s(
255*04e0dc4aSTimo Kreuzer int const value,
256*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
257*04e0dc4aSTimo Kreuzer size_t const buffer_count,
258*04e0dc4aSTimo Kreuzer int const radix
259*04e0dc4aSTimo Kreuzer )
260*04e0dc4aSTimo Kreuzer {
261*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
262*04e0dc4aSTimo Kreuzer return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
263*04e0dc4aSTimo Kreuzer }
264*04e0dc4aSTimo Kreuzer
_ltow_s(long const value,wchar_t * const buffer,size_t const buffer_count,int const radix)265*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _ltow_s(
266*04e0dc4aSTimo Kreuzer long const value,
267*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
268*04e0dc4aSTimo Kreuzer size_t const buffer_count,
269*04e0dc4aSTimo Kreuzer int const radix
270*04e0dc4aSTimo Kreuzer )
271*04e0dc4aSTimo Kreuzer {
272*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
273*04e0dc4aSTimo Kreuzer return common_xtox_s(static_cast<unsigned long>(value), buffer, buffer_count, radix, is_negative);
274*04e0dc4aSTimo Kreuzer }
275*04e0dc4aSTimo Kreuzer
_ultow_s(unsigned long const value,wchar_t * const buffer,size_t const buffer_count,int const radix)276*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _ultow_s(
277*04e0dc4aSTimo Kreuzer unsigned long const value,
278*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
279*04e0dc4aSTimo Kreuzer size_t const buffer_count,
280*04e0dc4aSTimo Kreuzer int const radix
281*04e0dc4aSTimo Kreuzer )
282*04e0dc4aSTimo Kreuzer {
283*04e0dc4aSTimo Kreuzer return common_xtox_s(value, buffer, buffer_count, radix, false);
284*04e0dc4aSTimo Kreuzer }
285*04e0dc4aSTimo Kreuzer
286*04e0dc4aSTimo Kreuzer
287*04e0dc4aSTimo Kreuzer
_itow(int const value,wchar_t * const buffer,int const radix)288*04e0dc4aSTimo Kreuzer extern "C" wchar_t* __cdecl _itow(
289*04e0dc4aSTimo Kreuzer int const value,
290*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
291*04e0dc4aSTimo Kreuzer int const radix
292*04e0dc4aSTimo Kreuzer )
293*04e0dc4aSTimo Kreuzer {
294*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
295*04e0dc4aSTimo Kreuzer common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
296*04e0dc4aSTimo Kreuzer return buffer;
297*04e0dc4aSTimo Kreuzer }
298*04e0dc4aSTimo Kreuzer
_ltow(long const value,wchar_t * const buffer,int const radix)299*04e0dc4aSTimo Kreuzer extern "C" wchar_t* __cdecl _ltow(
300*04e0dc4aSTimo Kreuzer long const value,
301*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
302*04e0dc4aSTimo Kreuzer int const radix
303*04e0dc4aSTimo Kreuzer )
304*04e0dc4aSTimo Kreuzer {
305*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
306*04e0dc4aSTimo Kreuzer common_xtox(static_cast<unsigned long>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
307*04e0dc4aSTimo Kreuzer return buffer;
308*04e0dc4aSTimo Kreuzer }
309*04e0dc4aSTimo Kreuzer
_ultow(unsigned long const value,wchar_t * const buffer,int const radix)310*04e0dc4aSTimo Kreuzer extern "C" wchar_t* __cdecl _ultow(
311*04e0dc4aSTimo Kreuzer unsigned long const value,
312*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
313*04e0dc4aSTimo Kreuzer int const radix
314*04e0dc4aSTimo Kreuzer )
315*04e0dc4aSTimo Kreuzer {
316*04e0dc4aSTimo Kreuzer common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
317*04e0dc4aSTimo Kreuzer return buffer;
318*04e0dc4aSTimo Kreuzer }
319*04e0dc4aSTimo Kreuzer
320*04e0dc4aSTimo Kreuzer
321*04e0dc4aSTimo Kreuzer
322*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
323*04e0dc4aSTimo Kreuzer //
324*04e0dc4aSTimo Kreuzer // 64-bit Integers => Wide Strings
325*04e0dc4aSTimo Kreuzer //
326*04e0dc4aSTimo Kreuzer //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
_i64tow_s(__int64 const value,wchar_t * const buffer,size_t const buffer_count,int const radix)327*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _i64tow_s(
328*04e0dc4aSTimo Kreuzer __int64 const value,
329*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
330*04e0dc4aSTimo Kreuzer size_t const buffer_count,
331*04e0dc4aSTimo Kreuzer int const radix
332*04e0dc4aSTimo Kreuzer )
333*04e0dc4aSTimo Kreuzer {
334*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
335*04e0dc4aSTimo Kreuzer return common_xtox_s(static_cast<unsigned __int64>(value), buffer, buffer_count, radix, is_negative);
336*04e0dc4aSTimo Kreuzer }
337*04e0dc4aSTimo Kreuzer
_ui64tow_s(unsigned __int64 const value,wchar_t * const buffer,size_t const buffer_count,int const radix)338*04e0dc4aSTimo Kreuzer extern "C" errno_t __cdecl _ui64tow_s(
339*04e0dc4aSTimo Kreuzer unsigned __int64 const value,
340*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
341*04e0dc4aSTimo Kreuzer size_t const buffer_count,
342*04e0dc4aSTimo Kreuzer int const radix
343*04e0dc4aSTimo Kreuzer )
344*04e0dc4aSTimo Kreuzer {
345*04e0dc4aSTimo Kreuzer return common_xtox_s(value, buffer, buffer_count, radix, false);
346*04e0dc4aSTimo Kreuzer }
347*04e0dc4aSTimo Kreuzer
348*04e0dc4aSTimo Kreuzer
349*04e0dc4aSTimo Kreuzer
_i64tow(__int64 const value,wchar_t * const buffer,int const radix)350*04e0dc4aSTimo Kreuzer extern "C" wchar_t* __cdecl _i64tow(
351*04e0dc4aSTimo Kreuzer __int64 const value,
352*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
353*04e0dc4aSTimo Kreuzer int const radix
354*04e0dc4aSTimo Kreuzer )
355*04e0dc4aSTimo Kreuzer {
356*04e0dc4aSTimo Kreuzer bool const is_negative = radix == 10 && value < 0;
357*04e0dc4aSTimo Kreuzer common_xtox(static_cast<unsigned __int64>(value), buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, is_negative);
358*04e0dc4aSTimo Kreuzer return buffer;
359*04e0dc4aSTimo Kreuzer }
360*04e0dc4aSTimo Kreuzer
_ui64tow(unsigned __int64 const value,wchar_t * const buffer,int const radix)361*04e0dc4aSTimo Kreuzer extern "C" wchar_t* __cdecl _ui64tow(
362*04e0dc4aSTimo Kreuzer unsigned __int64 const value,
363*04e0dc4aSTimo Kreuzer wchar_t* const buffer,
364*04e0dc4aSTimo Kreuzer int const radix
365*04e0dc4aSTimo Kreuzer )
366*04e0dc4aSTimo Kreuzer {
367*04e0dc4aSTimo Kreuzer common_xtox(value, buffer, _CRT_UNBOUNDED_BUFFER_SIZE, radix, false);
368*04e0dc4aSTimo Kreuzer return buffer;
369*04e0dc4aSTimo Kreuzer }
370