update for HEAD-2003091401
[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 <msvcrt/stdlib.h>
20 #include <msvcrt/wchar.h>
21
22 #include <msvcrt/errno.h>
23 #include <msvcrt/wchar.h>
24 #include <msvcrt/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 /*
50  * Convert WCHAR into its multibyte character representation,
51  * putting this in S and returning its length.
52  *
53  * Attention: this function should NEVER be intentionally used.
54  * The interface is completely stupid.  The state is shared between
55  * all conversion functions.  You should use instead the restartable
56  * version `wcrtomb'.
57  *
58  * @implemented
59  */
60 int
61 wctomb (char *s, wchar_t wchar)
62 {
63   /* If S is NULL the function has to return null or not null
64      depending on the encoding having a state depending encoding or
65      not.  This is nonsense because any multibyte encoding has a
66      state.  The ISO C amendment 1 corrects this while introducing the
67      restartable functions.  We simply say here all encodings have a
68      state.  */
69   if (s == NULL)
70     return 1;
71
72   return __wcrtomb (s, wchar);
73 }
74
75
76 size_t
77 __wcrtomb (char *s, wchar_t wc)
78 {
79   char fake[1];
80   size_t written = 0;
81
82  
83
84   if (s == NULL)
85     {
86       s = fake;
87       wc = L'\0';
88     }
89
90   /* Store the UTF8 representation of WC.  */
91   if (wc < 0 || wc > 0x7fffffff)
92     {
93       /* This is no correct ISO 10646 character.  */
94       __set_errno (EILSEQ);
95       return (size_t) -1;
96     }
97
98   if (wc < 0x80)
99     {
100       /* It's a one byte sequence.  */
101       if (s != NULL)
102         *s = (char) wc;
103       return 1;
104     }
105
106   for (written = 2; written < 6; ++written)
107     if ((wc & encoding_mask[written - 2]) == 0)
108       break;
109
110   if (s != NULL)
111     {
112       size_t cnt = written;
113       s[0] = encoding_byte[cnt - 2];
114
115       --cnt;
116       do
117         {
118           s[cnt] = 0x80 | (wc & 0x3f);
119           wc >>= 6;
120         }
121       while (--cnt > 0);
122       s[0] |= wc;
123     }
124
125   return written;
126 }