]> pd.if.org Git - pdclib/blobdiff - functions/stdio/_PDCLIB_flushbuffer.c
dos2unix
[pdclib] / functions / stdio / _PDCLIB_flushbuffer.c
index ffbbb4f088c88ef84767a056e3570fd7c78055a4..e7cf47c3549cad4d09e3687ec448666c0d450623 100644 (file)
-/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#ifndef REGTEST\r
-#include <_PDCLIB_glue.h>\r
-\r
-int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )\r
-{\r
-    if ( ! ( stream->status & _PDCLIB_FBIN ) )\r
-    {\r
-        /* TODO: Text stream conversion here */\r
-    }\r
-\r
-    size_t written = 0;\r
-\r
-\r
-    while(written != stream->bufidx) {\r
-        size_t justWrote;\r
-        size_t toWrite = stream->bufidx - written;\r
-        bool res = stream->ops->write( stream->handle, stream->buffer + written, \r
-                              toWrite, &justWrote);\r
-        written += justWrote;\r
-        stream->pos.offset += justWrote;\r
-\r
-        if(!res) {\r
-            stream->status |=_PDCLIB_ERRORFLAG;\r
-            stream->bufidx -= written;\r
-            memmove( stream->buffer, stream->buffer + written, stream->bufidx );\r
-            return EOF;\r
-        }\r
-    }\r
-\r
-    stream->bufidx = 0;\r
-    return 0;\r
-}\r
-\r
-#endif\r
-\r
-\r
-#ifdef TEST\r
-#include <_PDCLIB_test.h>\r
-\r
-int main( void )\r
-{\r
-    /* Testing covered by ftell.c */\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
-\r
+/* _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
+