⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gconv_simple.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 3 页
字号:
# 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 + -