Include gconv_builtin.h to get prototypes for loop functions.
[kopensolaris-gnu/glibc.git] / iconv / gconv_simple.c
1 /* Simple transformations functions.
2    Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
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.
10
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.
15
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.  */
20
21 #include <byteswap.h>
22 #include <dlfcn.h>
23 #include <endian.h>
24 #include <errno.h>
25 #include <gconv.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <wchar.h>
30 #include <sys/param.h>
31
32 #define BUILTIN_ALIAS(s1, s2) /* nothing */
33 #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, Init, End, MinF, \
34                                MaxF, MinT, MaxT) \
35   extern int Fct (struct __gconv_step *, struct __gconv_step_data *,          \
36                   __const unsigned char **, __const unsigned char *,          \
37                   unsigned char **, size_t *, int, int);
38 #include "gconv_builtin.h"
39
40
41 #ifndef EILSEQ
42 # define EILSEQ EINVAL
43 #endif
44
45
46 /* Transform from the internal, UCS4-like format, to UCS4.  The
47    difference between the internal ucs4 format and the real UCS4
48    format is, if any, the endianess.  The Unicode/ISO 10646 says that
49    unless some higher protocol specifies it differently, the byte
50    order is big endian.*/
51 #define DEFINE_INIT             0
52 #define DEFINE_FINI             0
53 #define MIN_NEEDED_FROM         4
54 #define MIN_NEEDED_TO           4
55 #define FROM_DIRECTION          1
56 #define FROM_LOOP               internal_ucs4_loop
57 #define TO_LOOP                 internal_ucs4_loop /* This is not used.  */
58 #define FUNCTION_NAME           __gconv_transform_internal_ucs4
59
60
61 static inline int
62 internal_ucs4_loop (struct __gconv_step *step,
63                     struct __gconv_step_data *step_data,
64                     const unsigned char **inptrp, const unsigned char *inend,
65                     unsigned char **outptrp, unsigned char *outend,
66                     size_t *irreversible)
67 {
68   const unsigned char *inptr = *inptrp;
69   unsigned char *outptr = *outptrp;
70   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
71   int result;
72
73 #if __BYTE_ORDER == __LITTLE_ENDIAN
74   /* Sigh, we have to do some real work.  */
75   size_t cnt;
76
77   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
78     *((uint32_t *) outptr)++ = bswap_32 (*(const uint32_t *) inptr);
79
80   *inptrp = inptr;
81   *outptrp = outptr;
82 #elif __BYTE_ORDER == __BIG_ENDIAN
83   /* Simply copy the data.  */
84   *inptrp = inptr + n_convert * 4;
85   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
86 #else
87 # error "This endianess is not supported."
88 #endif
89
90   /* Determine the status.  */
91   if (*inptrp == inend)
92     result = __GCONV_EMPTY_INPUT;
93   else if (*outptrp == outend)
94     result = __GCONV_FULL_OUTPUT;
95   else
96     result = __GCONV_INCOMPLETE_INPUT;
97
98   return result;
99 }
100
101 #ifndef _STRING_ARCH_unaligned
102 static inline int
103 internal_ucs4_loop_unaligned (struct __gconv_step *step,
104                               struct __gconv_step_data *step_data,
105                               const unsigned char **inptrp,
106                               const unsigned char *inend,
107                               unsigned char **outptrp, unsigned char *outend,
108                               size_t *irreversible)
109 {
110   const unsigned char *inptr = *inptrp;
111   unsigned char *outptr = *outptrp;
112   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
113   int result;
114
115 # if __BYTE_ORDER == __LITTLE_ENDIAN
116   /* Sigh, we have to do some real work.  */
117   size_t cnt;
118
119   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
120     {
121       outptr[0] = inptr[3];
122       outptr[1] = inptr[2];
123       outptr[2] = inptr[1];
124       outptr[3] = inptr[0];
125     }
126
127   *inptrp = inptr;
128   *outptrp = outptr;
129 # elif __BYTE_ORDER == __BIG_ENDIAN
130   /* Simply copy the data.  */
131   *inptrp = inptr + n_convert * 4;
132   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
133 # else
134 #  error "This endianess is not supported."
135 # endif
136
137   /* Determine the status.  */
138   if (*outptrp == outend)
139     result = __GCONV_FULL_OUTPUT;
140   else if (*inptrp == inend)
141     result = __GCONV_EMPTY_INPUT;
142   else
143     result = __GCONV_INCOMPLETE_INPUT;
144
145   return result;
146 }
147 #endif
148
149
150 static inline int
151 internal_ucs4_loop_single (struct __gconv_step *step,
152                            struct __gconv_step_data *step_data,
153                            const unsigned char **inptrp,
154                            const unsigned char *inend,
155                            unsigned char **outptrp, unsigned char *outend,
156                            size_t *irreversible)
157 {
158   mbstate_t *state = step_data->__statep;
159   size_t cnt = state->__count & 7;
160
161   while (*inptrp < inend && cnt < 4)
162     state->__value.__wchb[cnt++] = *(*inptrp)++;
163
164   if (__builtin_expect (cnt, 4) < 4)
165     {
166       /* Still not enough bytes.  Store the ones in the input buffer.  */
167       state->__count &= ~7;
168       state->__count |= cnt;
169
170       return __GCONV_INCOMPLETE_INPUT;
171     }
172
173 #if __BYTE_ORDER == __LITTLE_ENDIAN
174   (*outptrp)[0] = state->__value.__wchb[3];
175   (*outptrp)[1] = state->__value.__wchb[2];
176   (*outptrp)[2] = state->__value.__wchb[1];
177   (*outptrp)[3] = state->__value.__wchb[0];
178
179   *outptrp += 4;
180 #elif __BYTE_ORDER == __BIG_ENDIAN
181   /* XXX unaligned */
182   *(*((uint32_t **) outptrp)++) = state->__value.__wch;
183 #else
184 # error "This endianess is not supported."
185 #endif
186
187   /* Clear the state buffer.  */
188   state->__count &= ~7;
189
190   return __GCONV_OK;
191 }
192
193 #include <iconv/skeleton.c>
194
195
196 /* Transform from UCS4 to the internal, UCS4-like format.  Unlike
197    for the other direction we have to check for correct values here.  */
198 #define DEFINE_INIT             0
199 #define DEFINE_FINI             0
200 #define MIN_NEEDED_FROM         4
201 #define MIN_NEEDED_TO           4
202 #define FROM_DIRECTION          1
203 #define FROM_LOOP               ucs4_internal_loop
204 #define TO_LOOP                 ucs4_internal_loop /* This is not used.  */
205 #define FUNCTION_NAME           __gconv_transform_ucs4_internal
206
207
208 static inline int
209 ucs4_internal_loop (struct __gconv_step *step,
210                     struct __gconv_step_data *step_data,
211                     const unsigned char **inptrp, const unsigned char *inend,
212                     unsigned char **outptrp, unsigned char *outend,
213                     size_t *irreversible)
214 {
215   int flags = step_data->__flags;
216   const unsigned char *inptr = *inptrp;
217   unsigned char *outptr = *outptrp;
218   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
219   int result;
220   size_t cnt;
221
222   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
223     {
224       uint32_t inval;
225
226 #if __BYTE_ORDER == __LITTLE_ENDIAN
227       inval = bswap_32 (*(const uint32_t *) inptr);
228 #else
229       inval = *(const uint32_t *) inptr;
230 #endif
231
232       if (__builtin_expect (inval, 0) > 0x7fffffff)
233         {
234           /* The value is too large.  We don't try transliteration here since
235              this is not an error because of the lack of possibilities to
236              represent the result.  This is a genuine bug in the input since
237              UCS4 does not allow such values.  */
238           if (irreversible == NULL)
239             /* We are transliterating, don't try to correct anything.  */
240             return __GCONV_ILLEGAL_INPUT;
241
242           if (flags & __GCONV_IGNORE_ERRORS)
243             {
244               /* Just ignore this character.  */
245               ++*irreversible;
246               continue;
247             }
248
249           *inptrp = inptr;
250           *outptrp = outptr;
251           return __GCONV_ILLEGAL_INPUT;
252         }
253
254       *((uint32_t *) outptr)++ = inval;
255     }
256
257   *inptrp = inptr;
258   *outptrp = outptr;
259
260   /* Determine the status.  */
261   if (*inptrp == inend)
262     result = __GCONV_EMPTY_INPUT;
263   else if (*outptrp == outend)
264     result = __GCONV_FULL_OUTPUT;
265   else
266     result = __GCONV_INCOMPLETE_INPUT;
267
268   return result;
269 }
270
271 #ifndef _STRING_ARCH_unaligned
272 static inline int
273 ucs4_internal_loop_unaligned (struct __gconv_step *step,
274                               struct __gconv_step_data *step_data,
275                               const unsigned char **inptrp,
276                               const unsigned char *inend,
277                               unsigned char **outptrp, unsigned char *outend,
278                               size_t *irreversible)
279 {
280   int flags = step_data->__flags;
281   const unsigned char *inptr = *inptrp;
282   unsigned char *outptr = *outptrp;
283   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
284   int result;
285   size_t cnt;
286
287   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
288     {
289       if (__builtin_expect (inptr[0], 0) > 0x80)
290         {
291           /* The value is too large.  We don't try transliteration here since
292              this is not an error because of the lack of possibilities to
293              represent the result.  This is a genuine bug in the input since
294              UCS4 does not allow such values.  */
295           if (irreversible == NULL)
296             /* We are transliterating, don't try to correct anything.  */
297             return __GCONV_ILLEGAL_INPUT;
298
299           if (flags & __GCONV_IGNORE_ERRORS)
300             {
301               /* Just ignore this character.  */
302               ++*irreversible;
303               continue;
304             }
305
306           *inptrp = inptr;
307           *outptrp = outptr;
308           return __GCONV_ILLEGAL_INPUT;
309         }
310
311 # if __BYTE_ORDER == __LITTLE_ENDIAN
312       outptr[3] = inptr[0];
313       outptr[2] = inptr[1];
314       outptr[1] = inptr[2];
315       outptr[0] = inptr[3];
316 # else
317       outptr[0] = inptr[0];
318       outptr[1] = inptr[1];
319       outptr[2] = inptr[2];
320       outptr[3] = inptr[3];
321 # endif
322       outptr += 4;
323     }
324
325   *inptrp = inptr;
326   *outptrp = outptr;
327
328   /* Determine the status.  */
329   if (*inptrp == inend)
330     result = __GCONV_EMPTY_INPUT;
331   else if (*outptrp == outend)
332     result = __GCONV_FULL_OUTPUT;
333   else
334     result = __GCONV_INCOMPLETE_INPUT;
335
336   return result;
337 }
338 #endif
339
340
341 static inline int
342 ucs4_internal_loop_single (struct __gconv_step *step,
343                            struct __gconv_step_data *step_data,
344                            const unsigned char **inptrp,
345                            const unsigned char *inend,
346                            unsigned char **outptrp, unsigned char *outend,
347                            size_t *irreversible)
348 {
349   mbstate_t *state = step_data->__statep;
350   int flags = step_data->__flags;
351   size_t cnt = state->__count & 7;
352
353   while (*inptrp < inend && cnt < 4)
354     state->__value.__wchb[cnt++] = *(*inptrp)++;
355
356   if (__builtin_expect (cnt, 4) < 4)
357     {
358       /* Still not enough bytes.  Store the ones in the input buffer.  */
359       state->__count &= ~7;
360       state->__count |= cnt;
361
362       return __GCONV_INCOMPLETE_INPUT;
363     }
364
365   if (__builtin_expect (((unsigned char *) state->__value.__wchb)[0], 0)
366       > 0x80)
367     {
368       /* The value is too large.  We don't try transliteration here since
369          this is not an error because of the lack of possibilities to
370          represent the result.  This is a genuine bug in the input since
371          UCS4 does not allow such values.  */
372       if (!(flags & __GCONV_IGNORE_ERRORS))
373         {
374           *inptrp -= cnt - (state->__count & 7);
375           return __GCONV_ILLEGAL_INPUT;
376         }
377     }
378   else
379     {
380 #if __BYTE_ORDER == __LITTLE_ENDIAN
381       (*outptrp)[0] = state->__value.__wchb[3];
382       (*outptrp)[1] = state->__value.__wchb[2];
383       (*outptrp)[2] = state->__value.__wchb[1];
384       (*outptrp)[3] = state->__value.__wchb[0];
385 #elif __BYTE_ORDER == __BIG_ENDIAN
386       (*outptrp)[0] = state->__value.__wchb[0];
387       (*outptrp)[1] = state->__value.__wchb[1];
388       (*outptrp)[2] = state->__value.__wchb[2];
389       (*outptrp)[3] = state->__value.__wchb[3];
390 #endif
391
392       *outptrp += 4;
393     }
394
395   /* Clear the state buffer.  */
396   state->__count &= ~7;
397
398   return __GCONV_OK;
399 }
400
401 #include <iconv/skeleton.c>
402
403
404 /* Similarly for the little endian form.  */
405 #define DEFINE_INIT             0
406 #define DEFINE_FINI             0
407 #define MIN_NEEDED_FROM         4
408 #define MIN_NEEDED_TO           4
409 #define FROM_DIRECTION          1
410 #define FROM_LOOP               internal_ucs4le_loop
411 #define TO_LOOP                 internal_ucs4le_loop /* This is not used.  */
412 #define FUNCTION_NAME           __gconv_transform_internal_ucs4le
413
414
415 static inline int
416 internal_ucs4le_loop (struct __gconv_step *step,
417                       struct __gconv_step_data *step_data,
418                       const unsigned char **inptrp, const unsigned char *inend,
419                       unsigned char **outptrp, unsigned char *outend,
420                       size_t *irreversible)
421 {
422   const unsigned char *inptr = *inptrp;
423   unsigned char *outptr = *outptrp;
424   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
425   int result;
426
427 #if __BYTE_ORDER == __BIG_ENDIAN
428   /* Sigh, we have to do some real work.  */
429   size_t cnt;
430
431   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
432     *((uint32_t *) outptr)++ = bswap_32 (*(const uint32_t *) inptr);
433
434   *inptrp = inptr;
435   *outptrp = outptr;
436 #elif __BYTE_ORDER == __LITTLE_ENDIAN
437   /* Simply copy the data.  */
438   *inptrp = inptr + n_convert * 4;
439   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
440 #else
441 # error "This endianess is not supported."
442 #endif
443
444   /* Determine the status.  */
445   if (*inptrp == inend)
446     result = __GCONV_EMPTY_INPUT;
447   else if (*outptrp == outend)
448     result = __GCONV_FULL_OUTPUT;
449   else
450     result = __GCONV_INCOMPLETE_INPUT;
451
452   return result;
453 }
454
455 #ifndef _STRING_ARCH_unaligned
456 static inline int
457 internal_ucs4le_loop_unaligned (struct __gconv_step *step,
458                                 struct __gconv_step_data *step_data,
459                                 const unsigned char **inptrp,
460                                 const unsigned char *inend,
461                                 unsigned char **outptrp, unsigned char *outend,
462                                 size_t *irreversible)
463 {
464   const unsigned char *inptr = *inptrp;
465   unsigned char *outptr = *outptrp;
466   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
467   int result;
468
469 # if __BYTE_ORDER == __BIG_ENDIAN
470   /* Sigh, we have to do some real work.  */
471   size_t cnt;
472
473   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
474     {
475       outptr[0] = inptr[3];
476       outptr[1] = inptr[2];
477       outptr[2] = inptr[1];
478       outptr[3] = inptr[0];
479     }
480
481   *inptrp = inptr;
482   *outptrp = outptr;
483 # elif __BYTE_ORDER == __LITTLE_ENDIAN
484   /* Simply copy the data.  */
485   *inptrp = inptr + n_convert * 4;
486   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
487 # else
488 #  error "This endianess is not supported."
489 # endif
490
491   /* Determine the status.  */
492   if (*inptrp == inend)
493     result = __GCONV_EMPTY_INPUT;
494   else if (*outptrp == outend)
495     result = __GCONV_FULL_OUTPUT;
496   else
497     result = __GCONV_INCOMPLETE_INPUT;
498
499   return result;
500 }
501 #endif
502
503
504 static inline int
505 internal_ucs4le_loop_single (struct __gconv_step *step,
506                              struct __gconv_step_data *step_data,
507                              const unsigned char **inptrp,
508                              const unsigned char *inend,
509                              unsigned char **outptrp, unsigned char *outend,
510                              size_t *irreversible)
511 {
512   mbstate_t *state = step_data->__statep;
513   size_t cnt = state->__count & 7;
514
515   while (*inptrp < inend && cnt < 4)
516     state->__value.__wchb[cnt++] = *(*inptrp)++;
517
518   if (__builtin_expect (cnt, 4) < 4)
519     {
520       /* Still not enough bytes.  Store the ones in the input buffer.  */
521       state->__count &= ~7;
522       state->__count |= cnt;
523
524       return __GCONV_INCOMPLETE_INPUT;
525     }
526
527 #if __BYTE_ORDER == __BIG_ENDIAN
528   (*outptrp)[0] = state->__value.__wchb[3];
529   (*outptrp)[1] = state->__value.__wchb[2];
530   (*outptrp)[2] = state->__value.__wchb[1];
531   (*outptrp)[3] = state->__value.__wchb[0];
532
533   *outptrp += 4;
534 #else
535   /* XXX unaligned */
536   *(*((uint32_t **) outptrp)++) = state->__value.__wch;
537 #endif
538
539   /* Clear the state buffer.  */
540   state->__count &= ~7;
541
542   return __GCONV_OK;
543 }
544
545 #include <iconv/skeleton.c>
546
547
548 /* And finally from UCS4-LE to the internal encoding.  */
549 #define DEFINE_INIT             0
550 #define DEFINE_FINI             0
551 #define MIN_NEEDED_FROM         4
552 #define MIN_NEEDED_TO           4
553 #define FROM_DIRECTION          1
554 #define FROM_LOOP               ucs4le_internal_loop
555 #define TO_LOOP                 ucs4le_internal_loop /* This is not used.  */
556 #define FUNCTION_NAME           __gconv_transform_ucs4le_internal
557
558
559 static inline int
560 ucs4le_internal_loop (struct __gconv_step *step,
561                       struct __gconv_step_data *step_data,
562                       const unsigned char **inptrp, const unsigned char *inend,
563                       unsigned char **outptrp, unsigned char *outend,
564                       size_t *irreversible)
565 {
566   int flags = step_data->__flags;
567   const unsigned char *inptr = *inptrp;
568   unsigned char *outptr = *outptrp;
569   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
570   int result;
571   size_t cnt;
572
573   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
574     {
575       uint32_t inval;
576
577 #if __BYTE_ORDER == __BIG_ENDIAN
578       inval = bswap_32 (*(const uint32_t *) inptr);
579 #else
580       inval = *(const uint32_t *) inptr;
581 #endif
582
583       if (__builtin_expect (inval, 0) > 0x7fffffff)
584         {
585           /* The value is too large.  We don't try transliteration here since
586              this is not an error because of the lack of possibilities to
587              represent the result.  This is a genuine bug in the input since
588              UCS4 does not allow such values.  */
589           if (irreversible == NULL)
590             /* We are transliterating, don't try to correct anything.  */
591             return __GCONV_ILLEGAL_INPUT;
592
593           if (flags & __GCONV_IGNORE_ERRORS)
594             {
595               /* Just ignore this character.  */
596               ++*irreversible;
597               continue;
598             }
599
600           return __GCONV_ILLEGAL_INPUT;
601         }
602
603       *((uint32_t *) outptr)++ = inval;
604     }
605
606   *inptrp = inptr;
607   *outptrp = outptr;
608
609   /* Determine the status.  */
610   if (*inptrp == inend)
611     result = __GCONV_EMPTY_INPUT;
612   else if (*outptrp == outend)
613     result = __GCONV_FULL_OUTPUT;
614   else
615     result = __GCONV_INCOMPLETE_INPUT;
616
617   return result;
618 }
619
620 #ifndef _STRING_ARCH_unaligned
621 static inline int
622 ucs4le_internal_loop_unaligned (struct __gconv_step *step,
623                                 struct __gconv_step_data *step_data,
624                                 const unsigned char **inptrp,
625                                 const unsigned char *inend,
626                                 unsigned char **outptrp, unsigned char *outend,
627                                 size_t *irreversible)
628 {
629   int flags = step_data->__flags;
630   const unsigned char *inptr = *inptrp;
631   unsigned char *outptr = *outptrp;
632   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
633   int result;
634   size_t cnt;
635
636   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
637     {
638       if (__builtin_expect (inptr[3], 0) > 0x80)
639         {
640           /* The value is too large.  We don't try transliteration here since
641              this is not an error because of the lack of possibilities to
642              represent the result.  This is a genuine bug in the input since
643              UCS4 does not allow such values.  */
644           if (irreversible == NULL)
645             /* We are transliterating, don't try to correct anything.  */
646             return __GCONV_ILLEGAL_INPUT;
647
648           if (flags & __GCONV_IGNORE_ERRORS)
649             {
650               /* Just ignore this character.  */
651               ++*irreversible;
652               continue;
653             }
654
655           *inptrp = inptr;
656           *outptrp = outptr;
657           return __GCONV_ILLEGAL_INPUT;
658         }
659
660 # if __BYTE_ORDER == __BIG_ENDIAN
661       outptr[3] = inptr[0];
662       outptr[2] = inptr[1];
663       outptr[1] = inptr[2];
664       outptr[0] = inptr[3];
665 # else
666       outptr[0] = inptr[0];
667       outptr[1] = inptr[1];
668       outptr[2] = inptr[2];
669       outptr[3] = inptr[3];
670 # endif
671
672       outptr += 4;
673     }
674
675   *inptrp = inptr;
676   *outptrp = outptr;
677
678   /* Determine the status.  */
679   if (*inptrp == inend)
680     result = __GCONV_EMPTY_INPUT;
681   else if (*outptrp == outend)
682     result = __GCONV_FULL_OUTPUT;
683   else
684     result = __GCONV_INCOMPLETE_INPUT;
685
686   return result;
687 }
688 #endif
689
690
691 static inline int
692 ucs4le_internal_loop_single (struct __gconv_step *step,
693                              struct __gconv_step_data *step_data,
694                              const unsigned char **inptrp,
695                              const unsigned char *inend,
696                              unsigned char **outptrp, unsigned char *outend,
697                              size_t *irreversible)
698 {
699   mbstate_t *state = step_data->__statep;
700   int flags = step_data->__flags;
701   size_t cnt = state->__count & 7;
702
703   while (*inptrp < inend && cnt < 4)
704     state->__value.__wchb[cnt++] = *(*inptrp)++;
705
706   if (__builtin_expect (cnt, 4) < 4)
707     {
708       /* Still not enough bytes.  Store the ones in the input buffer.  */
709       state->__count &= ~7;
710       state->__count |= cnt;
711
712       return __GCONV_INCOMPLETE_INPUT;
713     }
714
715   if (__builtin_expect (((unsigned char *) state->__value.__wchb)[3], 0)
716       > 0x80)
717     {
718       /* The value is too large.  We don't try transliteration here since
719          this is not an error because of the lack of possibilities to
720          represent the result.  This is a genuine bug in the input since
721          UCS4 does not allow such values.  */
722       if (!(flags & __GCONV_IGNORE_ERRORS))
723         return __GCONV_ILLEGAL_INPUT;
724     }
725   else
726     {
727 #if __BYTE_ORDER == __BIG_ENDIAN
728       (*outptrp)[0] = state->__value.__wchb[3];
729       (*outptrp)[1] = state->__value.__wchb[2];
730       (*outptrp)[2] = state->__value.__wchb[1];
731       (*outptrp)[3] = state->__value.__wchb[0];
732 #elif __BYTE_ORDER == __BIG_ENDIAN
733       (*outptrp)[0] = state->__value.__wchb[0];
734       (*outptrp)[1] = state->__value.__wchb[1];
735       (*outptrp)[2] = state->__value.__wchb[2];
736       (*outptrp)[3] = state->__value.__wchb[3];
737 #endif
738
739       *outptrp += 4;
740     }
741
742   /* Clear the state buffer.  */
743   state->__count &= ~7;
744
745   return __GCONV_OK;
746 }
747
748 #include <iconv/skeleton.c>
749
750
751 /* Convert from ISO 646-IRV to the internal (UCS4-like) format.  */
752 #define DEFINE_INIT             0
753 #define DEFINE_FINI             0
754 #define MIN_NEEDED_FROM         1
755 #define MIN_NEEDED_TO           4
756 #define FROM_DIRECTION          1
757 #define FROM_LOOP               ascii_internal_loop
758 #define TO_LOOP                 ascii_internal_loop /* This is not used.  */
759 #define FUNCTION_NAME           __gconv_transform_ascii_internal
760 #define ONE_DIRECTION           1
761
762 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
763 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
764 #define LOOPFCT                 FROM_LOOP
765 #define BODY \
766   {                                                                           \
767     if (__builtin_expect (*inptr, 0) > '\x7f')                                \
768       {                                                                       \
769         /* The value is too large.  We don't try transliteration here since   \
770            this is not an error because of the lack of possibilities to       \
771            represent the result.  This is a genuine bug in the input since    \
772            ASCII does not allow such values.  */                              \
773         if (! ignore_errors_p ())                                             \
774           {                                                                   \
775             /* This is no correct ANSI_X3.4-1968 character.  */               \
776             result = __GCONV_ILLEGAL_INPUT;                                   \
777             break;                                                            \
778           }                                                                   \
779                                                                               \
780         ++*irreversible;                                                      \
781         ++inptr;                                                              \
782       }                                                                       \
783     else                                                                      \
784       /* It's an one byte sequence.  */                                       \
785       *((uint32_t *) outptr)++ = *inptr++;                                    \
786   }
787 #define LOOP_NEED_FLAGS
788 #include <iconv/loop.c>
789 #include <iconv/skeleton.c>
790
791
792 /* Convert from the internal (UCS4-like) format to ISO 646-IRV.  */
793 #define DEFINE_INIT             0
794 #define DEFINE_FINI             0
795 #define MIN_NEEDED_FROM         4
796 #define MIN_NEEDED_TO           1
797 #define FROM_DIRECTION          1
798 #define FROM_LOOP               internal_ascii_loop
799 #define TO_LOOP                 internal_ascii_loop /* This is not used.  */
800 #define FUNCTION_NAME           __gconv_transform_internal_ascii
801 #define ONE_DIRECTION           1
802
803 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
804 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
805 #define LOOPFCT                 FROM_LOOP
806 #define BODY \
807   {                                                                           \
808     if (__builtin_expect (*((const uint32_t *) inptr), 0) > 0x7f)             \
809       {                                                                       \
810         STANDARD_ERR_HANDLER (4);                                             \
811       }                                                                       \
812     else                                                                      \
813       /* It's an one byte sequence.  */                                       \
814       *outptr++ = *((const uint32_t *) inptr)++;                              \
815   }
816 #define LOOP_NEED_FLAGS
817 #include <iconv/loop.c>
818 #include <iconv/skeleton.c>
819
820
821 /* Convert from the internal (UCS4-like) format to UTF-8.  */
822 #define DEFINE_INIT             0
823 #define DEFINE_FINI             0
824 #define MIN_NEEDED_FROM         4
825 #define MIN_NEEDED_TO           1
826 #define MAX_NEEDED_TO           6
827 #define FROM_DIRECTION          1
828 #define FROM_LOOP               internal_utf8_loop
829 #define TO_LOOP                 internal_utf8_loop /* This is not used.  */
830 #define FUNCTION_NAME           __gconv_transform_internal_utf8
831 #define ONE_DIRECTION           1
832
833 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
834 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
835 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_TO
836 #define LOOPFCT                 FROM_LOOP
837 #define BODY \
838   {                                                                           \
839     uint32_t wc = *((const uint32_t *) inptr);                                \
840                                                                               \
841     /* Since we control every character we read this cannot happen.  */       \
842     assert (wc <= 0x7fffffff);                                                \
843                                                                               \
844     if (wc < 0x80)                                                            \
845       /* It's an one byte sequence.  */                                       \
846       *outptr++ = (unsigned char) wc;                                         \
847     else                                                                      \
848       {                                                                       \
849         size_t step;                                                          \
850         char *start;                                                          \
851                                                                               \
852         for (step = 2; step < 6; ++step)                                      \
853           if ((wc & (~(uint32_t)0 << (5 * step + 1))) == 0)                   \
854             break;                                                            \
855                                                                               \
856         if (__builtin_expect (outptr + step > outend, 0))                     \
857           {                                                                   \
858             /* Too long.  */                                                  \
859             result = __GCONV_FULL_OUTPUT;                                     \
860             break;                                                            \
861           }                                                                   \
862                                                                               \
863         start = outptr;                                                       \
864         *outptr = (unsigned char) (~0xff >> step);                            \
865         outptr += step;                                                       \
866         --step;                                                               \
867         do                                                                    \
868           {                                                                   \
869             start[step] = 0x80 | (wc & 0x3f);                                 \
870             wc >>= 6;                                                         \
871           }                                                                   \
872         while (--step > 0);                                                   \
873         start[0] |= wc;                                                       \
874       }                                                                       \
875                                                                               \
876     inptr += 4;                                                               \
877   }
878 #include <iconv/loop.c>
879 #include <iconv/skeleton.c>
880
881
882 /* Convert from UTF-8 to the internal (UCS4-like) format.  */
883 #define DEFINE_INIT             0
884 #define DEFINE_FINI             0
885 #define MIN_NEEDED_FROM         1
886 #define MAX_NEEDED_FROM         6
887 #define MIN_NEEDED_TO           4
888 #define FROM_DIRECTION          1
889 #define FROM_LOOP               utf8_internal_loop
890 #define TO_LOOP                 utf8_internal_loop /* This is not used.  */
891 #define FUNCTION_NAME           __gconv_transform_utf8_internal
892 #define ONE_DIRECTION           1
893
894 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
895 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
896 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
897 #define LOOPFCT                 FROM_LOOP
898 #define BODY \
899   {                                                                           \
900     uint32_t ch;                                                              \
901     uint_fast32_t cnt;                                                        \
902     uint_fast32_t i;                                                          \
903                                                                               \
904     /* Next input byte.  */                                                   \
905     ch = *inptr;                                                              \
906                                                                               \
907     if (ch < 0x80)                                                            \
908       {                                                                       \
909         /* One byte sequence.  */                                             \
910         cnt = 1;                                                              \
911         ++inptr;                                                              \
912       }                                                                       \
913     else                                                                      \
914       {                                                                       \
915         if (ch >= 0xc2 && ch < 0xe0)                                          \
916           {                                                                   \
917             /* We expect two bytes.  The first byte cannot be 0xc0 or 0xc1,   \
918                otherwise the wide character could have been represented       \
919                using a single byte.  */                                       \
920             cnt = 2;                                                          \
921             ch &= 0x1f;                                                       \
922           }                                                                   \
923         else if (__builtin_expect (ch & 0xf0, 0xe0) == 0xe0)                  \
924           {                                                                   \
925             /* We expect three bytes.  */                                     \
926             cnt = 3;                                                          \
927             ch &= 0x0f;                                                       \
928           }                                                                   \
929         else if (__builtin_expect (ch & 0xf8, 0xf0) == 0xf0)                  \
930           {                                                                   \
931             /* We expect four bytes.  */                                      \
932             cnt = 4;                                                          \
933             ch &= 0x07;                                                       \
934           }                                                                   \
935         else if (__builtin_expect (ch & 0xfc, 0xf8) == 0xf8)                  \
936           {                                                                   \
937             /* We expect five bytes.  */                                      \
938             cnt = 5;                                                          \
939             ch &= 0x03;                                                       \
940           }                                                                   \
941         else if (__builtin_expect (ch & 0xfe, 0xfc) == 0xfc)                  \
942           {                                                                   \
943             /* We expect six bytes.  */                                       \
944             cnt = 6;                                                          \
945             ch &= 0x01;                                                       \
946           }                                                                   \
947         else                                                                  \
948           {                                                                   \
949             int skipped;                                                      \
950                                                                               \
951             if (! ignore_errors_p ())                                         \
952               {                                                               \
953                 /* This is an illegal encoding.  */                           \
954                 result = __GCONV_ILLEGAL_INPUT;                               \
955                 break;                                                        \
956               }                                                               \
957                                                                               \
958             /* Search the end of this ill-formed UTF-8 character.  This       \
959                is the next byte with (x & 0xc0) != 0x80.  */                  \
960              skipped = 0;                                                     \
961              do                                                               \
962                {                                                              \
963                  ++inptr;                                                     \
964                  ++skipped;                                                   \
965                }                                                              \
966              while (inptr < inend && (*inptr & 0xc0) == 0x80 && skipped < 5); \
967                                                                               \
968              continue;                                                        \
969           }                                                                   \
970                                                                               \
971         if (__builtin_expect (inptr + cnt > inend, 0))                        \
972           {                                                                   \
973             /* We don't have enough input.  But before we report that check   \
974                that all the bytes are correct.  */                            \
975             for (i = 1; inptr + i < inend; ++i)                               \
976               if ((inptr[i] & 0xc0) != 0x80)                                  \
977                 break;                                                        \
978                                                                               \
979             if (__builtin_expect (inptr + i == inend, 1))                     \
980               {                                                               \
981                 result = __GCONV_INCOMPLETE_INPUT;                            \
982                 break;                                                        \
983               }                                                               \
984                                                                               \
985             if (ignore_errors_p ())                                           \
986               {                                                               \
987                 /* Ignore it.  */                                             \
988                 inptr += i;                                                   \
989                 ++*irreversible;                                              \
990                 continue;                                                     \
991               }                                                               \
992                                                                               \
993             result = __GCONV_ILLEGAL_INPUT;                                   \
994             break;                                                            \
995           }                                                                   \
996                                                                               \
997         /* Read the possible remaining bytes.  */                             \
998         for (i = 1; i < cnt; ++i)                                             \
999           {                                                                   \
1000             uint32_t byte = inptr[i];                                         \
1001                                                                               \
1002             if ((byte & 0xc0) != 0x80)                                        \
1003               /* This is an illegal encoding.  */                             \
1004               break;                                                          \
1005                                                                               \
1006             ch <<= 6;                                                         \
1007             ch |= byte & 0x3f;                                                \
1008           }                                                                   \
1009                                                                               \
1010         /* If i < cnt, some trail byte was not >= 0x80, < 0xc0.               \
1011            If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could       \
1012            have been represented with fewer than cnt bytes.  */               \
1013         if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0))               \
1014           {                                                                   \
1015             /* This is an illegal encoding.  */                               \
1016             if (ignore_errors_p ())                                           \
1017               {                                                               \
1018                 inptr += i;                                                   \
1019                 ++*irreversible;                                              \
1020                 continue;                                                     \
1021               }                                                               \
1022                                                                               \
1023             result = __GCONV_ILLEGAL_INPUT;                                   \
1024             break;                                                            \
1025           }                                                                   \
1026                                                                               \
1027         inptr += cnt;                                                         \
1028       }                                                                       \
1029                                                                               \
1030     /* Now adjust the pointers and store the result.  */                      \
1031     *((uint32_t *) outptr)++ = ch;                                            \
1032   }
1033 #define LOOP_NEED_FLAGS
1034
1035 #define STORE_REST \
1036   {                                                                           \
1037     /* We store the remaining bytes while converting them into the UCS4       \
1038        format.  We can assume that the first byte in the buffer is            \
1039        correct and that it requires a larger number of bytes than there       \
1040        are in the input buffer.  */                                           \
1041     wint_t ch = **inptrp;                                                     \
1042     size_t cnt;                                                               \
1043                                                                               \
1044     state->__count = inend - *inptrp;                                         \
1045                                                                               \
1046     if (ch >= 0xc2 && ch < 0xe0)                                              \
1047       {                                                                       \
1048         /* We expect two bytes.  The first byte cannot be 0xc0 or             \
1049            0xc1, otherwise the wide character could have been                 \
1050            represented using a single byte.  */                               \
1051         cnt = 2;                                                              \
1052         ch &= 0x1f;                                                           \
1053       }                                                                       \
1054     else if (__builtin_expect (ch & 0xf0, 0xe0) == 0xe0)                      \
1055       {                                                                       \
1056         /* We expect three bytes.  */                                         \
1057         cnt = 3;                                                              \
1058         ch &= 0x0f;                                                           \
1059       }                                                                       \
1060     else if (__builtin_expect (ch & 0xf8, 0xf0) == 0xf0)                      \
1061       {                                                                       \
1062         /* We expect four bytes.  */                                          \
1063         cnt = 4;                                                              \
1064         ch &= 0x07;                                                           \
1065       }                                                                       \
1066     else if (__builtin_expect (ch & 0xfc, 0xf8) == 0xf8)                      \
1067       {                                                                       \
1068         /* We expect five bytes.  */                                          \
1069         cnt = 5;                                                              \
1070         ch &= 0x03;                                                           \
1071       }                                                                       \
1072     else                                                                      \
1073       {                                                                       \
1074         /* We expect six bytes.  */                                           \
1075         cnt = 6;                                                              \
1076         ch &= 0x01;                                                           \
1077       }                                                                       \
1078                                                                               \
1079     /* The first byte is already consumed.  */                                \
1080     --cnt;                                                                    \
1081     while (++(*inptrp) < inend)                                               \
1082       {                                                                       \
1083         ch <<= 6;                                                             \
1084         ch |= **inptrp & 0x3f;                                                \
1085         --cnt;                                                                \
1086       }                                                                       \
1087                                                                               \
1088     /* Shift for the so far missing bytes.  */                                \
1089     ch <<= cnt * 6;                                                           \
1090                                                                               \
1091     /* Store the value.  */                                                   \
1092     state->__value.__wch = ch;                                                \
1093   }
1094
1095 #define UNPACK_BYTES \
1096   {                                                                           \
1097     wint_t wch = state->__value.__wch;                                        \
1098     size_t ntotal;                                                            \
1099     inlen = state->__count;                                                   \
1100                                                                               \
1101     if (state->__value.__wch <= 0x7ff)                                        \
1102       {                                                                       \
1103         bytebuf[0] = 0xc0;                                                    \
1104         ntotal = 2;                                                           \
1105       }                                                                       \
1106     else if (__builtin_expect (state->__value.__wch, 0) <= 0xffff)            \
1107       {                                                                       \
1108         bytebuf[0] = 0xe0;                                                    \
1109         ntotal = 3;                                                           \
1110       }                                                                       \
1111     else if (__builtin_expect (state->__value.__wch, 0) <= 0x1fffff)          \
1112       {                                                                       \
1113         bytebuf[0] = 0xf0;                                                    \
1114         ntotal = 4;                                                           \
1115       }                                                                       \
1116     else if (__builtin_expect (state->__value.__wch, 0) <= 0x3ffffff)         \
1117       {                                                                       \
1118         bytebuf[0] = 0xf8;                                                    \
1119         ntotal = 5;                                                           \
1120       }                                                                       \
1121     else                                                                      \
1122       {                                                                       \
1123         bytebuf[0] = 0xfc;                                                    \
1124         ntotal = 6;                                                           \
1125       }                                                                       \
1126                                                                               \
1127     do                                                                        \
1128       {                                                                       \
1129         if (--ntotal < inlen)                                                 \
1130           bytebuf[ntotal] = 0x80 | (wch & 0x3f);                              \
1131         wch >>= 6;                                                            \
1132       }                                                                       \
1133     while (ntotal > 1);                                                       \
1134                                                                               \
1135     bytebuf[0] |= wch;                                                        \
1136   }
1137
1138 #include <iconv/loop.c>
1139 #include <iconv/skeleton.c>
1140
1141
1142 /* Convert from UCS2 to the internal (UCS4-like) format.  */
1143 #define DEFINE_INIT             0
1144 #define DEFINE_FINI             0
1145 #define MIN_NEEDED_FROM         2
1146 #define MIN_NEEDED_TO           4
1147 #define FROM_DIRECTION          1
1148 #define FROM_LOOP               ucs2_internal_loop
1149 #define TO_LOOP                 ucs2_internal_loop /* This is not used.  */
1150 #define FUNCTION_NAME           __gconv_transform_ucs2_internal
1151 #define ONE_DIRECTION           1
1152
1153 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1154 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1155 #define LOOPFCT                 FROM_LOOP
1156 #define BODY \
1157   {                                                                           \
1158     uint16_t u1 = *((const uint16_t *) inptr);                                \
1159                                                                               \
1160     if (__builtin_expect (u1 >= 0xd800 && u1 < 0xe000, 0))                    \
1161       {                                                                       \
1162         /* Surrogate characters in UCS-2 input are not valid.  Reject         \
1163            them.  (Catching this here is not security relevant.)  */          \
1164         if (! ignore_errors_p ())                                             \
1165           {                                                                   \
1166             result = __GCONV_ILLEGAL_INPUT;                                   \
1167             break;                                                            \
1168           }                                                                   \
1169         inptr += 2;                                                           \
1170         ++*irreversible;                                                      \
1171         continue;                                                             \
1172       }                                                                       \
1173                                                                               \
1174     *((uint32_t *) outptr)++ = u1;                                            \
1175     inptr += 2;                                                               \
1176   }
1177 #define LOOP_NEED_FLAGS
1178 #include <iconv/loop.c>
1179 #include <iconv/skeleton.c>
1180
1181
1182 /* Convert from the internal (UCS4-like) format to UCS2.  */
1183 #define DEFINE_INIT             0
1184 #define DEFINE_FINI             0
1185 #define MIN_NEEDED_FROM         4
1186 #define MIN_NEEDED_TO           2
1187 #define FROM_DIRECTION          1
1188 #define FROM_LOOP               internal_ucs2_loop
1189 #define TO_LOOP                 internal_ucs2_loop /* This is not used.  */
1190 #define FUNCTION_NAME           __gconv_transform_internal_ucs2
1191 #define ONE_DIRECTION           1
1192
1193 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1194 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1195 #define LOOPFCT                 FROM_LOOP
1196 #define BODY \
1197   {                                                                           \
1198     uint32_t val = *((const uint32_t *) inptr);                               \
1199                                                                               \
1200     if (__builtin_expect (val, 0) >= 0x10000)                                 \
1201       {                                                                       \
1202         STANDARD_ERR_HANDLER (4);                                             \
1203       }                                                                       \
1204     else if (__builtin_expect (val >= 0xd800 && val < 0xe000, 0))             \
1205       {                                                                       \
1206         /* Surrogate characters in UCS-4 input are not valid.                 \
1207            We must catch this, because the UCS-2 output might be              \
1208            interpreted as UTF-16 by other programs.  If we let                \
1209            surrogates pass through, attackers could make a security           \
1210            hole exploit by synthesizing any desired plane 1-16                \
1211            character.  */                                                     \
1212         if (! ignore_errors_p ())                                             \
1213           {                                                                   \
1214             result = __GCONV_ILLEGAL_INPUT;                                   \
1215             break;                                                            \
1216           }                                                                   \
1217         inptr += 4;                                                           \
1218         ++*irreversible;                                                      \
1219         continue;                                                             \
1220       }                                                                       \
1221     else                                                                      \
1222       {                                                                       \
1223         *((uint16_t *) outptr)++ = val;                                       \
1224         inptr += 4;                                                           \
1225       }                                                                       \
1226   }
1227 #define LOOP_NEED_FLAGS
1228 #include <iconv/loop.c>
1229 #include <iconv/skeleton.c>
1230
1231
1232 /* Convert from UCS2 in other endianness to the internal (UCS4-like) format. */
1233 #define DEFINE_INIT             0
1234 #define DEFINE_FINI             0
1235 #define MIN_NEEDED_FROM         2
1236 #define MIN_NEEDED_TO           4
1237 #define FROM_DIRECTION          1
1238 #define FROM_LOOP               ucs2reverse_internal_loop
1239 #define TO_LOOP                 ucs2reverse_internal_loop/* This is not used.*/
1240 #define FUNCTION_NAME           __gconv_transform_ucs2reverse_internal
1241 #define ONE_DIRECTION           1
1242
1243 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1244 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1245 #define LOOPFCT                 FROM_LOOP
1246 #define BODY \
1247   {                                                                           \
1248     uint16_t u1 = bswap_16 (*((const uint16_t *) inptr));                     \
1249                                                                               \
1250     if (__builtin_expect (u1 >= 0xd800 && u1 < 0xe000, 0))                    \
1251       {                                                                       \
1252         /* Surrogate characters in UCS-2 input are not valid.  Reject         \
1253            them.  (Catching this here is not security relevant.)  */          \
1254         if (! ignore_errors_p ())                                             \
1255           {                                                                   \
1256             result = __GCONV_ILLEGAL_INPUT;                                   \
1257             break;                                                            \
1258           }                                                                   \
1259         inptr += 2;                                                           \
1260         ++*irreversible;                                                      \
1261         continue;                                                             \
1262       }                                                                       \
1263                                                                               \
1264     *((uint32_t *) outptr)++ = u1;                                            \
1265     inptr += 2;                                                               \
1266   }
1267 #define LOOP_NEED_FLAGS
1268 #include <iconv/loop.c>
1269 #include <iconv/skeleton.c>
1270
1271
1272 /* Convert from the internal (UCS4-like) format to UCS2 in other endianness. */
1273 #define DEFINE_INIT             0
1274 #define DEFINE_FINI             0
1275 #define MIN_NEEDED_FROM         4
1276 #define MIN_NEEDED_TO           2
1277 #define FROM_DIRECTION          1
1278 #define FROM_LOOP               internal_ucs2reverse_loop
1279 #define TO_LOOP                 internal_ucs2reverse_loop/* This is not used.*/
1280 #define FUNCTION_NAME           __gconv_transform_internal_ucs2reverse
1281 #define ONE_DIRECTION           1
1282
1283 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1284 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1285 #define LOOPFCT                 FROM_LOOP
1286 #define BODY \
1287   {                                                                           \
1288     uint32_t val = *((const uint32_t *) inptr);                               \
1289     if (__builtin_expect (val, 0) >= 0x10000)                                 \
1290       {                                                                       \
1291         STANDARD_ERR_HANDLER (4);                                             \
1292       }                                                                       \
1293     else if (__builtin_expect (val >= 0xd800 && val < 0xe000, 0))             \
1294       {                                                                       \
1295         /* Surrogate characters in UCS-4 input are not valid.                 \
1296            We must catch this, because the UCS-2 output might be              \
1297            interpreted as UTF-16 by other programs.  If we let                \
1298            surrogates pass through, attackers could make a security           \
1299            hole exploit by synthesizing any desired plane 1-16                \
1300            character.  */                                                     \
1301         if (! ignore_errors_p ())                                             \
1302           {                                                                   \
1303             result = __GCONV_ILLEGAL_INPUT;                                   \
1304             break;                                                            \
1305           }                                                                   \
1306         inptr += 4;                                                           \
1307         ++*irreversible;                                                      \
1308         continue;                                                             \
1309       }                                                                       \
1310     else                                                                      \
1311       {                                                                       \
1312         *((uint16_t *) outptr)++ = bswap_16 (val);                            \
1313         inptr += 4;                                                           \
1314       }                                                                       \
1315   }
1316 #define LOOP_NEED_FLAGS
1317 #include <iconv/loop.c>
1318 #include <iconv/skeleton.c>