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