about summary refs log tree commit diff
path: root/iconv/gconv_simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'iconv/gconv_simple.c')
-rw-r--r--iconv/gconv_simple.c282
1 files changed, 17 insertions, 265 deletions
diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c
index c50ffd3bf0..c60cffad4c 100644
--- a/iconv/gconv_simple.c
+++ b/iconv/gconv_simple.c
@@ -86,69 +86,22 @@ internal_ucs4_loop (struct __gconv_step *step,
 #if __BYTE_ORDER == __LITTLE_ENDIAN
   /* Sigh, we have to do some real work.  */
   size_t cnt;
-  uint32_t *outptr32 = (uint32_t *) outptr;
-
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
-    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
-
-  *inptrp = inptr;
-  *outptrp = (unsigned char *) outptr32;
-#elif __BYTE_ORDER == __BIG_ENDIAN
-  /* Simply copy the data.  */
-  *inptrp = inptr + n_convert * 4;
-  *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-#else
-# 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;
-}
-
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-internal_ucs4_loop_unaligned (struct __gconv_step *step,
-			      struct __gconv_step_data *step_data,
-			      const unsigned char **inptrp,
-			      const unsigned char *inend,
-			      unsigned char **outptrp,
-			      const 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 == __LITTLE_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];
+      uint32_t val = get32 (inptr);
+      put32 (outptr, __builtin_bswap32 (val));
     }
 
   *inptrp = inptr;
   *outptrp = outptr;
-# elif __BYTE_ORDER == __BIG_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
   /* Simply copy the data.  */
   *inptrp = inptr + n_convert * 4;
   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
-# else
-#  error "This endianess is not supported."
-# endif
+#else
+# error "This endianess is not supported."
+#endif
 
   /* Determine the status.  */
   if (*inptrp == inend)
@@ -160,7 +113,6 @@ internal_ucs4_loop_unaligned (struct __gconv_step *step,
 
   return result;
 }
-#endif
 
 
 static inline int
@@ -242,12 +194,9 @@ ucs4_internal_loop (struct __gconv_step *step,
 
   for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
     {
-      uint32_t inval;
-
+      uint32_t inval = get32 (inptr);
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-      inval = bswap_32 (*(const uint32_t *) inptr);
-#else
-      inval = *(const uint32_t *) inptr;
+      inval = __builtin_bswap32 (inval);
 #endif
 
       if (__glibc_unlikely (inval > 0x7fffffff))
@@ -272,7 +221,7 @@ ucs4_internal_loop (struct __gconv_step *step,
 	  return __GCONV_ILLEGAL_INPUT;
 	}
 
-      *((uint32_t *) outptr) = inval;
+      put32 (outptr, inval);
       outptr += sizeof (uint32_t);
     }
 
@@ -290,75 +239,6 @@ ucs4_internal_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-ucs4_internal_loop_unaligned (struct __gconv_step *step,
-			      struct __gconv_step_data *step_data,
-			      const unsigned char **inptrp,
-			      const unsigned char *inend,
-			      unsigned char **outptrp,
-			      const unsigned char *outend,
-			      size_t *irreversible)
-{
-  int flags = step_data->__flags;
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  int result;
-
-  for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
-    {
-      if (__glibc_unlikely (inptr[0] > 0x80))
-	{
-	  /* 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 == __LITTLE_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;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
@@ -453,11 +333,12 @@ internal_ucs4le_loop (struct __gconv_step *step,
 #if __BYTE_ORDER == __BIG_ENDIAN
   /* Sigh, we have to do some real work.  */
   size_t cnt;
-  uint32_t *outptr32 = (uint32_t *) outptr;
 
-  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
-    *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
-  outptr = (unsigned char *) outptr32;
+  for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
+    {
+      uint32_t val = get32 (inptr);
+      put32 (outptr, __builtin_bswap32 (val));
+    }
 
   *inptrp = inptr;
   *outptrp = outptr;
@@ -480,59 +361,6 @@ internal_ucs4le_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-internal_ucs4le_loop_unaligned (struct __gconv_step *step,
-				struct __gconv_step_data *step_data,
-				const unsigned char **inptrp,
-				const unsigned char *inend,
-				unsigned char **outptrp,
-				const 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 = __mempcpy (outptr, inptr, n_convert * 4);
-# else
-#  error "This endianess is not supported."
-# endif
-
-  /* Determine the status.  */
-  if (*inptrp == inend)
-    result = __GCONV_EMPTY_INPUT;
-  else if (*inptrp + 4 > inend)
-    result = __GCONV_INCOMPLETE_INPUT;
-  else
-    {
-      assert (*outptrp + 4 > outend);
-      result = __GCONV_FULL_OUTPUT;
-    }
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))
@@ -612,12 +440,9 @@ ucs4le_internal_loop (struct __gconv_step *step,
 
   for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
     {
-      uint32_t inval;
-
+      uint32_t inval = get32 (inptr);
 #if __BYTE_ORDER == __BIG_ENDIAN
-      inval = bswap_32 (*(const uint32_t *) inptr);
-#else
-      inval = *(const uint32_t *) inptr;
+      inval = __builtin_bswap32 (inval);
 #endif
 
       if (__glibc_unlikely (inval > 0x7fffffff))
@@ -642,7 +467,7 @@ ucs4le_internal_loop (struct __gconv_step *step,
 	  return __GCONV_ILLEGAL_INPUT;
 	}
 
-      *((uint32_t *) outptr) = inval;
+      put32 (outptr, inval);
       outptr += sizeof (uint32_t);
     }
 
@@ -663,79 +488,6 @@ ucs4le_internal_loop (struct __gconv_step *step,
   return result;
 }
 
-#if !_STRING_ARCH_unaligned
-static inline int
-__attribute ((always_inline))
-ucs4le_internal_loop_unaligned (struct __gconv_step *step,
-				struct __gconv_step_data *step_data,
-				const unsigned char **inptrp,
-				const unsigned char *inend,
-				unsigned char **outptrp,
-				const unsigned char *outend,
-				size_t *irreversible)
-{
-  int flags = step_data->__flags;
-  const unsigned char *inptr = *inptrp;
-  unsigned char *outptr = *outptrp;
-  int result;
-
-  for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
-    {
-      if (__glibc_unlikely (inptr[3] > 0x80))
-	{
-	  /* 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 (*inptrp + 4 > inend)
-    result = __GCONV_INCOMPLETE_INPUT;
-  else
-    {
-      assert (*outptrp + 4 > outend);
-      result = __GCONV_FULL_OUTPUT;
-    }
-
-  return result;
-}
-#endif
-
 
 static inline int
 __attribute ((always_inline))