]> pd.if.org Git - pdclib/blob - functions/stdio/_PDCLIB_flushbuffer.c
dos2unix
[pdclib] / functions / stdio / _PDCLIB_flushbuffer.c
1 /* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
2
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #ifndef REGTEST
11 #include "_PDCLIB_glue.h"
12 #include "_PDCLIB_io.h"
13
14
15 static int flushsubbuffer( FILE * stream, size_t length )
16 {
17     size_t justWrote;
18     size_t written = 0;
19     int rv = 0;
20
21 #if 0
22     // Very useful for debugging buffering issues
23     char l = '<', r = '>';
24     stream->ops->write( stream->handle, &l,  1, &justWrote );
25 #endif
26
27     while( written != length )
28     {
29         size_t toWrite = length - written;
30
31         bool res = stream->ops->write( stream->handle, stream->buffer + written,
32                               toWrite, &justWrote);
33         written += justWrote;
34         stream->pos.offset += justWrote;
35
36         if (!res)
37         {
38             stream->status |= _PDCLIB_ERRORFLAG;
39             rv = EOF;
40             break;
41         }
42     }
43
44 #if 0
45     stream->ops->write( stream->handle, &r,  1, &justWrote );
46 #endif
47
48     stream->bufidx   -= written;
49 #ifdef _PDCLIB_NEED_EOL_TRANSLATION
50     stream->bufnlexp -= written;
51 #endif
52     memmove( stream->buffer, stream->buffer + written, stream->bufidx );
53
54     return rv;
55 }
56
57 int _PDCLIB_flushbuffer( FILE * stream )
58 {
59 #ifdef _PDCLIB_NEED_EOL_TRANSLATION
60     // if a text stream, and this platform needs EOL translation, well...
61     if ( ! ( stream->status & _PDCLIB_FBIN ) )
62     {
63         // Special case: buffer is full and we start with a \n
64         if ( stream->bufnlexp == 0
65             && stream->bufidx == stream->bufend
66             && stream->buffer[0] == '\n' )
67         {
68             char cr = '\r';
69             size_t written = 0;
70             bool res = stream->ops->write( stream->handle, &cr, 1, &written );
71
72             if (!res) {
73                 stream->status |= _PDCLIB_ERRORFLAG;
74                 return EOF;
75             }
76
77         }
78
79         for ( ; stream->bufnlexp < stream->bufidx; stream->bufnlexp++ )
80         {
81             if (stream->buffer[stream->bufnlexp] == '\n' ) {
82                 if ( stream->bufidx == stream->bufend ) {
83                     // buffer is full. Need to print out everything up till now
84                     if( flushsubbuffer( stream, stream->bufnlexp - 1 ) )
85                     {
86                         return EOF;
87                     }
88                 }
89
90                 // we have spare space in buffer. Shift everything 1char and
91                 // insert \r
92                 memmove( &stream->buffer[stream->bufnlexp + 1],
93                          &stream->buffer[stream->bufnlexp],
94                          stream->bufidx - stream->bufnlexp );
95                 stream->buffer[stream->bufnlexp] = '\r';
96
97                 stream->bufnlexp++;
98                 stream->bufidx++;
99             }
100         }
101     }
102 #endif
103     return flushsubbuffer( stream, stream->bufidx );
104 }
105
106 #endif
107
108
109 #ifdef TEST
110 #include "_PDCLIB_test.h"
111
112 int main( void )
113 {
114     /* Testing covered by ftell.c */
115     return TEST_RESULTS;
116 }
117
118 #endif
119