X-Git-Url: https://pd.if.org/git/?p=pdclib;a=blobdiff_plain;f=functions%2Fstdio%2F_PDCLIB_flushbuffer.c;h=e7cf47c3549cad4d09e3687ec448666c0d450623;hp=44066d87dbd24099d40fe16ca657f25ef786c858;hb=abc15df6b9fae3374d24c7cf5c3ab94c605b2a6d;hpb=8ca96563618e4dd6cd092533711e4188c846c418 diff --git a/functions/stdio/_PDCLIB_flushbuffer.c b/functions/stdio/_PDCLIB_flushbuffer.c index 44066d8..e7cf47c 100644 --- a/functions/stdio/_PDCLIB_flushbuffer.c +++ b/functions/stdio/_PDCLIB_flushbuffer.c @@ -1,95 +1,119 @@ -/* _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 -#include - -#ifndef REGTEST -#include <_PDCLIB_glue.h> -#include <_PDCLIB_io.h> - -static int flushsubbuffer( FILE * stream, size_t length ) -{ - size_t written = 0; - int rv = 0; - - while( written != length ) - { - size_t justWrote; - 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; - } - } - - stream->bufidx -= written; - memmove( stream->buffer, stream->buffer + written, stream->bufidx ); - - return rv; -} - -#if defined(_PDCLIB_NEED_EOL_TRANSLATION) -#undef _PDCLIB_NEED_EOL_TRANSLATION -#define _PDCLIB_NEED_EOL_TRANSLATION 1 -#else -#define _PDCLIB_NEED_EOL_TRANSLATION 0 -#endif - -int _PDCLIB_flushbuffer( FILE * stream ) -{ - // if a text stream, and this platform needs EOL translation, well... - if ( ! ( stream->status & _PDCLIB_FBIN ) && _PDCLIB_NEED_EOL_TRANSLATION ) - { - size_t pos; - for ( pos = 0; pos < stream->bufidx; pos++ ) - { - if (stream->buffer[pos] == '\n' ) { - if ( stream->bufidx == stream->bufend ) { - // buffer is full. Need to print out everything up till now - if( flushsubbuffer( stream, pos ) ) - { - return EOF; - } - - pos = 0; - } - - // we have spare space in buffer. Shift everything 1char and - // insert \r - memmove( &stream->buffer[pos+1], &stream->buffer[pos], stream->bufidx - pos ); - stream->buffer[pos] = '\r'; - - pos += 2; - stream->bufidx++; - } - } - } - - return flushsubbuffer( stream, stream->bufidx ); -} - -#endif - - -#ifdef TEST -#include <_PDCLIB_test.h> - -int main( void ) -{ - /* Testing covered by ftell.c */ - return TEST_RESULTS; -} - -#endif - +/* _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 +#include + +#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 +