]>
Commit | Line | Data |
---|---|---|
5c614849 BK |
1 | /* Copyright (C) 2000 Free Software Foundation, Inc. |
2 | This file is part of the GNU IO Library. | |
3 | ||
4 | This library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU General Public License as | |
6 | published by the Free Software Foundation; either version 2, or (at | |
7 | your option) any later version. | |
8 | ||
9 | This library is distributed in the hope that it will be useful, but | |
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this library; see the file COPYING. If not, write to | |
16 | the Free Software Foundation, 59 Temple Place - Suite 330, Boston, | |
17 | MA 02111-1307, USA. | |
18 | ||
19 | As a special exception, if you link this library with files | |
20 | compiled with a GNU compiler to produce an executable, this does | |
21 | not cause the resulting executable to be covered by the GNU General | |
22 | Public License. This exception does not however invalidate any | |
23 | other reasons why the executable file might be covered by the GNU | |
24 | General Public License. */ | |
25 | ||
26 | /* Slightly modified from glibc/libio/iofwide.c */ | |
27 | ||
28 | #include <libio.h> | |
29 | ||
30 | ||
31 | /* Prototypes of libio's codecvt functions. */ | |
32 | static enum __codecvt_result | |
33 | do_out(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
34 | const wchar_t *from_start, const wchar_t *from_end, | |
35 | const wchar_t **from_stop, char *to_start, char *to_end, | |
36 | char **to_stop); | |
37 | ||
38 | static enum __codecvt_result | |
39 | do_unshift(struct _IO_codecvt *codecvt, __mbstate_t *statep, char *to_start, | |
40 | char *to_end, char **to_stop); | |
41 | ||
42 | static enum __codecvt_result | |
43 | do_in(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
44 | const char *from_start, const char *from_end, const char **from_stop, | |
45 | wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop); | |
46 | ||
47 | static int | |
48 | do_encoding(struct _IO_codecvt *codecvt); | |
49 | ||
50 | static int | |
51 | do_length(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
52 | const char *from_start, const char *from_end, _IO_size_t max); | |
53 | ||
54 | static int | |
55 | do_max_length(struct _IO_codecvt *codecvt); | |
56 | ||
57 | static int | |
58 | do_always_noconv(struct _IO_codecvt *codecvt); | |
59 | ||
60 | ||
61 | /* The functions used in `codecvt' for libio are always the same. */ | |
62 | struct _IO_codecvt __c_libio_codecvt = | |
63 | { | |
64 | .__codecvt_destr = NULL, /* Destructor, never used. */ | |
65 | .__codecvt_do_out = do_out, | |
66 | .__codecvt_do_unshift = do_unshift, | |
67 | .__codecvt_do_in = do_in, | |
68 | .__codecvt_do_encoding = do_encoding, | |
69 | .__codecvt_do_always_noconv = do_always_noconv, | |
70 | .__codecvt_do_length = do_length, | |
71 | .__codecvt_do_max_length = do_max_length | |
72 | }; | |
73 | ||
74 | static enum __codecvt_result | |
75 | do_out(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
76 | const wchar_t *from_start, const wchar_t *from_end, | |
77 | const wchar_t **from_stop, char *to_start, char *to_end, | |
78 | char **to_stop) | |
79 | { | |
80 | enum __codecvt_result res = __codecvt_ok; | |
81 | ||
82 | while (from_start < from_end) | |
83 | { | |
84 | if (to_start >= to_end) | |
85 | { | |
86 | res = __codecvt_partial; | |
87 | break; | |
88 | } | |
89 | *to_start++ = (char) *from_start++; | |
90 | } | |
91 | ||
92 | *from_stop = from_start; | |
93 | *to_stop = to_start; | |
94 | ||
95 | return res; | |
96 | } | |
97 | ||
98 | ||
99 | static enum __codecvt_result | |
100 | do_unshift(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
101 | char *to_start, char *to_end, char **to_stop) | |
102 | { | |
103 | *to_stop = to_start; | |
104 | return __codecvt_ok; | |
105 | } | |
106 | ||
107 | ||
108 | static enum __codecvt_result | |
109 | do_in(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
110 | const char *from_start, const char *from_end, const char **from_stop, | |
111 | wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) | |
112 | { | |
113 | enum __codecvt_result res = __codecvt_ok; | |
114 | ||
115 | while (from_start < from_end) | |
116 | { | |
117 | if (to_start >= to_end) | |
118 | { | |
119 | res = __codecvt_partial; | |
120 | break; | |
121 | } | |
122 | *to_start++ = (wchar_t) *from_start++; | |
123 | } | |
124 | ||
125 | *from_stop = from_start; | |
126 | *to_stop = to_start; | |
127 | ||
128 | return res; | |
129 | } | |
130 | ||
131 | ||
132 | static int | |
133 | do_encoding(struct _IO_codecvt *codecvt) | |
134 | { return 1; } | |
135 | ||
136 | ||
137 | static int | |
138 | do_always_noconv(struct _IO_codecvt *codecvt) | |
139 | { return 0; } | |
140 | ||
141 | ||
142 | static int | |
143 | do_length(struct _IO_codecvt *codecvt, __mbstate_t *statep, | |
144 | const char *from_start, const char *from_end, _IO_size_t max) | |
145 | { return from_end - from_start; } | |
146 | ||
147 | ||
148 | static int | |
149 | do_max_length(struct _IO_codecvt *codecvt) | |
150 | { return 1; } |