Reactos
at listview 137 lines 3.2 kB view raw
1// 2// fgetwc.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// Functions that read the next wide character from a stream and return it. If 7// the read causes the stream to reach EOF, WEOF is returned and the EOF bit is 8// set on the stream. 9// 10#include <corecrt_internal_stdio.h> 11 12 13 14extern "C" wint_t __cdecl _fgetwc_nolock(FILE* const public_stream) 15{ 16 __crt_stdio_stream const stream(public_stream); 17 18 // If the stream is backed by a real file and is open in a Unicode text mode, 19 // we need to read two bytes (note that we read two bytes for both UTF-8 and 20 // UTF-16 backed streams, since lowio translates UTF-8 to UTF-16 when we read. 21 if (!stream.is_string_backed() && 22 _textmode_safe(_fileno(stream.public_stream())) != __crt_lowio_text_mode::ansi) 23 { 24 wchar_t wc; 25 26 // Compose the wide character by reading byte-by-byte from the stream: 27 char* const wc_first = reinterpret_cast<char*>(&wc); 28 char* const wc_last = wc_first + sizeof(wc); 29 30 for (char* it = wc_first; it != wc_last; ++it) 31 { 32 int const c = _getc_nolock(stream.public_stream()); 33 if (c == EOF) 34 return WEOF; 35 36 *it = static_cast<char>(c); 37 } 38 39 return wc; 40 } 41 42 if (!stream.is_string_backed() && 43 (_osfile_safe(_fileno(stream.public_stream())) & FTEXT)) 44 { 45 int size = 1; 46 int ch; 47 char mbc[4]; 48 wchar_t wch; 49 50 /* text (multi-byte) mode */ 51 if ((ch = _getc_nolock(stream.public_stream())) == EOF) 52 return WEOF; 53 54 mbc[0] = static_cast<char>(ch); 55 56 if (isleadbyte(static_cast<unsigned char>(mbc[0]))) 57 { 58 if ((ch = _getc_nolock(stream.public_stream())) == EOF) 59 { 60 ungetc(mbc[0], stream.public_stream()); 61 return WEOF; 62 } 63 mbc[1] = static_cast<char>(ch); 64 size = 2; 65 } 66 67 if (mbtowc(&wch, mbc, size) == -1) 68 { 69 // Conversion failed! Set errno and return failure: 70 errno = EILSEQ; 71 return WEOF; 72 } 73 74 return wch; 75 } 76 77 // binary (Unicode) mode 78 if (stream->_cnt >= static_cast<int>(sizeof(wchar_t))) 79 { 80 stream->_cnt -= static_cast<int>(sizeof(wchar_t)); 81 return *reinterpret_cast<wchar_t*&>(stream->_ptr)++; 82 } 83 else 84 { 85 return static_cast<wint_t>(__acrt_stdio_refill_and_read_wide_nolock(stream.public_stream())); 86 } 87} 88 89 90 91extern "C" wint_t __cdecl _getwc_nolock(FILE* const stream) 92{ 93 return _fgetwc_nolock(stream); 94} 95 96 97 98extern "C" wint_t __cdecl fgetwc(FILE* const stream) 99{ 100 _VALIDATE_RETURN(stream != nullptr, EINVAL, WEOF); 101 102 wint_t return_value = 0; 103 104 _lock_file(stream); 105 __try 106 { 107 return_value = _fgetwc_nolock(stream); 108 } 109 __finally 110 { 111 _unlock_file(stream); 112 } 113 __endtry 114 115 return return_value; 116} 117 118 119 120extern "C" wint_t __cdecl getwc(FILE* const stream) 121{ 122 return fgetwc(stream); 123} 124 125 126 127extern "C" wint_t __cdecl _fgetwchar() 128{ 129 return fgetwc(stdin); 130} 131 132 133 134extern "C" wint_t __cdecl getwchar() 135{ 136 return _fgetwchar(); 137}