BizHawk/waterbox/libc/functions/stdio/_PDCLIB_flushbuffer.c

120 lines
3.0 KiB
C

/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#include <string.h>
#ifndef REGTEST
#include "_PDCLIB_glue.h"
#include "_PDCLIB_io.h"
static int flushsubbuffer( FILE * stream, size_t length )
{
size_t justWrote;
size_t written = 0;
int rv = 0;
#if 0
// Very useful for debugging buffering issues
char l = '<', r = '>';
stream->ops->write( stream->handle, &l, 1, &justWrote );
#endif
while( written != length )
{
size_t toWrite = length - written;
bool res = stream->ops->write( stream->handle, stream->buffer + written,
toWrite, &justWrote);
written += justWrote;
stream->pos.offset += justWrote;
if (!res)
{
stream->status |= _PDCLIB_ERRORFLAG;
rv = EOF;
break;
}
}
#if 0
stream->ops->write( stream->handle, &r, 1, &justWrote );
#endif
stream->bufidx -= written;
#ifdef _PDCLIB_NEED_EOL_TRANSLATION
stream->bufnlexp -= written;
#endif
memmove( stream->buffer, stream->buffer + written, stream->bufidx );
return rv;
}
int _PDCLIB_flushbuffer( FILE * stream )
{
#ifdef _PDCLIB_NEED_EOL_TRANSLATION
// if a text stream, and this platform needs EOL translation, well...
if ( ! ( stream->status & _PDCLIB_FBIN ) )
{
// Special case: buffer is full and we start with a \n
if ( stream->bufnlexp == 0
&& stream->bufidx == stream->bufend
&& stream->buffer[0] == '\n' )
{
char cr = '\r';
size_t written = 0;
bool res = stream->ops->write( stream->handle, &cr, 1, &written );
if (!res) {
stream->status |= _PDCLIB_ERRORFLAG;
return EOF;
}
}
for ( ; stream->bufnlexp < stream->bufidx; stream->bufnlexp++ )
{
if (stream->buffer[stream->bufnlexp] == '\n' ) {
if ( stream->bufidx == stream->bufend ) {
// buffer is full. Need to print out everything up till now
if( flushsubbuffer( stream, stream->bufnlexp - 1 ) )
{
return EOF;
}
}
// we have spare space in buffer. Shift everything 1char and
// insert \r
memmove( &stream->buffer[stream->bufnlexp + 1],
&stream->buffer[stream->bufnlexp],
stream->bufidx - stream->bufnlexp );
stream->buffer[stream->bufnlexp] = '\r';
stream->bufnlexp++;
stream->bufidx++;
}
}
}
#endif
return flushsubbuffer( stream, stream->bufidx );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c */
return TEST_RESULTS;
}
#endif