ReactOS 0.4.16-dev-927-g467dec4
ungetwc.cpp File Reference
Include dependency graph for ungetwc.cpp:

Go to the source code of this file.

Functions

wint_t __cdecl ungetwc (wint_t const c, FILE *const stream)
 
static wint_t __cdecl ungetwc_text_mode_nolock (wint_t const c, __crt_stdio_stream const stream) throw ()
 
static wint_t __cdecl ungetwc_binary_mode_nolock (wint_t const c, __crt_stdio_stream const stream) throw ()
 
wint_t __cdecl _ungetwc_nolock (wint_t const c, FILE *const public_stream)
 

Function Documentation

◆ _ungetwc_nolock()

wint_t __cdecl _ungetwc_nolock ( wint_t const  c,
FILE *const  public_stream 
)

Definition at line 151 of file ungetwc.cpp.

152{
153 __crt_stdio_stream const stream(public_stream);
154
155 // Ungetting WEOF is expressly forbidden:
156 if (c == WEOF)
157 return WEOF;
158
159 // To unget, the stream must currently be in read mode, _or_ it must be open
160 // for update (read and write) and must not _currently_ be in write mode:
161 bool const is_in_read_mode = stream.has_all_of(_IOREAD);
162 bool const is_in_update_mode = stream.has_all_of(_IOUPDATE);
163 bool const is_in_write_mode = stream.has_all_of(_IOWRITE);
164
165 if (!is_in_read_mode && !(is_in_update_mode && !is_in_write_mode))
166 return WEOF;
167
168 // If the stream is currently unbuffered, buffer it:
169 if (stream->_base == nullptr)
171
172 // If the stream is file-backed and is open in text mode, we need to perform
173 // text mode translations:
174 if (!stream.is_string_backed() && (_osfile_safe(_fileno(stream.public_stream())) & FTEXT) != 0)
175 {
177 }
178
179 // Otherwise, the stream is string-backed or is a file-backed file open in
180 // binary mode; we can simply push the character back into the stream:
182}
void __cdecl __acrt_stdio_allocate_buffer_nolock(FILE *const public_stream)
Definition: _getbuf.cpp:16
const GLubyte * c
Definition: glext.h:8905
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
#define _IOREAD
Definition: stdio.h:124
#define WEOF
Definition: conio.h:185
#define _osfile_safe(i)
Definition: internal.h:78
Definition: parse.h:23
static wint_t __cdecl ungetwc_text_mode_nolock(wint_t const c, __crt_stdio_stream const stream)
Definition: ungetwc.cpp:39
static wint_t __cdecl ungetwc_binary_mode_nolock(wint_t const c, __crt_stdio_stream const stream)
Definition: ungetwc.cpp:98

Referenced by ungetwc().

◆ ungetwc()

wint_t __cdecl ungetwc ( wint_t const  c,
FILE *const  stream 
)

Definition at line 16 of file ungetwc.cpp.

17{
18 _VALIDATE_RETURN(stream != nullptr, EINVAL, WEOF);
19
20 wint_t return_value = WEOF;
21
23 __try
24 {
25 return_value = _ungetwc_nolock(c, stream);
26 }
28 {
30 }
32
33 return return_value;
34}
int wint_t
Definition: _apple.h:38
#define EINVAL
Definition: acclib.h:90
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
_CRTIMP void __cdecl _unlock_file(_Inout_ FILE *_File)
_CRTIMP void __cdecl _lock_file(_Inout_ FILE *_File)
#define __try
Definition: pseh2_64.h:188
#define __endtry
Definition: pseh2_64.h:191
#define __finally
Definition: pseh2_64.h:190
wint_t __cdecl _ungetwc_nolock(wint_t const c, FILE *const public_stream)
Definition: ungetwc.cpp:151

◆ ungetwc_binary_mode_nolock()

static wint_t __cdecl ungetwc_binary_mode_nolock ( wint_t const  c,
__crt_stdio_stream const  stream 
)
throw (
)
static

Definition at line 98 of file ungetwc.cpp.

