📄 gconv_simple.c
字号:
# error "This endianess is not supported."#endif /* Determine the status. */ if (*inptrp == inend) result = __GCONV_EMPTY_INPUT; else if (*outptrp + 4 > outend) result = __GCONV_FULL_OUTPUT; else result = __GCONV_INCOMPLETE_INPUT; return result;}#ifndef _STRING_ARCH_unalignedstatic inline intinternal_ucs4le_loop_unaligned (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible){ const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; int result;# if __BYTE_ORDER == __BIG_ENDIAN /* Sigh, we have to do some real work. */ size_t cnt; for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4) { outptr[0] = inptr[3]; outptr[1] = inptr[2]; outptr[2] = inptr[1]; outptr[3] = inptr[0]; } *inptrp = inptr; *outptrp = outptr;# elif __BYTE_ORDER == __LITTLE_ENDIAN /* Simply copy the data. */ *inptrp = inptr + n_convert * 4; *outptrp = memcpy (outptr, inptr, n_convert * 4); *outptrp += n_convert * 4;# else# error "This endianess is not supported."# endif /* Determine the status. */ if (*inptrp + 4 > inend) result = __GCONV_EMPTY_INPUT; else if (*outptrp + 4 > outend) result = __GCONV_FULL_OUTPUT; else result = __GCONV_INCOMPLETE_INPUT; return result;}#endifstatic inline intinternal_ucs4le_loop_single (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible){ mbstate_t *state = step_data->__statep; size_t cnt = state->__count & 7; while (*inptrp < inend && cnt < 4) state->__value.__wchb[cnt++] = *(*inptrp)++; if (__builtin_expect (cnt < 4, 0)) { /* Still not enough bytes. Store the ones in the input buffer. */ state->__count &= ~7; state->__count |= cnt; return __GCONV_INCOMPLETE_INPUT; }#if __BYTE_ORDER == __BIG_ENDIAN (*outptrp)[0] = state->__value.__wchb[3]; (*outptrp)[1] = state->__value.__wchb[2]; (*outptrp)[2] = state->__value.__wchb[1]; (*outptrp)[3] = state->__value.__wchb[0]; *outptrp += 4;#else { /* XXX unaligned */ uint32_t **p = (uint32_t **)outptrp; uint32_t *q = *p; *q = state->__value.__wch; outptrp = (unsigned char **)(p + 1); }#endif /* Clear the state buffer. */ state->__count &= ~7; return __GCONV_OK;}#include <iconv/skeleton.c>/* And finally from UCS4-LE to the internal encoding. */#define DEFINE_INIT 0#define DEFINE_FINI 0#define MIN_NEEDED_FROM 4#define MIN_NEEDED_TO 4#define FROM_DIRECTION 1#define FROM_LOOP ucs4le_internal_loop#define TO_LOOP ucs4le_internal_loop /* This is not used. */#define FUNCTION_NAME __gconv_transform_ucs4le_internalstatic inline intucs4le_internal_loop (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible){ int flags = step_data->__flags; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; int result; size_t cnt; for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4) { uint32_t inval;#if __BYTE_ORDER == __BIG_ENDIAN inval = bswap_32 (*(const uint32_t *) inptr);#else inval = *(const uint32_t *) inptr;#endif if (__builtin_expect (inval > 0x7fffffff, 0)) { /* The value is too large. We don't try transliteration here since this is not an error because of the lack of possibilities to represent the result. This is a genuine bug in the input since UCS4 does not allow such values. */ if (irreversible == NULL) /* We are transliterating, don't try to correct anything. */ return __GCONV_ILLEGAL_INPUT; if (flags & __GCONV_IGNORE_ERRORS) { /* Just ignore this character. */ ++*irreversible; continue; } return __GCONV_ILLEGAL_INPUT; } *((uint32_t *) outptr) = inval; outptr = (unsigned char *)((uint32_t *) outptr + 1); } *inptrp = inptr; *outptrp = outptr; /* Determine the status. */ if (*inptrp == inend) result = __GCONV_EMPTY_INPUT; else if (*outptrp + 4 > outend) result = __GCONV_FULL_OUTPUT; else result = __GCONV_INCOMPLETE_INPUT; return result;}#ifndef _STRING_ARCH_unalignedstatic inline intucs4le_internal_loop_unaligned (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible){ int flags = step_data->__flags; const unsigned char *inptr = *inptrp; unsigned char *outptr = *outptrp; size_t n_convert = MIN (inend - inptr, outend - outptr) / 4; int result; size_t cnt; for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4) { if (__builtin_expect (inptr[3] > 0x80, 0)) { /* The value is too large. We don't try transliteration here since this is not an error because of the lack of possibilities to represent the result. This is a genuine bug in the input since UCS4 does not allow such values. */ if (irreversible == NULL) /* We are transliterating, don't try to correct anything. */ return __GCONV_ILLEGAL_INPUT; if (flags & __GCONV_IGNORE_ERRORS) { /* Just ignore this character. */ ++*irreversible; continue; } *inptrp = inptr; *outptrp = outptr; return __GCONV_ILLEGAL_INPUT; }# if __BYTE_ORDER == __BIG_ENDIAN outptr[3] = inptr[0]; outptr[2] = inptr[1]; outptr[1] = inptr[2]; outptr[0] = inptr[3];# else outptr[0] = inptr[0]; outptr[1] = inptr[1]; outptr[2] = inptr[2]; outptr[3] = inptr[3];# endif outptr += 4; } *inptrp = inptr; *outptrp = outptr; /* Determine the status. */ if (*inptrp == inend) result = __GCONV_EMPTY_INPUT; else if (*outptrp + 4 > outend) result = __GCONV_FULL_OUTPUT; else result = __GCONV_INCOMPLETE_INPUT; return result;}#endifstatic inline intucs4le_internal_loop_single (struct __gconv_step *step, struct __gconv_step_data *step_data, const unsigned char **inptrp, const unsigned char *inend, unsigned char **outptrp, unsigned char *outend, size_t *irreversible){ mbstate_t *state = step_data->__statep; int flags = step_data->__flags; size_t cnt = state->__count & 7; while (*inptrp < inend && cnt < 4) state->__value.__wchb[cnt++] = *(*inptrp)++; if (__builtin_expect (cnt < 4, 0)) { /* Still not enough bytes. Store the ones in the input buffer. */ state->__count &= ~7; state->__count |= cnt; return __GCONV_INCOMPLETE_INPUT; } if (__builtin_expect (((unsigned char *) state->__value.__wchb)[3] > 0x80, 0)) { /* The value is too large. We don't try transliteration here since this is not an error because of the lack of possibilities to represent the result. This is a genuine bug in the input since UCS4 does not allow such values. */ if (!(flags & __GCONV_IGNORE_ERRORS)) return __GCONV_ILLEGAL_INPUT; } else {#if __BYTE_ORDER == __BIG_ENDIAN (*outptrp)[0] = state->__value.__wchb[3]; (*outptrp)[1] = state->__value.__wchb[2]; (*outptrp)[2] = state->__value.__wchb[1]; (*outptrp)[3] = state->__value.__wchb[0];#elif __BYTE_ORDER == __BIG_ENDIAN (*outptrp)[0] = state->__value.__wchb[0]; (*outptrp)[1] = state->__value.__wchb[1]; (*outptrp)[2] = state->__value.__wchb[2]; (*outptrp)[3] = state->__value.__wchb[3];#endif *outptrp += 4; } /* Clear the state buffer. */ state->__count &= ~7; return __GCONV_OK;}#include <iconv/skeleton.c>/* Convert from ISO 646-IRV to the internal (UCS4-like) format. */#define DEFINE_INIT 0#define DEFINE_FINI 0#define MIN_NEEDED_FROM 1#define MIN_NEEDED_TO 4#define FROM_DIRECTION 1#define FROM_LOOP ascii_internal_loop#define TO_LOOP ascii_internal_loop /* This is not used. */#define FUNCTION_NAME __gconv_transform_ascii_internal#define ONE_DIRECTION 1#define MIN_NEEDED_INPUT MIN_NEEDED_FROM#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO#define LOOPFCT FROM_LOOP#define BODY \ { \ if (__builtin_expect (*inptr > '\x7f', 0)) \ { \ /* The value is too large. We don't try transliteration here since \ this is not an error because of the lack of possibilities to \ represent the result. This is a genuine bug in the input since \ ASCII does not allow such values. */ \ if (! ignore_errors_p ()) \ { \ /* This is no correct ANSI_X3.4-1968 character. */ \ result = __GCONV_ILLEGAL_INPUT; \ break; \ } \ \ *irreversible = *irreversible + 1; \ ++inptr; \ } \ else \ { \ /* It's an one byte sequence. */ \ *((uint32_t *) outptr) = *inptr; \ ++inptr; \ outptr = (unsigned char *)((uint32_t *) outptr + 1); \ } \ }#define LOOP_NEED_FLAGS#include <iconv/loop.c>#include <iconv/skeleton.c>/* Convert from the internal (UCS4-like) format to ISO 646-IRV. */#define DEFINE_INIT 0#define DEFINE_FINI 0#define MIN_NEEDED_FROM 4#define MIN_NEEDED_TO 1#define FROM_DIRECTION 1#define FROM_LOOP internal_ascii_loop#define TO_LOOP internal_ascii_loop /* This is not used. */#define FUNCTION_NAME __gconv_transform_internal_ascii#define ONE_DIRECTION 1#define MIN_NEEDED_INPUT MIN_NEEDED_FROM#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO#define LOOPFCT FROM_LOOP#define BODY \ { \ if (__builtin_expect (*((const uint32_t *) inptr) > 0x7f, 0)) \ { \ UNICODE_TAG_HANDLER (*((const uint32_t *) inptr), 4); \ STANDARD_ERR_HANDLER (4); \ } \ else \ { \ /* It's an one byte sequence. */ \ *outptr++ = *((const uint32_t *) inptr); \ inptr = ((const uint32_t *) inptr + 1); \ } \ }#define LOOP_NEED_FLAGS#include <iconv/loop.c>#include <iconv/skeleton.c>/* Convert from the internal (UCS4-like) format to UTF-8. */#define DEFINE_INIT 0#define DEFINE_FINI 0#define MIN_NEEDED_FROM 4#define MIN_NEEDED_TO 1#define MAX_NEEDED_TO 6#define FROM_DIRECTION 1#define FROM_LOOP internal_utf8_loop#define TO_LOOP internal_utf8_loop /* This is not used. */#define FUNCTION_NAME __gconv_transform_internal_utf8#define ONE_DIRECTION 1#define MIN_NEEDED_INPUT MIN_NEEDED_FROM#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO#define LOOPFCT FROM_LOOP#define BODY \ { \ uint32_t wc = *((const uint32_t *) inptr); \ \ if (wc < 0x80) \ /* It's an one byte sequence. */ \ *outptr++ = (unsigned char) wc; \ else if (__builtin_expect (wc <= 0x7fffffff, 1)) \ { \ size_t step; \ char *start; \ \ for (step = 2; step < 6; ++step) \ if ((wc & (~(uint32_t)0 << (5 * step + 1))) == 0) \ break; \ \ if (__builtin_expect (outptr + step > outend, 0)) \ { \ /* Too long. */ \ result = __GCONV_FULL_OUTPUT; \ break; \ } \ \ start = outptr; \ *outptr = (unsigned char) (~0xff >> step); \ outptr += step; \ --step; \ do \ { \ start[step] = 0x80 | (wc & 0x3f); \ wc >>= 6; \ } \ while (--step > 0); \ start[0] |= wc; \ } \ else \ { \ STANDARD_ERR_HANDLER (4); \ } \ \ inptr += 4; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -