📄 _filbuf.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/***
*_filbuf.c - fill buffer and get character
*
*
*Purpose:
* defines _filbuf() - fill buffer and read first character, allocate
* buffer if there is none. Used from getc().
* defines _filwbuf() - fill buffer and read first wide character, allocate
* buffer if there is none. Used from getwc().
*
*******************************************************************************/
#include <cruntime.h>
#include <stdio.h>
#include <file2.h>
#include <dbgint.h>
#include <malloc.h>
#include <internal.h>
#include <msdos.h>
#include <mtdll.h>
/***
*int _filbuf(stream) - fill buffer and get first character
*
*Purpose:
* get a buffer if the file doesn't have one, read into it, return first
* char. try to get a buffer, if a user buffer is not assigned. called
* only from getc; intended for use only within library. assume no input
* stream is to remain unbuffered when memory is available unless it is
* marked _IONBF. at worst, give it a single char buffer. the need for a
* buffer, no matter how small, becomes evident when we consider the
* ungetc's necessary in scanf
*
* [NOTE: Multi-thread - _filbuf() assumes that the caller has aquired
* the stream lock, if needed.]
*
*Entry:
* FILEX *stream - stream to read from
*
*Exit:
* returns first character from buffer (next character to be read)
* returns EOF if the FILEX is actually a string, or not open for reading,
* or if open for writing or if no more chars to read.
* all fields in FILEX structure may be changed except _file.
*
*Exceptions:
*
*******************************************************************************/
int __cdecl _real_filbuf2(FILEX *str, int fWide)
{
REG1 FILEX *stream;
_ASSERTE(str != NULL);
/* Init pointer to _iob2 entry. */
stream = str;
if (!inuse(stream) || stream->_flag & _IOSTRG)
goto reteof;
if (stream->_flag & _IOWRT)
{
stream->_flag |= _IOERR;
goto reteof;
}
stream->_flag |= _IOREAD;
/* Get a buffer, if necessary. */
if (!anybuf(stream))
_getbuf(stream);
else
stream->_ptr = stream->_base;
stream->_cnt = _read(stream, stream->_base, stream->_bufsiz);
if ((stream->_cnt == 0) || (stream->_cnt == -1) || (fWide && (stream->_cnt == 1)))
{
stream->_flag |= stream->_cnt ? _IOERR : _IOEOF;
stream->_cnt = 0;
goto reteof;
}
if ( !(stream->_flag & (_IOWRT|_IORW)) && ((_osfilestr(stream) & (FTEXT|FEOFLAG)) == (FTEXT|FEOFLAG)) )
stream->_flag |= _IOCTRLZ;
/* Check for small _bufsiz (_SMALL_BUFSIZ). If it is small and
if it is our buffer, then this must be the first _filbuf after
an fseek on a read-access-only stream. Restore _bufsiz to its
larger value (_INTERNAL_BUFSIZ) so that the next _filbuf call,
if one is made, will fill the whole buffer. */
if ( (stream->_bufsiz == _SMALL_BUFSIZ) && (stream->_flag &
_IOMYBUF) && !(stream->_flag & _IOSETVBUF) )
{
stream->_bufsiz = _INTERNAL_BUFSIZ;
}
if(fWide)
{
stream->_cnt -= sizeof(wchar_t);
return (0xffff & *((wchar_t *)(stream->_ptr))++);
}
else
{
stream->_cnt--;
return (0xff & *stream->_ptr++);
}
reteof:
return (fWide ? WEOF : EOF);
}
/***
*int _flsbuf(ch, stream) - flush buffer and output character.
*
*Purpose:
* flush a buffer if this stream has one. if not, try to get one. put the
* next output char (ch) into the buffer (or output it immediately if this
* stream can't have a buffer). called only from putc. intended for use
* only within library.
*
* [NOTE: Multi-thread - It is assumed that the caller has aquired
* the stream lock.]
*
*Entry:
* FILEX *stream - stream to flish and write on
* int ch - character to output.
*
*Exit:
* returns -1 if FILEX is actually a string, or if can't write ch to
* unbuffered file, or if we flush a buffer but the number of chars
* written doesn't agree with buffer size. Otherwise returns ch.
* all fields in FILEX struct can be affected except _file.
*
*Exceptions:
*
*******************************************************************************/
int __cdecl _real_flsbuf2(int ch, FILEX *str, int fWide)
{
REG1 FILEX *stream;
REG2 int charcount;
REG3 int written;
int csize = (fWide ? sizeof(WCHAR) : sizeof(char));
_ASSERTE(str != NULL);
/* Init file handle and pointers */
stream = str;
if (!(stream->_flag & (_IOWRT|_IORW)) || (stream->_flag & _IOSTRG))
{
stream->_flag |= _IOERR;
goto reteof;
}
/* Check that _IOREAD is not set or, if it is, then so is _IOEOF. Note
that _IOREAD and IOEOF both being set implies switching from read to
write at end-of-file, which is allowed by ANSI. Note that resetting
the _cnt and _ptr fields amounts to doing an fflush() on the stream
in this case. Note also that the _cnt field has to be reset to 0 for
the error path as well (i.e., _IOREAD set but _IOEOF not set) as
well as the non-error path. */
if (stream->_flag & _IOREAD) {
stream->_cnt = 0;
if (stream->_flag & _IOEOF) {
stream->_ptr = stream->_base;
stream->_flag &= ~_IOREAD;
}
else {
stream->_flag |= _IOERR;
goto reteof;
}
}
stream->_flag |= _IOWRT;
stream->_flag &= ~_IOEOF;
written = charcount = stream->_cnt = 0;
/* Get a buffer for this stream, if necessary. */
if (!anybuf(stream)) {
/* Do NOT get a buffer if (1) stream is stdout/stderr, and
(2) stream is NOT a tty.
[If stdout/stderr is a tty, we do NOT set up single char
buffering. This is so that later temporary buffering will
not be thwarted by the _IONBF bit being set (see
_stbuf/_ftbuf usage).]
*/
if (!( ((stream==stdout) || (stream==stderr)) && (_isatty(stream)) ))
_getbuf(stream);
} /* end !anybuf() */
/* If big buffer is assigned to stream... */
if (bigbuf(stream))
{
_ASSERTE(("inconsistent IOB fields", stream->_ptr - stream->_base >= 0));
charcount = stream->_ptr - stream->_base;
stream->_ptr = stream->_base + csize;
stream->_cnt = stream->_bufsiz - csize;
if (charcount > 0)
written = _write(stream, stream->_base, charcount);
else
if (_osfilestr(stream) & FAPPEND)
_lseek(stream,0L,SEEK_END);
if(fWide)
*(wchar_t *)(stream->_base) = (wchar_t)(ch & 0xffff);
else
*stream->_base = (char)ch;
}
/* Perform single character output (either _IONBF or no buffering) */
else {
charcount = csize;
written = _write(stream, &ch, charcount);
/***
{ char mbc[4];
*(wchar_t *)mbc = (wchar_t)(ch & 0xffff);
written = _write(stream, mbc, charcount);}
***/
}
/* See if the _write() was successful. */
if (written != charcount)
{
stream->_flag |= _IOERR;
goto reteof;
}
return (ch & (fWide ? 0xffff : 0xff));
reteof:
return EOF;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -