about summary refs log tree commit diff
path: root/iconv/loop.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-04-09 17:43:29 +0000
committerUlrich Drepper <drepper@redhat.com>2000-04-09 17:43:29 +0000
commitfd1b5c0fb6ca63dd76e833672be840cc4c3a7eff (patch)
treea7930ff78ac1764d4bc70748acd26b2053125bb3 /iconv/loop.c
parent3de968b60f92708df0873407e19ae3eae08f77c9 (diff)
downloadglibc-fd1b5c0fb6ca63dd76e833672be840cc4c3a7eff.tar.gz
glibc-fd1b5c0fb6ca63dd76e833672be840cc4c3a7eff.tar.xz
glibc-fd1b5c0fb6ca63dd76e833672be840cc4c3a7eff.zip
Update.
2000-04-09  Ulrich Drepper  <drepper@redhat.com>

	Implement handling of restartable conversion functions according to
	ISO C.
	* iconv/gconv.h (__gconv_fct): Add additional parameter.
	* iconv/gconv_int.h (__BUILTIN_TRANS): Likewise.
	* iconv/gconv.c: Pass additional parameter to conversion function.
	* iconv/gconv_simple.c (internal_ucs4_loop_single): New function.
	(internal_ucs4le_loop_single): New function.
	(__gconv_transform_ascii_internal): Define ONE_DIRECTION.
	(__gconv_transform_internal_ascii): Likewise.
	(__gconv_transform_internal_utf8): Likewise.
	(__gconv_transform_utf8_internal): Likewise.
	(__gconv_transform_ucs2_internal): Likewise.
	(__gconv_transform_internal_ucs2): Likewise.
	(__gconv_transform_ucs2reverse_internal): Likewise.
	(__gconv_transform_internal_ucs2reverse): Likewise.
	(internal_ucs4le_loop_unaligned): Before return
	__GCONV_INCOMPLETE_INPUT check that the remaining bytes really form
	a valid character.  Otherwise return __GCONV_ILLEGAL_INPUT.
	(__gconv_transform_utf8_internal): Define STORE_REST and UNPACK_BYTES.
	* iconv/loop.c: Fit in definition of function to convert one character
	for processing of left-over bytes from the state object.
	* iconv/skeleton.c (gconv): Rename inbuf to inptrp and inbufend to
	inend to match names in loop functions.
	(RESET_INPUT_BUFFER): Change apprpriately.
	(gconv): If needed, call function to process bytes from the state
	object.  Similar at the end: store left over bytes if input is
	incomplete.
	Take extra argument and add new argument to all calls of the
	conversion function.
	* iconvdata/iso-2022-cn.c: Adjust numeric values used to store
	information in the state object to not conflict with length count.
	* iconvdata/iso-2022-jp.c: Likewise.
	* iconvdata/iso-2022-kr.c: Likewise.
	* iconvdata/unicode.c: Adjust for change change in parameters of
	skeleton function.
	* iconvdata/utf-16.c: Likewise.
	* libio/iofwide.c: Add new parameter to all calls of conversion
	function.
	* wcsmbs/btowc.c: Likewise.
	* wcsmbs/mbrtowc.c: Likewise.
	* wcsmbs/mbsnrtowcs.c: Likewise.
	* wcsmbs/mbsrtowcs.c: Likewise.
	* wcsmbs/wcrtomb.c: Likewise.
	* wcsmbs/wcsnrtombs.c: Likewise.
	* wcsmbs/wcsrtombs.c: Likewise.
	* wcsmbs/wctob.c: Likewise.

	* iconvdata/gbgbk.c: Always define MAX_NEEDED_OUTPUT and
	MAX_NEEDED_INPUT.
Diffstat (limited to 'iconv/loop.c')
-rw-r--r--iconv/loop.c105
1 files changed, 99 insertions, 6 deletions
diff --git a/iconv/loop.c b/iconv/loop.c
index 1e5403310e..ffdd24d7e3 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -45,6 +45,7 @@
      UPDATE_PARAMS	code to store result in params.
 */
 
