a047be2a829441f52b59c2caa29c6de1e65fe63b
[reactos.git] / lib / msvcrt / stdio / putc.c
1 /* $Id$
2  *
3  *  ReactOS msvcrt library
4  *
5  *  putc.c
6  *
7  *  Copyright (C) 2002  Robert Dickenson <robd@reactos.org>
8  *
9  *  Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
26
27 #include <windows.h>
28 #include <msvcrt/stdio.h>
29 #include <msvcrt/wchar.h>
30 #include <msvcrt/errno.h>
31 #include <msvcrt/internal/file.h>
32
33 // putc can be a macro
34 #undef putc
35 #undef putwc
36
37 #ifndef MB_CUR_MAX_CONST
38 #define MB_CUR_MAX_CONST 10
39 #endif
40
41 int putc(int c, FILE* fp)
42 {
43     // valid stream macro should check that fp is dword aligned
44     if (!__validfp(fp)) {
45         __set_errno(EINVAL);
46         return EOF;
47     }
48     // check for write access on fp
49     if (!OPEN4WRITING(fp)) {
50         __set_errno(EINVAL);
51         return EOF;
52     }
53     fp->_flag |= _IODIRTY;
54     if (fp->_cnt > 0) {
55         fp->_cnt--;
56         *(fp)->_ptr++ = (unsigned char)c;
57         return (int)(unsigned char)c; 
58     } else {
59         return _flsbuf((unsigned char)c, fp);
60     }
61     return EOF;
62 }
63
64 //wint_t putwc(wint_t c, FILE* fp)
65 /*
66  * @implemented
67  */
68 int putwc(wint_t c, FILE* fp)
69 {
70     // valid stream macro should check that fp is dword aligned
71     if (!__validfp(fp)) {
72         __set_errno(EINVAL);
73         return WEOF;
74     }
75     // check for write access on fp
76     if (!OPEN4WRITING(fp)) {
77         __set_errno(EINVAL);
78         return WEOF;
79     }
80     // might check on multi bytes if text mode
81     if (fp->_flag & _IOBINARY) {
82     //if (1) {
83
84         fp->_flag |= _IODIRTY;
85         if (fp->_cnt > 0) {
86             fp->_cnt -= sizeof(wchar_t);
87             //*((wchar_t*)(fp->_ptr))++ = c;
88             *((wchar_t*)(fp->_ptr)) = c;
89             ++((wchar_t*)(fp->_ptr));
90             return (wint_t)c;
91         } else {
92 #if 1
93             wint_t result;
94             result = _flsbuf(c, fp);
95             if (result == (wint_t)EOF)
96                 return WEOF;
97             result = _flsbuf((int)(c >> 8), fp);
98             if (result == (wint_t)EOF)
99                 return WEOF;
100             return result;
101 #else
102             return _flswbuf(c, fp);
103 #endif
104         }
105
106     } else {
107 #if 0
108         int i;
109         int mb_cnt;
110         char mbchar[MB_CUR_MAX_CONST];
111
112         // Convert wide character to the corresponding multibyte character.
113         mb_cnt = wctomb(mbchar, (wchar_t)c);
114         if (mb_cnt == -1) {
115             fp->_flag |= _IOERR;
116             return WEOF;
117         }
118         if (mb_cnt > MB_CUR_MAX_CONST) {
119             // BARF();
120         }
121         for (i = 0; i < mb_cnt; i++) {
122             fp->_flag |= _IODIRTY;
123             if (fp->_cnt > 0) {
124                 fp->_cnt--;
125                 *(fp)->_ptr++ = (unsigned char)mbchar[i];
126             } else {
127                 if (_flsbuf((unsigned char)mbchar[i], fp) == EOF) {
128                     return WEOF;
129                 }
130             }
131         }
132 #else
133         fp->_flag |= _IODIRTY;
134         if (fp->_cnt > 0) {
135             fp->_cnt--;
136             *(fp)->_ptr++ = (unsigned char)c;
137         } else {
138             if (_flsbuf(c, fp) == EOF) {
139                 return WEOF;
140             }
141         }
142 #endif
143         return c; 
144     }
145     return WEOF;
146 }