]>
git.ipfire.org Git - thirdparty/glibc.git/blob - iconv/gconv_simple.c
1 /* Simple transformations functions.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include <sys/param.h>
29 __gconv_transform_dummy (struct gconv_step
*step
, struct gconv_step_data
*data
,
30 const char *inbuf
, size_t *inlen
, size_t *written
,
35 /* We have no stateful encoding. So we don't have to do anything
41 do_write
= MIN (*inlen
, data
->outbufsize
- data
->outbufavail
);
43 memcpy (data
->outbuf
, inbuf
, do_write
);
46 data
->outbufavail
+= do_write
;
49 /* ### TODO Actually, this number must be devided according to the
50 size of the input charset. I.e., if the input is in UCS4 the
51 number of copied bytes must be divided by 4. */
60 __gconv_transform_init_rstate (struct gconv_step
*step
,
61 struct gconv_step_data
*data
)
63 /* We have to provide the transformation function an correctly initialized
64 object of type `mbstate_t'. This must be dynamically allocated. */
65 data
->data
= calloc (1, sizeof (mbstate_t));
67 return data
->data
== NULL
? GCONV_NOMEM
: GCONV_OK
;
72 __gconv_transform_end_rstate (struct gconv_step_data
*data
)
74 if (data
->data
!= NULL
)
80 __gconv_transform_ucs4_utf8 (struct gconv_step
*step
,
81 struct gconv_step_data
*data
, const char *inbuf
,
82 size_t *inlen
, size_t *written
, int do_flush
)
84 struct gconv_step
*next_step
= step
+ 1;
85 struct gconv_step_data
*next_data
= data
+ 1;
86 gconv_fct fct
= next_step
->fct
;
90 /* If the function is called with no input this means we have to reset
91 to the initial state. The possibly partly converted input is
95 /* Clear the state. */
96 memset (data
->data
, '\0', sizeof (mbstate_t));
99 /* Call the steps down the chain if there are any. */
104 struct gconv_step
*next_step
= step
+ 1;
105 struct gconv_step_data
*next_data
= data
+ 1;
107 result
= (*fct
) (next_step
, next_data
, NULL
, 0, written
, 1);
109 /* Clear output buffer. */
110 data
->outbufavail
= 0;
119 const char *newinbuf
= inbuf
;
120 size_t actually
= __wcsnrtombs (&data
->outbuf
[data
->outbufavail
],
121 (const wchar_t **) &newinbuf
,
122 *inlen
/ sizeof (wchar_t),
123 data
->outbufsize
- data
->outbufavail
,
124 (mbstate_t *) data
->data
);
127 result
= GCONV_EMPTY_INPUT
;
129 /* Remember how much we converted. */
130 do_write
+= newinbuf
- inbuf
;
131 *inlen
-= (newinbuf
- inbuf
) * sizeof (wchar_t);
133 data
->outbufavail
+= actually
;
134 if (data
->outbufavail
> 0)
136 /* Call the functions below in the chain. */
137 size_t newavail
= data
->outbufavail
;
139 result
= (*fct
) (next_step
, next_data
, data
->outbuf
, &newavail
,
142 /* Correct the output buffer. */
143 if (newavail
!= data
->outbufavail
)
145 memmove (data
->outbuf
,
146 &data
->outbuf
[data
->outbufavail
- newavail
],
148 data
->outbufavail
= newavail
;
152 while (*inlen
> 0 && result
== GCONV_EMPTY_INPUT
);
155 if (written
!= NULL
&& data
->is_last
)
156 *written
= do_write
/ sizeof (wchar_t);
163 __gconv_transform_utf8_ucs4 (struct gconv_step
*step
,
164 struct gconv_step_data
*data
, const char *inbuf
,
165 size_t *inlen
, size_t *written
, int do_flush
)
167 struct gconv_step
*next_step
= step
+ 1;
168 struct gconv_step_data
*next_data
= data
+ 1;
169 gconv_fct fct
= next_step
->fct
;
173 /* If the function is called with no input this means we have to reset
174 to the initial state. The possibly partly converted input is
178 /* Clear the state. */
179 memset (data
->data
, '\0', sizeof (mbstate_t));
182 /* Call the steps down the chain if there are any. */
187 struct gconv_step
*next_step
= step
+ 1;
188 struct gconv_step_data
*next_data
= data
+ 1;
190 result
= (*fct
) (next_step
, next_data
, NULL
, 0, written
, 1);
199 const char *newinbuf
= inbuf
;
200 size_t actually
= __mbsnrtowcs ((wchar_t *) &data
->outbuf
[data
->outbufavail
],
205 (mbstate_t *) data
->data
);
208 result
= GCONV_EMPTY_INPUT
;
210 /* Remember how much we converted. */
211 do_write
+= actually
;
212 *inlen
-= newinbuf
- inbuf
;
214 data
->outbufavail
+= actually
* sizeof (wchar_t);
215 if (data
->outbufavail
> 0)
217 /* Call the functions below in the chain. */
218 size_t newavail
= data
->outbufavail
;
220 result
= (*fct
) (next_step
, next_data
, data
->outbuf
, &newavail
,
223 /* Correct the output buffer. */
224 if (newavail
!= data
->outbufavail
)
226 memmove (data
->outbuf
,
227 &data
->outbuf
[data
->outbufavail
- newavail
],
229 data
->outbufavail
= newavail
;
233 while (*inlen
> 0 && result
== GCONV_EMPTY_INPUT
);
236 if (written
!= NULL
&& data
->is_last
)