832672a7b52a71a7d2c36a8881ad438104d6dd6e
[reactos.git] / reactos / 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 }