home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
setvbuf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-17
|
5KB
|
176 lines
/***
*setvbuf.c - set buffer size for a stream
*
* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines setvbuf() - set the buffering mode and size for a stream.
*
*******************************************************************************/
#include <cruntime.h>
#include <stdio.h>
#include <file2.h>
#include <malloc.h>
#include <internal.h>
#include <mtdll.h>
#include <limits.h>
#include <dbgint.h>
/***
*int setvbuf(stream, buffer, type, size) - set buffering for a file
*
*Purpose:
* Controls buffering and buffer size for the specified stream. The
* array pointed to by buf is used as a buffer, unless NULL, in which
* case we'll allocate a buffer automatically. type specifies the type
* of buffering: _IONBF = no buffer, _IOFBF = buffered, _IOLBF = same
* as _IOFBF.
*
*Entry:
* FILE *stream - stream to control buffer on
* char *buffer - pointer to buffer to use (NULL means auto allocate)
* int type - type of buffering (_IONBF, _IOFBF or _IOLBF)
* size_t size - size of buffer
*
*Exit:
* return 0 if successful
* returns non-zero if fails
*
*Exceptions:
*
*******************************************************************************/
int __cdecl setvbuf (
FILE *str,
char *buffer,
int type,
size_t size
)
{
REG1 FILE *stream;
int retval=0; /* assume good return */
_ASSERTE(str != NULL);
/*
* (1) Make sure type is one of the three legal values.
* (2) If we are buffering, make sure size is greater than 0.
*/
#ifdef _WIN32
if ( (type != _IONBF) && ((size < 2) || (size > INT_MAX) ||
#else /* _WIN32 */
#if defined (_M_MPPC) || defined (_M_M68K)
if ( (type != _IONBF) && ((size == 0) || (size > INT_MAX) ||
#endif /* defined (_M_MPPC) || defined (_M_M68K) */
#endif /* _WIN32 */
((type != _IOFBF) && (type != _IOLBF))) )
return(-1);
#ifdef _WIN32
/*
* force size to be even by masking down to the nearest multiple
* of 2
*/
size &= (size_t)~1;
#endif /* _WIN32 */
/*
* Init stream pointers
*/
stream = str;
/*
* Lock the file
*/
_lock_str(stream);
/*
* Flush the current buffer and free it, if it is ours.
*/
_flush(stream);
_freebuf(stream);
/*
* Clear a bunch of bits in stream->_flag (all bits related to
* buffering and those which used to be in stream2->_flag2). Most
* of these should never be set when setvbuf() is called, but it
* doesn't cost anything to be safe.
*/
stream->_flag &= ~(_IOMYBUF | _IOYOURBUF | _IONBF |
#ifdef _WIN32
_IOSETVBUF |
#endif /* _WIN32 */
_IOFEOF | _IOFLRTN | _IOCTRLZ);
/*
* CASE 1: No Buffering.
*/
if (type & _IONBF) {
stream->_flag |= _IONBF;
buffer = (char *)&(stream->_charbuf);
#ifdef _WIN32
size = 2;
#else /* _WIN32 */
#if defined (_M_MPPC) || defined (_M_M68K)
size = 1;
#endif /* defined (_M_MPPC) || defined (_M_M68K) */
#endif /* _WIN32 */
}
/*
* NOTE: Cases 2 and 3 (below) cover type == _IOFBF or type == _IOLBF
* Line buffering is treated as the same as full buffering, so the
* _IOLBF bit in stream->_flag is never set. Finally, since _IOFBF is
* defined to be 0, full buffering is simply assumed whenever _IONBF
* is not set.
*/
/*
* CASE 2: Default Buffering -- Allocate a buffer for the user.
*/
else if ( buffer == NULL ) {
if ( (buffer = _malloc_crt(size)) == NULL ) {
#ifndef CRTDLL
/*
* force library pre-termination procedure (placed here
* because the code path should almost never be hit)
*/
_cflush++;
#endif /* CRTDLL */
retval = -1;
goto done;
}
#ifdef _WIN32
stream->_flag |= _IOMYBUF | _IOSETVBUF;
#else /* _WIN32 */
#if defined (_M_MPPC) || defined (_M_M68K)
stream->_flag |= _IOMYBUF;
#endif /* defined (_M_MPPC) || defined (_M_M68K) */
#endif /* _WIN32 */
}
/*
* CASE 3: User Buffering -- Use the buffer supplied by the user.
*/
else {
#ifdef _WIN32
stream->_flag |= _IOYOURBUF | _IOSETVBUF;
#else /* _WIN32 */
#if defined (_M_MPPC) || defined (_M_M68K)
stream->_flag |= _IOYOURBUF;
#endif /* defined (_M_MPPC) || defined (_M_M68K) */
#endif /* _WIN32 */
}
/*
* Common return for all cases.
*/
stream->_bufsiz = size;
stream->_ptr = stream->_base = buffer;
stream->_cnt = 0;
done:
_unlock_str(stream);
return(retval);
}