ReactOS 0.4.16-dev-927-g467dec4
output.cpp
Go to the documentation of this file.
1//
2// output.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// The standard _output functions, which perform formatted output to a stream.
7//
9
10
11
12using namespace __crt_stdio_output;
13
14
15// Enclaves do not have a file system, but they do allow in-memory operations
16// from stdio.
17#ifndef _UCRT_ENCLAVE_BUILD
18
19template <template <typename, typename> class Base, typename Character>
21 unsigned __int64 const options,
22 FILE* const stream,
23 Character const* const format,
24 __crt_cached_ptd_host& ptd,
25 va_list const arglist
26 ) throw()
27{
28 typedef output_processor<
29 Character,
31 Base<Character, stream_output_adapter<Character>>
32 > processor_type;
33
34 _UCRT_VALIDATE_RETURN(ptd, stream != nullptr, EINVAL, -1);
35 _UCRT_VALIDATE_RETURN(ptd, format != nullptr, EINVAL, -1);
36
37 return __acrt_lock_stream_and_call(stream, [&]() -> int
38 {
39 __acrt_stdio_temporary_buffering_guard const buffering(stream, ptd);
40
41 processor_type processor(
43 options,
44 format,
45 ptd,
46 arglist);
47
48 return processor.process();
49 });
50}
51
53 unsigned __int64 const options,
54 FILE* const stream,
55 char const* const format,
56 _locale_t const locale,
57 va_list const arglist
58 )
59{
60 __crt_cached_ptd_host ptd(locale);
61 return common_vfprintf<standard_base>(options, stream, format, ptd, arglist);
62}
63
65 unsigned __int64 const options,
66 FILE* const stream,
67 wchar_t const* const format,
68 _locale_t const locale,
69 va_list const arglist
70 )
71{
72 __crt_cached_ptd_host ptd(locale);
73 return common_vfprintf<standard_base>(options, stream, format, ptd, arglist);
74}
75
77 unsigned __int64 const options,
78 FILE* const stream,
79 char const* const format,
80 _locale_t const locale,
81 va_list const arglist
82 )
83{
84 __crt_cached_ptd_host ptd(locale);
85 return common_vfprintf<format_validation_base>(options, stream, format, ptd, arglist);
86}
87
89 unsigned __int64 const options,
90 FILE* const stream,
91 wchar_t const* const format,
92 _locale_t const locale,
93 va_list const arglist
94 )
95{
96 __crt_cached_ptd_host ptd(locale);
97 return common_vfprintf<format_validation_base>(options, stream, format, ptd, arglist);
98}
99
101 unsigned __int64 const options,
102 FILE* const stream,
103 char const* const format,
104 _locale_t const locale,
105 va_list const arglist
106 )
107{
108 __crt_cached_ptd_host ptd(locale);
109 return common_vfprintf<positional_parameter_base>(options, stream, format, ptd, arglist);
110}
111
113 unsigned __int64 const options,
114 FILE* const stream,
115 wchar_t const* const format,
116 _locale_t const locale,
117 va_list const arglist
118 )
119{
120 __crt_cached_ptd_host ptd(locale);
121 return common_vfprintf<positional_parameter_base>(options, stream, format, ptd, arglist);
122}
123
124#endif /* _UCRT_ENCLAVE_BUILD */
125
126
127template <template <typename, typename> class Base, typename Character>
128_Success_(return >= 0)
129static int __cdecl common_vsprintf(
130 unsigned __int64 const options,
133 Character const* const format,
134 __crt_cached_ptd_host& ptd,
137{
139
140 typedef output_processor<
141 Character,
143 Base<Character, string_output_adapter<Character>>
144 > processor_type;
145
146 _UCRT_VALIDATE_RETURN(ptd, format != nullptr, EINVAL, -1);
147 _UCRT_VALIDATE_RETURN(ptd, buffer_count == 0 || buffer != nullptr, EINVAL, -1);
148
150 context._buffer = buffer;
151 context._buffer_count = buffer_count;
152 context._buffer_used = 0;
153
154 // For the C Standard snprintf functions, we continue formatting even after
155 // the buffer is full so that we can return the number of characters that
156 // are required to complete the format operation. For all other sprintf
157 // functions that have a buffer count, if no buffer was provided then we
158 // do the same.
159 context._continue_count =
161 buffer == nullptr;
162
163 processor_type processor(
165 options,
166 format,
167 ptd,
168 arglist);
169
170 int const result = processor.process();
171
172 if (buffer == nullptr)
173 {
174 return result;
175 }
176
177 // Otherwise, we formatted data into the buffer and need to terminate it:
179 {
180 if (buffer_count == 0 && result != 0)
181 {
182 return -1;
183 }
184 else if (context._buffer_used != buffer_count)
185 {
186 buffer[context._buffer_used] = '\0';
187 }
188 else if (result >= 0 && static_cast<size_t>(result) > buffer_count)
189 {
190 return -1;
191 }
192 }
194 {
195 if (buffer_count == 0)
196 {
197 // No-op
198 }
199 else if (result < 0)
200 {
201 buffer[0] = '\0';
202 }
203 else if (context._buffer_used == buffer_count)
204 {
205 buffer[buffer_count - 1] = '\0';
206 }
207 else
208 {
209 buffer[context._buffer_used] = '\0';
210 }
211 }
212 else
213 {
214 if (buffer_count == 0)
215 {
216 return -1;
217 }
218 else if (context._buffer_used == buffer_count)
219 {
220 buffer[buffer_count - 1] = '\0';
221 return -2;
222 }
223 else
224 {
225 buffer[context._buffer_used] = '\0';
226 }
227 }
228
229#pragma warning(suppress:__WARNING_POSTCONDITION_NULLTERMINATION_VIOLATION) // 26036 needs work
230 return result;
231}
232
234 unsigned __int64 const options,
235 char* const buffer,
236 size_t const buffer_count,
237 char const* const format,
238 _locale_t const locale,
239 va_list const arglist
240 )
241{
242 __crt_cached_ptd_host ptd(locale);
243 return common_vsprintf<standard_base>(options, buffer, buffer_count, format, ptd, arglist);
244}
245
247 unsigned __int64 const options,
248 wchar_t* const buffer,
249 size_t const buffer_count,
250 wchar_t const* const format,
251 _locale_t const locale,
252 va_list const arglist
253 )
254{
255 __crt_cached_ptd_host ptd(locale);
256 return common_vsprintf<standard_base>(options, buffer, buffer_count, format, ptd, arglist);
257}
258
259template <typename Character>
260_Success_(return >= 0)
261static int __cdecl common_vsprintf_s(
262 unsigned __int64 const options,
264 size_t const buffer_count,
265 Character const* const format,
266 __crt_cached_ptd_host& ptd,
268 ) throw()
269{
270 _UCRT_VALIDATE_RETURN(ptd, format != nullptr, EINVAL, -1);
271 _UCRT_VALIDATE_RETURN(ptd, buffer != nullptr && buffer_count > 0, EINVAL, -1);
272
273 int const result = common_vsprintf<format_validation_base>(options, buffer, buffer_count, format, ptd, arglist);
274 if (result < 0)
275 {
276 buffer[0] = 0;
278 }
279
280 if (result == -2)
281 {
282 _UCRT_VALIDATE_RETURN(ptd, ("Buffer too small", 0), ERANGE, -1);
283 }
284 else if (result >= 0)
285 {
287 }
288
289 return result;
290}
291
293 unsigned __int64 const options,
294 char* const buffer,
295 size_t const buffer_count,
296 char const* const format,
297 _locale_t const locale,
298 va_list const arglist
299 )
300{
301 __crt_cached_ptd_host ptd(locale);
302 return common_vsprintf_s(options, buffer, buffer_count, format, ptd, arglist);
303}
304
306 unsigned __int64 const options,
307 wchar_t* const buffer,
308 size_t const buffer_count,
309 wchar_t const* const format,
310 _locale_t const locale,
311 va_list const arglist
312 )
313{
314 __crt_cached_ptd_host ptd(locale);
315 return common_vsprintf_s(options, buffer, buffer_count, format, ptd, arglist);
316}
317
318template <typename Character>
319_Success_(return >= 0)
320static int __cdecl common_vsnprintf_s(
321 unsigned __int64 const options,
323 size_t const buffer_count,
325 Character const* const format,
326 __crt_cached_ptd_host& ptd,
328 ) throw()
329{
330 _UCRT_VALIDATE_RETURN(ptd, format != nullptr, EINVAL, -1);
331
332 if (max_count == 0 && buffer == nullptr && buffer_count == 0)
333 return 0; // No work to do
334
335 _UCRT_VALIDATE_RETURN(ptd, buffer != nullptr && buffer_count > 0, EINVAL, -1);
336
337 int result = -1;
338 {
339 auto errno_restore_point = ptd.get_errno().create_guard();
340 errno_restore_point.disable();
341
343 {
344 result = common_vsprintf<format_validation_base>(options, buffer, max_count + 1, format, ptd, arglist);
345
346 if (result == -2)
347 {
348 // The string has been truncated; return -1:
350 if (ptd.get_errno().check(ERANGE))
351 {
352 errno_restore_point.enable();
353 }
354
355 return -1;
356 }
357 }
358 else
359 {
360 result = common_vsprintf<format_validation_base>(options, buffer, buffer_count, format, ptd, arglist);
361 buffer[buffer_count - 1] = 0;
362
363 // We allow truncation if count == _TRUNCATE
364 if (result == -2 && max_count == _TRUNCATE)
365 {
366 if (ptd.get_errno().check(ERANGE))
367 {
368 errno_restore_point.enable();
369 }
370
371 return -1;
372 }
373 }
374 }
375
376 if (result < 0)
377 {
378 buffer[0] = 0;
380 if (result == -2)
381 {
382 _UCRT_VALIDATE_RETURN(ptd, ("Buffer too small", 0), ERANGE, -1);
383 }
384
385 return -1;
386 }
387
389
390 return result < 0 ? -1 : result;
391}
392
394 unsigned __int64 const options,
395 char* const buffer,
396 size_t const buffer_count,
397 size_t const max_count,
398 char const* const format,
399 _locale_t const locale,
400 va_list const arglist
401 )
402{
403 __crt_cached_ptd_host ptd(locale);
404 return common_vsnprintf_s(options, buffer, buffer_count, max_count, format, ptd, arglist);
405}
406
408 unsigned __int64 const options,
409 wchar_t* const buffer,
410 size_t const buffer_count,
411 size_t const max_count,
412 wchar_t const* const format,
413 _locale_t const locale,
414 va_list const arglist
415 )
416{
417 __crt_cached_ptd_host ptd(locale);
418 return common_vsnprintf_s(options, buffer, buffer_count, max_count, format, ptd, arglist);
419}
420
422 unsigned __int64 const options,
423 char* const buffer,
424 size_t const buffer_count,
425 char const* const format,
426 _locale_t const locale,
427 va_list const arglist
428 )
429{
430 __crt_cached_ptd_host ptd(locale);
431 return common_vsprintf<positional_parameter_base>(options, buffer, buffer_count, format, ptd, arglist);
432}
433
435 unsigned __int64 const options,
436 wchar_t* const buffer,
437 size_t const buffer_count,
438 wchar_t const* const format,
439 _locale_t const locale,
440 va_list const arglist
441 )
442{
443 __crt_cached_ptd_host ptd(locale);
444 return common_vsprintf<positional_parameter_base>(options, buffer, buffer_count, format, ptd, arglist);
445}
#define EINVAL
Definition: acclib.h:90
#define ERANGE
Definition: acclib.h:92
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define __int64
Definition: basetyps.h:16
Definition: _locale.h:75
#define _SECURECRT__FILL_STRING(_String, _Count, _Offset)
#define _UCRT_VALIDATE_RETURN(ptd, expr, errorcode, retexpr)
auto __acrt_lock_stream_and_call(FILE *const stream, Action &&action) -> decltype(action())
#define _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION
#define _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR
GLuint buffer
Definition: glext.h:5915
GLuint64EXT * result
Definition: glext.h:11304
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
#define _Out_writes_z_(s)
Definition: no_sal2.h:180
#define _Success_(c)
Definition: no_sal2.h:84
size_t const size_t const max_count
Definition: output.cpp:324
int __cdecl __stdio_common_vsprintf_s(unsigned __int64 const options, char *const buffer, size_t const buffer_count, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:292
size_t const buffer_count
Definition: output.cpp:132
size_t const Character const *const __crt_cached_ptd_host & ptd
Definition: output.cpp:134
int __cdecl __stdio_common_vfprintf(unsigned __int64 const options, FILE *const stream, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:52
int __cdecl __stdio_common_vsprintf(unsigned __int64 const options, char *const buffer, size_t const buffer_count, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:233
int __cdecl __stdio_common_vsprintf_p(unsigned __int64 const options, char *const buffer, size_t const buffer_count, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:421
int __cdecl __stdio_common_vswprintf(unsigned __int64 const options, wchar_t *const buffer, size_t const buffer_count, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:246
int __cdecl __stdio_common_vfwprintf_s(unsigned __int64 const options, FILE *const stream, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:88
int __cdecl __stdio_common_vfwprintf_p(unsigned __int64 const options, FILE *const stream, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:112
int __cdecl __stdio_common_vfwprintf(unsigned __int64 const options, FILE *const stream, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:64
static int __cdecl common_vfprintf(unsigned __int64 const options, FILE *const stream, Character const *const format, __crt_cached_ptd_host &ptd, va_list const arglist)
Definition: output.cpp:20
int __cdecl __stdio_common_vswprintf_s(unsigned __int64 const options, wchar_t *const buffer, size_t const buffer_count, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:305
int __cdecl __stdio_common_vfprintf_p(unsigned __int64 const options, FILE *const stream, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:100
int __cdecl __stdio_common_vfprintf_s(unsigned __int64 const options, FILE *const stream, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:76
int __cdecl __stdio_common_vswprintf_p(unsigned __int64 const options, wchar_t *const buffer, size_t const buffer_count, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:434
size_t const Character const *const __crt_cached_ptd_host va_list const arglist throw()
Definition: output.cpp:136
int __cdecl __stdio_common_vsnprintf_s(unsigned __int64 const options, char *const buffer, size_t const buffer_count, size_t const max_count, char const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:393
int __cdecl __stdio_common_vsnwprintf_s(unsigned __int64 const options, wchar_t *const buffer, size_t const buffer_count, size_t const max_count, wchar_t const *const format, _locale_t const locale, va_list const arglist)
Definition: output.cpp:407
va_lists_t arglist[FMT_ARGMAX+1]
Definition: format.c:284
Definition: http.c:7252
Definition: format.c:58
Definition: parse.h:23
#define _TRUNCATE
Definition: corecrt.h:278
#define const
Definition: zconf.h:233