:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / crtdll / stdlib / wcstomb.c
1 /* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <crtdll/stdlib.h>
20 #include <crtdll/wchar.h>
21
22 #include <crtdll/errno.h>
23 #include <crtdll/wchar.h>
24 #include <crtdll/internal/file.h>
25
26 #ifndef EILSEQ
27 #define EILSEQ EINVAL
28 #endif
29
30 static const wchar_t encoding_mask[] =
31 {
32   (wchar_t)~0x7ff, (wchar_t)~0xffff, (wchar_t)~0x1fffff, (wchar_t)~0x3ffffff
33 };
34
35 static const unsigned char encoding_byte[] =
36 {
37   0xc0, 0xe0, 0xf0, 0xf8, 0xfc
38 };
39
40 /* The state is for this UTF8 encoding not used.  */
41 //static mbstate_t internal;
42
43
44 //extern mbstate_t __no_r_state;  /* Defined in mbtowc.c.  */
45
46 size_t
47 __wcrtomb (char *s, wchar_t wc);
48
49 /* Convert WCHAR into its multibyte character representation,
50    putting this in S and returning its length.
51
52    Attention: this function should NEVER be intentionally used.
53    The interface is completely stupid.  The state is shared between
54    all conversion functions.  You should use instead the restartable
55    version `wcrtomb'.  */
56 int
57 wctomb (char *s, wchar_t wchar)
58 {
59   /* If S is NULL the function has to return null or not null
60      depending on the encoding having a state depending encoding or
61      not.  This is nonsense because any multibyte encoding has a
62      state.  The ISO C amendment 1 corrects this while introducing the
63      restartable functions.  We simply say here all encodings have a
64      state.  */
65   if (s == NULL)
66     return 1;
67
68   return __wcrtomb (s, wchar);
69 }
70
71
72 size_t
73 __wcrtomb (char *s, wchar_t wc)
74 {
75   char fake[1];
76   size_t written = 0;
77
78  
79
80   if (s == NULL)
81     {
82       s = fake;
83       wc = L'\0';
84     }
85
86   /* Store the UTF8 representation of WC.  */
87   if (wc < 0 || wc > 0x7fffffff)
88     {
89       /* This is no correct ISO 10646 character.  */
90       __set_errno (EILSEQ);
91       return (size_t) -1;
92     }
93
94   if (wc < 0x80)
95     {
96       /* It's a one byte sequence.  */
97       if (s != NULL)
98         *s = (char) wc;
99       return 1;
100     }
101
102   for (written = 2; written < 6; ++written)
103     if ((wc & encoding_mask[written - 2]) == 0)
104       break;
105
106   if (s != NULL)
107     {
108       size_t cnt = written;
109       s[0] = encoding_byte[cnt - 2];
110
111       --cnt;
112       do
113         {
114           s[cnt] = 0x80 | (wc & 0x3f);
115           wc >>= 6;
116         }
117       while (--cnt > 0);
118       s[0] |= wc;
119     }
120
121   return written;
122 }