:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / msvcrt / stdio / flsbuf.c
1 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
2 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
3
4 #include <msvcrt/stdio.h>
5 #include <msvcrt/wchar.h>
6 #include <msvcrt/sys/types.h>
7 #include <msvcrt/stdlib.h>
8 #include <msvcrt/internal/file.h>
9 #include <msvcrt/io.h>
10 #include <msvcrt/errno.h>
11
12 int cntcr(char *bufp, int bufsiz);
13 int convert(char *endp, int bufsiz,int n);
14 int _writecnv(int fn, void *buf, size_t bufsiz);
15
16 int
17 _flsbuf(int c, FILE *f)
18 {
19   char *base;
20   int n, rn;
21   char c1;
22   int size;
23
24
25
26   if (!OPEN4WRITING(f)) {
27         __set_errno (EINVAL);
28         return EOF;
29   }
30
31 // no file associated with buffer
32 // this is a memory stream
33
34   if ( fileno(f) == -1 )
35         return c;
36
37   /* if the buffer is not yet allocated, allocate it */
38   if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0)
39   {
40     size = 4096;
41     if ((f->_base = base = malloc (size)) == NULL)
42     {
43       f->_flag |= _IONBF;
44       f->_flag &= ~(_IOFBF|_IOLBF);
45     }
46     else
47     {
48       f->_flag |= _IOMYBUF;
49       f->_cnt = f->_bufsiz = size;
50       f->_ptr = base;
51       rn = 0;
52       if (f == stdout && isatty (fileno (stdout)))
53         f->_flag |= _IOLBF;
54     }
55   }
56
57   if (f->_flag & _IOLBF)
58   {
59     /* in line-buffering mode we get here on each character */
60     *f->_ptr++ = c;
61     rn = f->_ptr - base;
62     if (c == '\n' || rn >= f->_bufsiz)
63     {
64       /* time for real flush */
65       f->_ptr = base;
66       f->_cnt = 0;
67     }
68     else
69     {
70       /* we got here because _cnt is wrong, so fix it */
71       /* Negative _cnt causes all output functions
72         to call _flsbuf for each character, thus realizing line-buffering */
73       f->_cnt = -rn;
74       return c;
75     }
76   }
77   else if (f->_flag & _IONBF)
78   {                   
79     c1 = c;           
80     rn = 1;           
81     base = &c1;       
82     f->_cnt = 0;
83   }                   
84   else /* _IOFBF */
85   {
86     rn = f->_ptr - base;
87     f->_ptr = base;
88     if ( (f->_flag & _IOAHEAD) == _IOAHEAD )
89         _lseek(fileno(f),-(rn+f->_cnt), SEEK_CUR);
90     f->_cnt = f->_bufsiz;
91     f->_flag &= ~_IOAHEAD;
92   }
93
94  
95
96   f->_flag &= ~_IODIRTY;
97   while (rn > 0)
98   {
99     n = _write(fileno(f), base, rn);
100     if (n <= 0)
101     {
102       f->_flag |= _IOERR;
103       return EOF;
104     }
105     rn -= n;
106     base += n;
107   }
108
109
110   if ((f->_flag&(_IOLBF|_IONBF)) == 0)
111   {
112     f->_cnt--;
113     *f->_ptr++ = c;
114   }
115   return c;
116 }
117
118 wint_t  _flswbuf(wchar_t c,FILE *fp)
119 {
120         return (wint_t )_flsbuf((int)c,fp);
121 }
122
123
124 int _writecnv(int fn, void *buf, size_t siz)
125 {
126         char *bufp = (char *)buf;
127         int bufsiz = siz;
128
129         char *tmp;
130         int cr1 = 0;
131         int cr2 = 0;
132
133         int n;
134                 
135
136         cr1 = cntcr(bufp,bufsiz);
137
138         tmp = malloc(cr1);
139         memcpy(tmp,bufp+bufsiz-cr1,cr1);
140         cr2 = cntcr(tmp,cr1);
141                 
142         convert(bufp,bufsiz-cr2,cr1-cr2);
143         n = _write(fn, bufp, bufsiz + cr1);
144
145         convert(tmp,cr1,cr2);
146         n += _write(fn, tmp, cr1 + cr2);
147         free(tmp);
148         return n;       
149         
150
151 }
152
153 int convert(char *endp, int bufsiz,int n)
154 {       
155         endp = endp + bufsiz + n;
156         while (bufsiz > 0) {
157                 *endp = *(endp  - n);
158                 if (*endp == '\n') {
159                         *endp--;
160                         n--;
161                         *endp = '\r';
162                 }
163                 endp--;
164                 bufsiz--;
165         }
166         return n;
167 }
168 int cntcr(char *bufp, int bufsiz)
169 {
170         int cr = 0; 
171         while (bufsiz > 0) {
172                 if (*bufp == '\n') 
173                         cr++;
174                 bufp++;
175                 bufsiz--;
176         }
177
178         return cr;
179 }