99{
100 wchar_t const wide_c = static_cast<wchar_t>(c);
101
102 // At this point, the file must be buffered, so we know the base is non-null.
103 // First, we need to ensure there is sufficient room in the buffer to store
104 // the character:
105 if (stream->_ptr < stream->_base + sizeof(wchar_t))
106 {
107 // If we've already ungotten one character and it has not yet been read,
108 // there may not be room for this unget. In this case, there's nothing
109 // we can do so we simply fail:
110 if (stream->_cnt)
111 return WEOF;
112
113 if (sizeof(wchar_t) > stream->_bufsiz)
114 return WEOF;
115
116 stream->_ptr = sizeof(wchar_t) + stream->_base;
117 }
118
119 wchar_t*& wide_stream_ptr = reinterpret_cast<wchar_t*&>(stream->_ptr);
120
121 // If the stream is string-backed, we cannot modify the buffer. We retreat
122 // the stream pointer and test if the character being ungotten is the same
123 // as the character that was last read. If they are the same, then we allow
124 // the unget (because we don't have to modify the buffer). If they are not
125 // the same, then we re-advance the stream pointer and fail:
126 if (stream.is_string_backed())
127 {
128 if (*--wide_stream_ptr != wide_c)
129 {
130 ++wide_stream_ptr;
131 return WEOF;
132 }
133 }
134 // Otherwise, the stream is file-backed and open in binary mode, and we can
135 // just write the character to the front of the stream:
136 else
137 {
138 *--wide_stream_ptr = wide_c;
139 }
140
141 stream->_cnt += sizeof(wchar_t);
142
143 stream.unset_flags(_IOEOF);
144 stream.set_flags(_IOREAD);
145
146 return static_cast<wint_t>(wide_c);
147}
#define _IOEOF
Definition: stdio.h:132
#define c
Definition: ke_i.h:80
#define wchar_t
Definition: wchar.h:102

Referenced by _ungetwc_nolock().

◆ ungetwc_text_mode_nolock()

static wint_t __cdecl ungetwc_text_mode_nolock ( wint_t const  c,
__crt_stdio_stream const  stream 
)
throw (
)
static

Definition at line 39 of file ungetwc.cpp.

40{
41 // The stream is open in text mode, and we need to do the unget differently
42 // depending on whether the stream is open in ANSI or Unicode mode.
43 __crt_lowio_text_mode const text_mode = _textmode_safe(_fileno(stream.public_stream()));
44
45 int count = 0;
46 char characters[MB_LEN_MAX] = { 0 };
47
48 // If the file is open in ANSI mode, we need to convert the wide character
49 // to multibyte so that we can unget the multibyte character back into the
50 // stream:
51 if (text_mode == __crt_lowio_text_mode::ansi)
52 {
53 // If conversion fails, errno is set by wctomb_s and we can just return:
54 if (wctomb_s(&count, characters, MB_LEN_MAX, c) != 0)
55 return WEOF;
56 }
57 // Otherwise, the file is open in Unicode mode. This means the characters
58 // in the stream were originally Unicode (and not multibyte). Hence, we
59 // do not need to translate back to multibyte. This is true for both UTF-16
60 // and UTF-8, because the lowio read converts UTF-8 data to UTF-16.
61 else
62 {
63 char const* c_bytes = reinterpret_cast<char const*>(&c);
64 characters[0] = c_bytes[0];
65 characters[1] = c_bytes[1];
66 count = 2;
67 }
68
69 // At this point, the file must be buffered, so we know the base is non-null.
70 // First we need to ensure there is sufficient room in the buffer to store
71 // the translated data:
72 if (stream->_ptr < stream->_base + count)
73 {
74 if (stream->_cnt)
75 return WEOF;
76
77 if (count > stream->_bufsiz)
78 return WEOF;
79
80 stream->_ptr = count + stream->_base;
81 }
82
83 for (int i = count - 1; i >= 0; --i)
84 {
85 *--stream->_ptr = characters[i];
86 }
87
88 stream->_cnt += count;
89
90 stream.unset_flags(_IOEOF);
91 stream.set_flags(_IOREAD);
92 return static_cast<wint_t>(0xffff & c);
93}
__crt_lowio_text_mode
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MB_LEN_MAX
Definition: stdlib.h:19
#define _textmode_safe(i)
Definition: internal.h:81
errno_t __cdecl wctomb_s(int *const return_value, char *const destination, size_t const destination_count, wchar_t const wchar)
Definition: wctomb.cpp:160
#define const
Definition: zconf.h:233

Referenced by _ungetwc_nolock().