Added binary and unicode file i/o support to msvcrt.
[reactos.git] / reactos / lib / msvcrt / stdio / putc.c
index 62f31ce..086a148 100644 (file)
@@ -1,4 +1,29 @@
+/* $Id: putc.c,v 1.5 2002/11/24 18:42:24 robd Exp $
+ *
+ *  ReactOS msvcrt library
+ *
+ *  putc.c
+ *
+ *  Copyright (C) 2002  Robert Dickenson <robd@reactos.org>
+ *
+ *  Based on original work Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+
 #include <windows.h>
 #include <msvcrt/stdio.h>
 #include <msvcrt/wchar.h>
 
 // putc can be a macro
 #undef putc
+#undef putwc
+
+#ifndef MB_CUR_MAX_CONST
+#define MB_CUR_MAX_CONST 10
+#endif
 
 int putc(int c, FILE *fp)
 {
-
-// valid stream macro should check that fp 
-// is dword aligned
-       if (!__validfp (fp)) {
-               __set_errno(EINVAL);
-               return -1;
-       }
-// check for write access on fp
-
-       if ( !OPEN4WRITING(fp)  ) {
-               __set_errno(EINVAL);
-               return -1;
-       }
-       
-       fp->_flag |= _IODIRTY;
-       if (fp->_cnt > 0 ) {
-               fp->_cnt--;
-                       *(fp)->_ptr++ = (unsigned char)c;
-               return (int)(unsigned char)c; 
-       }
-       else {
-               return _flsbuf((unsigned char)c,fp);
-       }
-       return EOF;
+    // valid stream macro should check that fp is dword aligned
+    if (!__validfp(fp)) {
+        __set_errno(EINVAL);
+        return EOF;
+    }
+    // check for write access on fp
+    if (!OPEN4WRITING(fp)) {
+        __set_errno(EINVAL);
+        return EOF;
+    }
+    fp->_flag |= _IODIRTY;
+    if (fp->_cnt > 0) {
+        fp->_cnt--;
+        *(fp)->_ptr++ = (unsigned char)c;
+        return (int)(unsigned char)c; 
+    } else {
+        return _flsbuf((unsigned char)c, fp);
+    }
+    return EOF;
 }
 
-wint_t putwc(wint_t c, FILE *fp)
+//wint_t putwc(wint_t c, FILE *fp)
+int putwc(wint_t c, FILE *fp)
 {
-// valid stream macro should check that fp 
-// is dword aligned
-       if (!__validfp (fp)) {
-               __set_errno(EINVAL);
-               return -1;
-       }
-// check for write access on fp
-
-       if ( !OPEN4WRITING(fp)  ) {
-               __set_errno(EINVAL);
-               return -1;
-       }
-       // might check on multi bytes if text mode
+    int i;
+    int mb_cnt;
+    char mbchar[MB_CUR_MAX_CONST];
 
-       fp->_flag |= _IODIRTY;
+    // valid stream macro should check that fp is dword aligned
+    if (!__validfp(fp)) {
+        __set_errno(EINVAL);
+        return WEOF;
+    }
+    // check for write access on fp
+    if (!OPEN4WRITING(fp)) {
+        __set_errno(EINVAL);
+        return WEOF;
+    }
+    // might check on multi bytes if text mode
+    if (fp->_flag & _IOBINARY) {
+    //if (1) {
 
+        fp->_flag |= _IODIRTY;
         if (fp->_cnt > 0 ) {
-                fp->_cnt-= sizeof(wchar_t);
-               *((wchar_t *)(fp->_ptr))++  = c;
-               return (wint_t)c;
+            fp->_cnt -= sizeof(wchar_t);
+            //*((wchar_t*)(fp->_ptr))++ = c;
+            *((wchar_t*)(fp->_ptr)) = c;
+            ++((wchar_t*)(fp->_ptr));
+            return (wint_t)c;
+        } else {
+            return _flswbuf(c, fp);
         }
-        else
-                return  _flswbuf(c,fp);
-
-        return -1;
-
 
+    } else {
+        // Convert wide character to the corresponding multibyte character.
+        mb_cnt = wctomb(mbchar, (wchar_t)c);
+        if (mb_cnt == -1) {
+            fp->_flag |= _IOERR;
+            return WEOF;
+        }
+        if (mb_cnt > MB_CUR_MAX_CONST) {
+            // BARF();
+        }
+        for (i = 0; i < mb_cnt; i++) {
+            fp->_flag |= _IODIRTY;
+#if 0
+            // convert lf's into a cr/lf pair.
+            if (mbchar[i] == '\n') {
+                if (fp->_cnt > 0) {
+                    fp->_cnt--;
+                    *(fp)->_ptr++ = (unsigned char)'\r';
+                } else {
+                    if (_flsbuf((unsigned char)'\r', fp) == EOF) {
+                        return WEOF;
+                    }
+                }
+            }
+#endif
+            if (fp->_cnt > 0) {
+                fp->_cnt--;
+                *(fp)->_ptr++ = (unsigned char)mbchar[i];
+            } else {
+                if (_flsbuf((unsigned char)mbchar[i], fp) == EOF) {
+                    return WEOF;
+                }
+            }
+        }
+        return c; 
+    }
+    return WEOF;
 }