]> pd.if.org Git - pdclib.old/blobdiff - functions/stdio/_PDCLIB_flushbuffer.c
flushbuffer: make EOL conversion code more robust against I/O errors
[pdclib.old] / functions / stdio / _PDCLIB_flushbuffer.c
index 44066d87dbd24099d40fe16ca657f25ef786c858..b3357ade950233953a03b74a0a535f63c2816df3 100644 (file)
 #include <_PDCLIB_glue.h>\r
 #include <_PDCLIB_io.h>\r
 \r
+\r
 static int flushsubbuffer( FILE * stream, size_t length )\r
 {\r
+    size_t justWrote;\r
     size_t written = 0;\r
     int rv = 0;\r
 \r
+#if 0\r
+    // Very useful for debugging buffering issues\r
+    char l = '<', r = '>';\r
+    stream->ops->write( stream->handle, &l,  1, &justWrote );\r
+#endif\r
+\r
     while( written != length )\r
     {\r
-        size_t justWrote;\r
         size_t toWrite = length - written;\r
+\r
         bool res = stream->ops->write( stream->handle, stream->buffer + written,\r
                               toWrite, &justWrote);\r
         written += justWrote;\r
@@ -27,55 +35,71 @@ static int flushsubbuffer( FILE * stream, size_t length )
 \r
         if (!res)\r
         {\r
-            stream->status |=_PDCLIB_ERRORFLAG;\r
+            stream->status |= _PDCLIB_ERRORFLAG;\r
             rv = EOF;\r
             break;\r
         }\r
     }\r
 \r
-    stream->bufidx -= written;\r
+#if 0\r
+    stream->ops->write( stream->handle, &r,  1, &justWrote );\r
+#endif\r
+\r
+    stream->bufidx   -= written;\r
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
+    stream->bufnlexp -= written;\r
+#endif\r
     memmove( stream->buffer, stream->buffer + written, stream->bufidx );\r
 \r
     return rv;\r
 }\r
 \r
-#if defined(_PDCLIB_NEED_EOL_TRANSLATION)\r
-#undef  _PDCLIB_NEED_EOL_TRANSLATION\r
-#define _PDCLIB_NEED_EOL_TRANSLATION 1\r
-#else\r
-#define _PDCLIB_NEED_EOL_TRANSLATION 0\r
-#endif\r
-\r
 int _PDCLIB_flushbuffer( FILE * stream )\r
 {\r
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
     // if a text stream, and this platform needs EOL translation, well...\r
-    if ( ! ( stream->status & _PDCLIB_FBIN ) && _PDCLIB_NEED_EOL_TRANSLATION )\r
+    if ( ! ( stream->status & _PDCLIB_FBIN ) )\r
     {\r
-        size_t pos;\r
-        for ( pos = 0; pos < stream->bufidx; pos++ )\r
+        // Special case: buffer is full and we start with a \n\r
+        if ( stream->bufnlexp == 0\r
+            && stream->bufidx == stream->bufend\r
+            && stream->buffer[0] == '\n' )\r
         {\r
-            if (stream->buffer[pos] == '\n' ) {\r
+            char cr = '\r';\r
+            size_t written = 0;\r
+            bool res = stream->ops->write( stream->handle, &cr, 1, &written );\r
+\r
+            if (!res) {\r
+                stream->status |= _PDCLIB_ERRORFLAG;\r
+                return EOF;\r
+            }\r
+\r
+        }\r
+\r
+        for ( ; stream->bufnlexp < stream->bufidx; stream->bufnlexp++ )\r
+        {\r
+            if (stream->buffer[stream->bufnlexp] == '\n' ) {\r
                 if ( stream->bufidx == stream->bufend ) {\r
                     // buffer is full. Need to print out everything up till now\r
-                    if( flushsubbuffer( stream, pos ) )\r
+                    if( flushsubbuffer( stream, stream->bufnlexp - 1 ) )\r
                     {\r
                         return EOF;\r
                     }\r
-\r
-                    pos = 0;\r
                 }\r
 \r
                 // we have spare space in buffer. Shift everything 1char and\r
                 // insert \r\r
-                memmove( &stream->buffer[pos+1], &stream->buffer[pos], stream->bufidx - pos );\r
-                stream->buffer[pos] = '\r';\r
+                memmove( &stream->buffer[stream->bufnlexp + 1],\r
+                         &stream->buffer[stream->bufnlexp],\r
+                         stream->bufidx - stream->bufnlexp );\r
+                stream->buffer[stream->bufnlexp] = '\r';\r
 \r
-                pos += 2;\r
+                stream->bufnlexp++;\r
                 stream->bufidx++;\r
             }\r
         }\r
     }\r
-\r
+#endif\r
     return flushsubbuffer( stream, stream->bufidx );\r
 }\r
 \r