+#include <assert.h>
 #include <endian.h>
 #include <gconv.h>
 #include <stdint.h>
@@ -261,23 +262,109 @@ FCTNAME (LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend,
 }
 
 
-#undef get16
-#undef get32
-#undef put16
-#undef put32
-#undef unaligned
-
 /* Include the file a second time to define the function to define the
    function to handle unaligned access.  */
 #if !defined DEFINE_UNALIGNED && !defined _STRING_ARCH_unaligned \
     && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \
     && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
+# undef get16
+# undef get32
+# undef put16
+# undef put32
+# undef unaligned
+
 # define DEFINE_UNALIGNED
 # include "loop.c"
 # undef DEFINE_UNALIGNED
 #endif
 
 
+#if MAX_NEEDED_INPUT > 1
+# define SINGLE(fct) SINGLE2 (fct)
+# define SINGLE2(fct) fct##_single
+static inline int
+SINGLE(LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend,
+		 unsigned char **outptrp, unsigned char *outend,
+		 mbstate_t *state, void *data, size_t *converted
+		 EXTRA_LOOP_DECLS)
+{
+  int result = __GCONV_OK;
+  unsigned char bytebuf[MAX_NEEDED_INPUT];
+  const unsigned char *inptr = *inptrp;
+  unsigned char *outptr = *outptrp;
+  size_t inlen;
+
+#ifdef INIT_PARAMS
+  INIT_PARAMS;
+#endif
+
+#ifdef UNPACK_BYTES
+  UNPACK_BYTES
+#else
+  /* Add the bytes from the state to the input buffer.  */
+  for (inlen = 0; inlen < (state->__count & 7); ++ inlen)
+    bytebuf[inlen] = state->__value.__wchb[inlen];
+#endif
+
+  /* Are there enough bytes in the input buffer?  */
+  if (inptr + (MAX_NEEDED_INPUT - inlen) > inend)
+    {
+#ifdef STORE_REST
+      *inptrp = inend;
+      inptr = bytebuf;
+      inptrp = &inptr;
+      inend = &bytebuf[inlen];
+
+      STORE_REST
+#else
+      /* We don't have enough input for another complete input
+	 character.  */
+      while (inptr < inend)
+	state->__value.__wchb[inlen++] = *inptr++;
+#endif
+
+      return __GCONV_INCOMPLETE_INPUT;
+    }
+
+  /* Enough space in output buffer.  */
+  if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
+      || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
+    /* Overflow in the output buffer.  */
+    return __GCONV_FULL_OUTPUT;
+
+  /*  Now add characters from the normal input buffer.  */
+  do
+    bytebuf[inlen++] = *inptr++;
+  while (inlen < MAX_NEEDED_INPUT);
+
+  inptr = bytebuf;
+  inend = &inptr[MAX_NEEDED_INPUT];
+  do
+    {
+      BODY
+    }
+  while (0);
+
+  if (result == __GCONV_OK)
+    {
+      /* We successfully converted the character (maybe even more).
+	 Update the pointers passed in.  */
+      assert (inptr - bytebuf > (state->__count & 7));
+
+      *inptrp += inptr - bytebuf - (state->__count & 7);
+      *outptrp = outptr;
+
+      /* Clear the state buffer.  */
+      state->__count &= ~7;
+    }
+
+  return result;
+}
+# undef SINGLE
+# undef SINGLE2
+#endif
+
+
 /* We remove the macro definitions so that we can include this file again
    for the definition of another function.  */
 #undef MIN_NEEDED_INPUT
@@ -290,3 +377,9 @@ FCTNAME (LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend,
 #undef EXTRA_LOOP_DECLS
 #undef INIT_PARAMS
 #undef UPDATE_PARAMS
+#undef get16
+#undef get32
+#undef put16
+#undef put32
+#undef unaligned
+#undef UNPACK_BYTES