X-Git-Url: https://pd.if.org/git/?p=pdclib.old;a=blobdiff_plain;f=functions%2Fstdio%2F_PDCLIB_flushbuffer.c;h=b3357ade950233953a03b74a0a535f63c2816df3;hp=7ee0d93c35730aa08b1baaa28128d2e735f23f16;hb=d1954049a406af2992113a783539aa5d86cfdfa8;hpb=0e35e82c5e9a0804864839e8fc0e985b1ae41f07 diff --git a/functions/stdio/_PDCLIB_flushbuffer.c b/functions/stdio/_PDCLIB_flushbuffer.c index 7ee0d93..b3357ad 100644 --- a/functions/stdio/_PDCLIB_flushbuffer.c +++ b/functions/stdio/_PDCLIB_flushbuffer.c @@ -11,34 +11,96 @@ #include <_PDCLIB_glue.h> #include <_PDCLIB_io.h> -int _PDCLIB_flushbuffer( FILE * stream ) -{ - if ( ! ( stream->status & _PDCLIB_FBIN ) ) - { - /* TODO: Text stream conversion here */ - } +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; - while(written != stream->bufidx) { - size_t justWrote; - size_t toWrite = stream->bufidx - written; - bool res = stream->ops->write( stream->handle, stream->buffer + 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; - stream->bufidx -= written; - memmove( stream->buffer, stream->buffer + written, stream->bufidx ); - return EOF; + if (!res) + { + stream->status |= _PDCLIB_ERRORFLAG; + rv = EOF; + break; } } - stream->bufidx = 0; - return 0; +#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