(U-0002195D): Add `ideographic-structure'; add `sound@ja/on'; add
[chise/xemacs-chise.git.1] / src / file-coding.c
index d44359b..763acae 100644 (file)
@@ -58,14 +58,14 @@ struct file_coding_dump {
      This describes a permutation of the possible coding categories. */
   int coding_category_by_priority[CODING_CATEGORY_LAST];
 
-#ifdef MULE
+#if defined(MULE) && !defined(UTF2000)
   Lisp_Object ucs_to_mule_table[65536];
 #endif
 } *fcd;
 
 static const struct lrecord_description fcd_description_1[] = {
   { XD_LISP_OBJECT_ARRAY, offsetof (struct file_coding_dump, coding_category_system), CODING_CATEGORY_LAST },
-#ifdef MULE
+#if defined(MULE) && !defined(UTF2000)
   { XD_LISP_OBJECT_ARRAY, offsetof (struct file_coding_dump, ucs_to_mule_table), countof (fcd->ucs_to_mule_table) },
 #endif
   { XD_END }
@@ -176,47 +176,47 @@ EXFUN (Fcopy_coding_system, 2);
 #ifdef MULE
 struct detection_state;
 static int detect_coding_sjis (struct detection_state *st,
-                              const Extbyte *src, size_t n);
+                              const Extbyte *src, Lstream_data_count n);
 static void decode_coding_sjis (Lstream *decoding, const Extbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static void encode_coding_sjis (Lstream *encoding, const Bufbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static int detect_coding_big5 (struct detection_state *st,
-                              const Extbyte *src, size_t n);
+                              const Extbyte *src, Lstream_data_count n);
 static void decode_coding_big5 (Lstream *decoding, const Extbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static void encode_coding_big5 (Lstream *encoding, const Bufbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static int detect_coding_ucs4 (struct detection_state *st,
-                              const Extbyte *src, size_t n);
+                              const Extbyte *src, Lstream_data_count n);
 static void decode_coding_ucs4 (Lstream *decoding, const Extbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static void encode_coding_ucs4 (Lstream *encoding, const Bufbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static int detect_coding_utf8 (struct detection_state *st,
-                              const Extbyte *src, size_t n);
+                              const Extbyte *src, Lstream_data_count n);
 static void decode_coding_utf8 (Lstream *decoding, const Extbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static void encode_coding_utf8 (Lstream *encoding, const Bufbyte *src,
-                               unsigned_char_dynarr *dst, size_t n);
+                               unsigned_char_dynarr *dst, Lstream_data_count n);
 static int postprocess_iso2022_mask (int mask);
 static void reset_iso2022 (Lisp_Object coding_system,
                           struct iso2022_decoder *iso);
 static int detect_coding_iso2022 (struct detection_state *st,
-                                 const Extbyte *src, size_t n);
+                                 const Extbyte *src, Lstream_data_count n);
 static void decode_coding_iso2022 (Lstream *decoding, const Extbyte *src,
-                                  unsigned_char_dynarr *dst, size_t n);
+                                  unsigned_char_dynarr *dst, Lstream_data_count n);
 static void encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
-                                  unsigned_char_dynarr *dst, size_t n);
+                                  unsigned_char_dynarr *dst, Lstream_data_count n);
 #endif /* MULE */
 static void decode_coding_no_conversion (Lstream *decoding, const Extbyte *src,
-                                        unsigned_char_dynarr *dst, size_t n);
+                                        unsigned_char_dynarr *dst, Lstream_data_count n);
 static void encode_coding_no_conversion (Lstream *encoding, const Bufbyte *src,
-                                        unsigned_char_dynarr *dst, size_t n);
+                                        unsigned_char_dynarr *dst, Lstream_data_count n);
 static void mule_decode (Lstream *decoding, const Extbyte *src,
-                        unsigned_char_dynarr *dst, size_t n);
+                        unsigned_char_dynarr *dst, Lstream_data_count n);
 static void mule_encode (Lstream *encoding, const Bufbyte *src,
-                        unsigned_char_dynarr *dst, size_t n);
+                        unsigned_char_dynarr *dst, Lstream_data_count n);
 
 typedef struct codesys_prop codesys_prop;
 struct codesys_prop
@@ -433,7 +433,7 @@ eol_type_to_symbol (eol_type_t type)
 {
   switch (type)
     {
-    default: abort ();
+    default: ABORT ();
     case EOL_LF:         return Qlf;
     case EOL_CRLF:       return Qcrlf;
     case EOL_CR:         return Qcr;
@@ -1222,7 +1222,7 @@ subsidiary_coding_system (Lisp_Object coding_system, eol_type_t type)
     case EOL_LF:   new_coding_system = CODING_SYSTEM_EOL_LF   (cs); break;
     case EOL_CR:   new_coding_system = CODING_SYSTEM_EOL_CR   (cs); break;
     case EOL_CRLF: new_coding_system = CODING_SYSTEM_EOL_CRLF (cs); break;
-    default:       abort (); return Qnil;
+    default:       ABORT (); return Qnil;
     }
 
   return NILP (new_coding_system) ? coding_system : new_coding_system;
@@ -1260,7 +1260,7 @@ Return the type of CODING-SYSTEM.
 {
   switch (XCODING_SYSTEM_TYPE (Fget_coding_system (coding_system)))
     {
-    default: abort ();
+    default: ABORT ();
     case CODESYS_AUTODETECT:   return Qundecided;
 #ifdef MULE
     case CODESYS_SHIFT_JIS:    return Qshift_jis;
@@ -1336,7 +1336,7 @@ Return the PROP property of CODING-SYSTEM.
            break;
 #endif /* MULE */
          default:
-           abort ();
+           ABORT ();
          }
       }
 
@@ -1404,7 +1404,7 @@ Return the PROP property of CODING-SYSTEM.
          unparse_charset_conversion_specs
            (XCODING_SYSTEM (coding_system)->iso2022.output_conv);
       else
-       abort ();
+       ABORT ();
     }
   else if (type == CODESYS_CCL)
     {
@@ -1413,11 +1413,11 @@ Return the PROP property of CODING-SYSTEM.
       else if (EQ (prop, Qencode))
        return XCODING_SYSTEM_CCL_ENCODE (coding_system);
       else
-       abort ();
+       ABORT ();
     }
 #endif /* MULE */
   else
-    abort ();
+    ABORT ();
 
   return Qnil; /* not reached */
 }
@@ -1632,7 +1632,7 @@ mask_has_at_most_one_bit_p (int mask)
 
 static eol_type_t
 detect_eol_type (struct detection_state *st, const Extbyte *src,
-                size_t n)
+                Lstream_data_count n)
 {
   while (n--)
     {
@@ -1675,7 +1675,7 @@ detect_eol_type (struct detection_state *st, const Extbyte *src,
 
 static int
 detect_coding_type (struct detection_state *st, const Extbyte *src,
-                   size_t n, int just_do_eol)
+                   Lstream_data_count n, int just_do_eol)
 {
   if (st->eol_type == EOL_AUTODETECT)
     st->eol_type = detect_eol_type (st, src, n);
@@ -1785,6 +1785,8 @@ coding_system_from_mask (int mask)
    that should be unnecessary with the explicit eol-type argument. */
 
 #define LENGTH(string_constant) (sizeof (string_constant) - 1)
+/* number of leading lines to check for a coding cookie */
+#define LINES_TO_CHECK 2
 
 void
 determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
@@ -1806,15 +1808,15 @@ determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
       Extbyte buf[4096];
       Lisp_Object coding_system = Qnil;
       Extbyte *p;
-      ssize_t nread = Lstream_read (stream, buf, sizeof (buf));
+      Lstream_data_count nread = Lstream_read (stream, buf, sizeof (buf));
       Extbyte *scan_end;
+      int lines_checked = 0;
 
       /* Look for initial "-*-"; mode line prefix */
       for (p = buf,
             scan_end = buf + nread - LENGTH ("-*-coding:?-*-");
           p <= scan_end
-            && *p != '\n'
-            && *p != '\r';
+            && lines_checked < LINES_TO_CHECK;
           p++)
        if (*p == '-' && *(p+1) == '*' && *(p+2) == '-')
          {
@@ -1823,8 +1825,7 @@ determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
            for (p = local_vars_beg,
                   scan_end = buf + nread - LENGTH ("-*-");
                 p <= scan_end
-                  && *p != '\n'
-                  && *p != '\r';
+                  && lines_checked < LINES_TO_CHECK;
                 p++)
              if (*p == '-' && *(p+1) == '*' && *(p+2) == '-')
                {
@@ -1866,8 +1867,24 @@ determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
                      }
                  break;
                }
+             /* #### file must use standard EOLs or we miss 2d line */
+             /* #### not to mention this is broken for UTF-16 DOS files */
+             else if (*p == '\n' || *p == '\r')
+               {
+                 lines_checked++;
+                 /* skip past multibyte (DOS) newline */
+                 if (*p == '\r' && *(p+1) == '\n') p++;
+               }
            break;
          }
+       /* #### file must use standard EOLs or we miss 2d line */
+       /* #### not to mention this is broken for UTF-16 DOS files */
+       else if (*p == '\n' || *p == '\r')
+         {
+           lines_checked++;
+           /* skip past multibyte (DOS) newline */
+           if (*p == '\r' && *(p+1) == '\n') p++;
+         }
 
       if (NILP (coding_system))
        do
@@ -1940,7 +1957,7 @@ type.  Optional arg BUFFER defaults to the current buffer.
   while (1)
     {
       Extbyte random_buffer[4096];
-      ssize_t nread = Lstream_read (istr, random_buffer, sizeof (random_buffer));
+      Lstream_data_count nread = Lstream_read (istr, random_buffer, sizeof (random_buffer));
 
       if (!nread)
        break;
@@ -2026,6 +2043,62 @@ do {                                                             \
 /* C should be a binary character in the range 0 - 255; convert
    to internal format and add to Dynarr DST. */
 
+#ifdef UTF2000
+#define DECODE_ADD_BINARY_CHAR(c, dst) \
+do {                                           \
+  if (BYTE_ASCII_P (c))                                \
+    Dynarr_add (dst, c);                       \
+  else                                         \
+    {                                          \
+      Dynarr_add (dst, (c >> 6) | 0xc0);       \
+      Dynarr_add (dst, (c & 0x3f) | 0x80);     \
+    }                                          \
+} while (0)
+
+INLINE void
+DECODE_ADD_UCS_CHAR(Emchar c, unsigned_char_dynarr* dst)
+{
+  if ( c <= 0x7f )
+    {
+      Dynarr_add (dst, c);
+    }
+  else if ( c <= 0x7ff )
+    {
+      Dynarr_add (dst, (c >> 6) | 0xc0);
+      Dynarr_add (dst, (c & 0x3f) | 0x80);
+    }
+  else if ( c <= 0xffff )
+    {
+      Dynarr_add (dst,  (c >> 12) | 0xe0);
+      Dynarr_add (dst, ((c >>  6) & 0x3f) | 0x80);
+      Dynarr_add (dst,  (c        & 0x3f) | 0x80);
+    }
+  else if ( c <= 0x1fffff )
+    {
+      Dynarr_add (dst,  (c >> 18) | 0xf0);
+      Dynarr_add (dst, ((c >> 12) & 0x3f) | 0x80);
+      Dynarr_add (dst, ((c >>  6) & 0x3f) | 0x80);
+      Dynarr_add (dst,  (c        & 0x3f) | 0x80);
+    }
+  else if ( c <= 0x3ffffff )
+    {
+      Dynarr_add (dst,  (c >> 24) | 0xf8);
+      Dynarr_add (dst, ((c >> 18) & 0x3f) | 0x80);
+      Dynarr_add (dst, ((c >> 12) & 0x3f) | 0x80);
+      Dynarr_add (dst, ((c >>  6) & 0x3f) | 0x80);
+      Dynarr_add (dst,  (c        & 0x3f) | 0x80);
+    }
+  else
+    {
+      Dynarr_add (dst,  (c >> 30) | 0xfc);
+      Dynarr_add (dst, ((c >> 24) & 0x3f) | 0x80);
+      Dynarr_add (dst, ((c >> 18) & 0x3f) | 0x80);
+      Dynarr_add (dst, ((c >> 12) & 0x3f) | 0x80);
+      Dynarr_add (dst, ((c >>  6) & 0x3f) | 0x80);
+      Dynarr_add (dst,  (c        & 0x3f) | 0x80);
+    }
+}
+#else
 #define DECODE_ADD_BINARY_CHAR(c, dst)         \
 do {                                           \
   if (BYTE_ASCII_P (c))                                \
@@ -2041,6 +2114,7 @@ do {                                              \
       Dynarr_add (dst, c);                     \
     }                                          \
 } while (0)
+#endif
 
 #define DECODE_OUTPUT_PARTIAL_CHAR(ch) \
 do {                                   \
@@ -2107,10 +2181,10 @@ struct decoding_stream
   struct detection_state decst;
 };
 
-static ssize_t decoding_reader (Lstream *stream,
-                               unsigned char *data, size_t size);
-static ssize_t decoding_writer (Lstream *stream,
-                               const unsigned char *data, size_t size);
+static Lstream_data_count decoding_reader (Lstream *stream,
+                               unsigned char *data, Lstream_data_count size);
+static Lstream_data_count decoding_writer (Lstream *stream,
+                               const unsigned char *data, Lstream_data_count size);
 static int decoding_rewinder   (Lstream *stream);
 static int decoding_seekable_p (Lstream *stream);
 static int decoding_flusher    (Lstream *stream);
@@ -2142,12 +2216,12 @@ decoding_marker (Lisp_Object stream)
 /* Read SIZE bytes of data and store it into DATA.  We are a decoding stream
    so we read data from the other end, decode it, and store it into DATA. */
 
-static ssize_t
-decoding_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+decoding_reader (Lstream *stream, unsigned char *data, Lstream_data_count size)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (stream);
   unsigned char *orig_data = data;
-  ssize_t read_size;
+  Lstream_data_count read_size;
   int error_occurred = 0;
 
   /* We need to interface to mule_decode(), which expects to take some
@@ -2163,7 +2237,7 @@ decoding_reader (Lstream *stream, unsigned char *data, size_t size)
         most SIZE bytes, and delete the data from the runoff. */
       if (Dynarr_length (str->runoff) > 0)
        {
-         size_t chunk = min (size, (size_t) Dynarr_length (str->runoff));
+         Lstream_data_count chunk = min (size, (Lstream_data_count) Dynarr_length (str->runoff));
          memcpy (data, Dynarr_atp (str->runoff, 0), chunk);
          Dynarr_delete_many (str->runoff, 0, chunk);
          data += chunk;
@@ -2204,11 +2278,11 @@ decoding_reader (Lstream *stream, unsigned char *data, size_t size)
     return data - orig_data;
 }
 
-static ssize_t
-decoding_writer (Lstream *stream, const unsigned char *data, size_t size)
+static Lstream_data_count
+decoding_writer (Lstream *stream, const unsigned char *data, Lstream_data_count size)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (stream);
-  ssize_t retval;
+  Lstream_data_count retval;
 
   /* Decode all our data into the runoff, and then attempt to write
      it all out to the other end.  Remove whatever chunk we succeeded
@@ -2366,7 +2440,7 @@ make_decoding_output_stream (Lstream *stream, Lisp_Object codesys)
 
 static void
 mule_decode (Lstream *decoding, const Extbyte *src,
-            unsigned_char_dynarr *dst, size_t n)
+            unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
 
@@ -2440,7 +2514,7 @@ mule_decode (Lstream *decoding, const Extbyte *src,
       break;
 #endif /* MULE */
     default:
-      abort ();
+      ABORT ();
     }
 }
 
@@ -2488,7 +2562,7 @@ BUFFER defaults to the current buffer if unspecified.
       char tempbuf[1024]; /* some random amount */
       Bufpos newpos, even_newer_pos;
       Bufpos oldpos = lisp_buffer_stream_startpos (istr);
-      ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+      Lstream_data_count size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
 
       if (!size_in_bytes)
        break;
@@ -2573,9 +2647,9 @@ struct encoding_stream
 #endif /* MULE */
 };
 
-static ssize_t encoding_reader (Lstream *stream, unsigned char *data, size_t size);
-static ssize_t encoding_writer (Lstream *stream, const unsigned char *data,
-                               size_t size);
+static Lstream_data_count encoding_reader (Lstream *stream, unsigned char *data, Lstream_data_count size);
+static Lstream_data_count encoding_writer (Lstream *stream, const unsigned char *data,
+                               Lstream_data_count size);
 static int encoding_rewinder   (Lstream *stream);
 static int encoding_seekable_p (Lstream *stream);
 static int encoding_flusher    (Lstream *stream);
@@ -2607,12 +2681,12 @@ encoding_marker (Lisp_Object stream)
 /* Read SIZE bytes of data and store it into DATA.  We are a encoding stream
    so we read data from the other end, encode it, and store it into DATA. */
 
-static ssize_t
-encoding_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+encoding_reader (Lstream *stream, unsigned char *data, Lstream_data_count size)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (stream);
   unsigned char *orig_data = data;
-  ssize_t read_size;
+  Lstream_data_count read_size;
   int error_occurred = 0;
 
   /* We need to interface to mule_encode(), which expects to take some
@@ -2669,11 +2743,11 @@ encoding_reader (Lstream *stream, unsigned char *data, size_t size)
     return data - orig_data;
 }
 
-static ssize_t
-encoding_writer (Lstream *stream, const unsigned char *data, size_t size)
+static Lstream_data_count
+encoding_writer (Lstream *stream, const unsigned char *data, Lstream_data_count size)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (stream);
-  ssize_t retval;
+  Lstream_data_count retval;
 
   /* Encode all our data into the runoff, and then attempt to write
      it all out to the other end.  Remove whatever chunk we succeeded
@@ -2710,7 +2784,11 @@ reset_encoding_stream (struct encoding_stream *str)
        str->iso2022.register_right = 1;
        str->iso2022.current_charset = Qnil;
        str->iso2022.current_half = 0;
+#ifdef UTF2000
+       str->iso2022.current_char_boundary = 0;
+#else
        str->iso2022.current_char_boundary = 1;
+#endif
        break;
       }
     case CODESYS_CCL:
@@ -2813,7 +2891,7 @@ make_encoding_output_stream (Lstream *stream, Lisp_Object codesys)
 
 static void
 mule_encode (Lstream *encoding, const Bufbyte *src,
-            unsigned_char_dynarr *dst, size_t n)
+            unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
 
@@ -2855,7 +2933,7 @@ mule_encode (Lstream *encoding, const Bufbyte *src,
       break;
 #endif /* MULE */
     default:
-      abort ();
+      ABORT ();
     }
 }
 
@@ -2899,7 +2977,7 @@ text.  BUFFER defaults to the current buffer if unspecified.
       char tempbuf[1024]; /* some random amount */
       Bufpos newpos, even_newer_pos;
       Bufpos oldpos = lisp_buffer_stream_startpos (istr);
-      ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+      Lstream_data_count size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
 
       if (!size_in_bytes)
        break;
@@ -2962,7 +3040,7 @@ text.  BUFFER defaults to the current buffer if unspecified.
   ((c) >= 0xA1 && (c) <= 0xDF)
 
 static int
-detect_coding_sjis (struct detection_state *st, const Extbyte *src, size_t n)
+detect_coding_sjis (struct detection_state *st, const Extbyte *src, Lstream_data_count n)
 {
   while (n--)
     {
@@ -2985,7 +3063,7 @@ detect_coding_sjis (struct detection_state *st, const Extbyte *src, size_t n)
 
 static void
 decode_coding_sjis (Lstream *decoding, const Extbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags  = str->flags;
@@ -3003,10 +3081,16 @@ decode_coding_sjis (Lstream *decoding, const Extbyte *src,
            {
              unsigned char e1, e2;
 
-             Dynarr_add (dst, LEADING_BYTE_JAPANESE_JISX0208);
              DECODE_SJIS (ch, c, e1, e2);
+#ifdef UTF2000
+             DECODE_ADD_UCS_CHAR(MAKE_CHAR(Vcharset_japanese_jisx0208,
+                                           e1 & 0x7F,
+                                           e2 & 0x7F), dst);
+#else
+             Dynarr_add (dst, LEADING_BYTE_JAPANESE_JISX0208);
              Dynarr_add (dst, e1);
              Dynarr_add (dst, e2);
+#endif
            }
          else
            {
@@ -3022,8 +3106,13 @@ decode_coding_sjis (Lstream *decoding, const Extbyte *src,
            ch = c;
          else if (BYTE_SJIS_KATAKANA_P (c))
            {
+#ifdef UTF2000
+             DECODE_ADD_UCS_CHAR(MAKE_CHAR(Vcharset_katakana_jisx0201,
+                                           c & 0x7F, 0), dst);
+#else
              Dynarr_add (dst, LEADING_BYTE_KATAKANA_JISX0201);
              Dynarr_add (dst, c);
+#endif
            }
          else
            DECODE_ADD_BINARY_CHAR (c, dst);
@@ -3041,16 +3130,88 @@ decode_coding_sjis (Lstream *decoding, const Extbyte *src,
 
 static void
 encode_coding_sjis (Lstream *encoding, const Bufbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags  = str->flags;
   unsigned int ch     = str->ch;
   eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys);
+#ifdef UTF2000
+  unsigned char char_boundary = str->iso2022.current_char_boundary;
+#endif
 
   while (n--)
     {
       Bufbyte c = *src++;
+#ifdef UTF2000
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             ch = c & 0x01;
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             ch = c & 0x03;
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             ch = c & 0x07;
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             ch = c & 0x0f;
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             ch = c & 0x1f;
+             char_boundary = 1;
+           }
+         else
+           {
+             ch = 0;
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               Dynarr_add (dst, c);
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         {
+           Lisp_Object charset;
+           unsigned int c1, c2, s1, s2;
+           
+           BREAKUP_CHAR (ch, charset, c1, c2);
+           if (EQ(charset, Vcharset_katakana_jisx0201))
+             {
+               Dynarr_add (dst, c1 | 0x80);
+             }
+           else if (EQ(charset, Vcharset_japanese_jisx0208))
+             {
+               ENCODE_SJIS (c1 | 0x80, c2 | 0x80, s1, s2);
+               Dynarr_add (dst, s1);
+               Dynarr_add (dst, s2);
+             }
+         }
+         char_boundary = 0;
+         break;
+       default:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         char_boundary--;
+       }
+#else
       if (c == '\n')
        {
          if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
@@ -3087,10 +3248,14 @@ encode_coding_sjis (Lstream *encoding, const Bufbyte *src,
              ch = 0;
            }
        }
+#endif
     }
 
   str->flags = flags;
   str->ch    = ch;
+#ifdef UTF2000
+  str->iso2022.current_char_boundary = char_boundary;
+#endif
 }
 
 DEFUN ("decode-shift-jis-char", Fdecode_shift_jis_char, 1, 1, 0, /*
@@ -3243,7 +3408,7 @@ Return the corresponding character code in SHIFT-JIS as a cons of two bytes.
 } while (0)
 
 static int
-detect_coding_big5 (struct detection_state *st, const Extbyte *src, size_t n)
+detect_coding_big5 (struct detection_state *st, const Extbyte *src, Lstream_data_count n)
 {
   while (n--)
     {
@@ -3267,7 +3432,7 @@ detect_coding_big5 (struct detection_state *st, const Extbyte *src, size_t n)
 
 static void
 decode_coding_big5 (Lstream *decoding, const Extbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags  = str->flags;
@@ -3316,8 +3481,9 @@ decode_coding_big5 (Lstream *decoding, const Extbyte *src,
 
 static void
 encode_coding_big5 (Lstream *encoding, const Bufbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
+#ifndef UTF2000
   unsigned char c;
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags  = str->flags;
@@ -3372,6 +3538,7 @@ encode_coding_big5 (Lstream *encoding, const Bufbyte *src,
 
   str->flags = flags;
   str->ch    = ch;
+#endif
 }
 
 
@@ -3392,7 +3559,7 @@ Return the corresponding character.
   if (BYTE_BIG5_TWO_BYTE_1_P (b1) &&
       BYTE_BIG5_TWO_BYTE_2_P (b2))
     {
-      int leading_byte;
+      Charset_ID leading_byte;
       Lisp_Object charset;
       DECODE_BIG5 (b1, b2, leading_byte, c1, c2);
       charset = CHARSET_BY_LEADING_BYTE (leading_byte);
@@ -3432,7 +3599,7 @@ Return the corresponding character code in Big5.
 /*                                                                      */
 /************************************************************************/
 
-
+#ifndef UTF2000
 DEFUN ("set-ucs-char", Fset_ucs_char, 2, 2, 0, /*
 Map UCS-4 code CODE to Mule character CHARACTER.
 
@@ -3470,7 +3637,7 @@ ucs_to_char (unsigned long code)
       c = code % (94 * 94);
       return make_char
        (MAKE_CHAR (CHARSET_BY_ATTRIBUTES
-                   (CHARSET_TYPE_94X94, code / (94 * 94) + '@',
+                   (94, 2, code / (94 * 94) + '@',
                     CHARSET_LEFT_TO_RIGHT),
                    c / 94 + 33, c % 94 + 33));
     }
@@ -3507,7 +3674,11 @@ Return the UCS code (a positive integer) corresponding to CHARACTER.
 {
   return Fget_char_table (character, mule_to_ucs_table);
 }
+#endif
 
+#ifdef UTF2000
+#define decode_ucs4 DECODE_ADD_UCS_CHAR
+#else
 /* Decode a UCS-4 character into a buffer.  If the lookup fails, use
    <GETA MARK> (U+3013) of JIS X 0208, which means correct character
    is not found, instead.
@@ -3536,7 +3707,9 @@ decode_ucs4 (unsigned long ch, unsigned_char_dynarr *dst)
       Dynarr_add (dst, 46 + 128);
     }
 }
+#endif
 
+#ifndef UTF2000
 static unsigned long
 mule_char_to_ucs4 (Lisp_Object charset,
                   unsigned char h, unsigned char l)
@@ -3580,9 +3753,10 @@ encode_ucs4 (Lisp_Object charset,
   Dynarr_add (dst, (code >>  8) & 255);
   Dynarr_add (dst,  code        & 255);
 }
+#endif
 
 static int
-detect_coding_ucs4 (struct detection_state *st, const Extbyte *src, size_t n)
+detect_coding_ucs4 (struct detection_state *st, const Extbyte *src, Lstream_data_count n)
 {
   while (n--)
     {
@@ -3607,7 +3781,7 @@ detect_coding_ucs4 (struct detection_state *st, const Extbyte *src, size_t n)
 
 static void
 decode_coding_ucs4 (Lstream *decoding, const Extbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags = str->flags;
@@ -3643,8 +3817,9 @@ decode_coding_ucs4 (Lstream *decoding, const Extbyte *src,
 
 static void
 encode_coding_ucs4 (Lstream *encoding, const Bufbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
+#ifndef UTF2000
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags = str->flags;
   unsigned int ch = str->ch;
@@ -3751,7 +3926,7 @@ encode_coding_ucs4 (Lstream *encoding, const Bufbyte *src,
                    }
                  break;
                default:
-                 abort ();
+                 ABORT ();
                }
            }
        }
@@ -3773,6 +3948,7 @@ encode_coding_ucs4 (Lstream *encoding, const Bufbyte *src,
   str->iso2022.current_charset = charset;
 
   /* Verbum caro factum est! */
+#endif
 }
 
 \f
@@ -3781,7 +3957,7 @@ encode_coding_ucs4 (Lstream *encoding, const Bufbyte *src,
 /************************************************************************/
 
 static int
-detect_coding_utf8 (struct detection_state *st, const Extbyte *src, size_t n)
+detect_coding_utf8 (struct detection_state *st, const Extbyte *src, Lstream_data_count n)
 {
   while (n--)
     {
@@ -3816,7 +3992,7 @@ detect_coding_utf8 (struct detection_state *st, const Extbyte *src, size_t n)
 
 static void
 decode_coding_utf8 (Lstream *decoding, const Extbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags  = str->flags;
@@ -3882,6 +4058,7 @@ decode_coding_utf8 (Lstream *decoding, const Extbyte *src,
   str->counter = counter;
 }
 
+#ifndef UTF2000
 static void
 encode_utf8 (Lisp_Object charset,
             unsigned char h, unsigned char l, unsigned_char_dynarr *dst)
@@ -3927,16 +4104,74 @@ encode_utf8 (Lisp_Object charset,
       Dynarr_add (dst,  (code        & 0x3f) | 0x80);
     }
 }
+#endif
 
 static void
 encode_coding_utf8 (Lstream *encoding, const Bufbyte *src,
-                   unsigned_char_dynarr *dst, size_t n)
+                   unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags  = str->flags;
   unsigned int ch     = str->ch;
   eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys);
   unsigned char char_boundary = str->iso2022.current_char_boundary;
+#ifdef UTF2000
+
+  while (n--)
+    {
+      unsigned char c = *src++;          
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             Dynarr_add (dst, c);
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             Dynarr_add (dst, c);
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             Dynarr_add (dst, c);
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             Dynarr_add (dst, c);
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             Dynarr_add (dst, c);
+             char_boundary = 1;
+           }
+         else
+           {
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               Dynarr_add (dst, c);
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         Dynarr_add (dst, c);
+         char_boundary = 0;
+         break;
+       default:
+         Dynarr_add (dst, c);
+         char_boundary--;
+       }
+    }
+#else /* not UTF2000 */
   Lisp_Object charset = str->iso2022.current_charset;
 
 #ifdef ENABLE_COMPOSITE_CHARS
@@ -4044,7 +4279,7 @@ encode_coding_utf8 (Lstream *encoding, const Bufbyte *src,
                    }
                  break;
                default:
-                 abort ();
+                 ABORT ();
                }
            }
        }
@@ -4060,10 +4295,13 @@ encode_coding_utf8 (Lstream *encoding, const Bufbyte *src,
     }
 #endif
 
+#endif /* not UTF2000 */
   str->flags = flags;
   str->ch    = ch;
   str->iso2022.current_char_boundary = char_boundary;
+#ifndef UTF2000
   str->iso2022.current_charset = charset;
+#endif
 
   /* Verbum caro factum est! */
 }
@@ -4559,7 +4797,7 @@ parse_iso2022_esc (Lisp_Object codesys, struct iso2022_decoder *iso,
        }
       if (0x40 <= c && c <= 0x42)
        {
-         cs = CHARSET_BY_ATTRIBUTES (CHARSET_TYPE_94X94, c,
+         cs = CHARSET_BY_ATTRIBUTES (94, 2, c,
                                      *flags & CODING_STATE_R2L ?
                                      CHARSET_RIGHT_TO_LEFT :
                                      CHARSET_LEFT_TO_RIGHT);
@@ -4570,7 +4808,9 @@ parse_iso2022_esc (Lisp_Object codesys, struct iso2022_decoder *iso,
 
     default:
       {
-       int type =-1;
+       /* int type =-1; */
+       int chars = 0;
+       int single = 0;
 
        if (c < '0' || c > '~')
          return 0; /* bad final byte */
@@ -4578,25 +4818,25 @@ parse_iso2022_esc (Lisp_Object codesys, struct iso2022_decoder *iso,
        if (iso->esc >= ISO_ESC_2_8 &&
            iso->esc <= ISO_ESC_2_15)
          {
-           type = ((iso->esc >= ISO_ESC_2_12) ?
-                   CHARSET_TYPE_96 : CHARSET_TYPE_94);
+           chars = (iso->esc >= ISO_ESC_2_12) ? 96 : 94;
+           single = 1; /* single-byte */
            reg = (iso->esc - ISO_ESC_2_8) & 3;
          }
        else if (iso->esc >= ISO_ESC_2_4_8 &&
                 iso->esc <= ISO_ESC_2_4_15)
          {
-           type = ((iso->esc >= ISO_ESC_2_4_12) ?
-                   CHARSET_TYPE_96X96 : CHARSET_TYPE_94X94);
+           chars = (iso->esc >= ISO_ESC_2_4_12) ? 96 : 94;
+           single = -1; /* multi-byte */
            reg = (iso->esc - ISO_ESC_2_4_8) & 3;
          }
        else
          {
            /* Can this ever be reached? -slb */
-           abort();
+           ABORT();
            return 0;
          }
 
-       cs = CHARSET_BY_ATTRIBUTES (type, c,
+       cs = CHARSET_BY_ATTRIBUTES (chars, single, c,
                                    *flags & CODING_STATE_R2L ?
                                    CHARSET_RIGHT_TO_LEFT :
                                    CHARSET_LEFT_TO_RIGHT);
@@ -4689,7 +4929,7 @@ parse_iso2022_esc (Lisp_Object codesys, struct iso2022_decoder *iso,
 }
 
 static int
-detect_coding_iso2022 (struct detection_state *st, const Extbyte *src, size_t n)
+detect_coding_iso2022 (struct detection_state *st, const Extbyte *src, Lstream_data_count n)
 {
   int mask;
 
@@ -4880,7 +5120,7 @@ ensure_correct_direction (int direction, Lisp_Coding_System *codesys,
 
 static void
 decode_coding_iso2022 (Lstream *decoding, const Extbyte *src,
-                      unsigned_char_dynarr *dst, size_t n)
+                      unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags  = str->flags;
@@ -5004,7 +5244,9 @@ decode_coding_iso2022 (Lstream *decoding, const Extbyte *src,
       else
        {                       /* Graphic characters */
          Lisp_Object charset;
-         int lb;
+#ifndef UTF2000
+         Charset_ID lb;
+#endif
          int reg;
 
          DECODE_HANDLE_EOL_TYPE (eol_type, c, flags, dst);
@@ -5047,6 +5289,22 @@ decode_coding_iso2022 (Lstream *decoding, const Extbyte *src,
                    charset = new_charset;
                }
 
+#ifdef UTF2000
+             if (XCHARSET_DIMENSION (charset) == 1)
+               {
+                 DECODE_OUTPUT_PARTIAL_CHAR (ch);
+                 DECODE_ADD_UCS_CHAR
+                   (MAKE_CHAR (charset, c & 0x7F, 0), dst);
+               }
+             else if (ch)
+               {
+                 DECODE_ADD_UCS_CHAR
+                   (MAKE_CHAR (charset, ch & 0x7F, c & 0x7F), dst);
+                 ch = 0;
+               }
+             else
+               ch = c;
+#else
              lb = XCHARSET_LEADING_BYTE (charset);
              switch (XCHARSET_REP_BYTES (charset))
                {
@@ -5095,6 +5353,7 @@ decode_coding_iso2022 (Lstream *decoding, const Extbyte *src,
                  else
                    ch = c;
                }
+#endif
            }
 
          if (!ch)
@@ -5206,18 +5465,21 @@ ensure_shift_out (struct encoding_stream *str, unsigned_char_dynarr *dst)
 
 static void
 encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
-                      unsigned_char_dynarr *dst, size_t n)
+                      unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   unsigned char charmask, c;
   unsigned char char_boundary;
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags          = str->flags;
-  unsigned int ch             = str->ch;
+  Emchar ch                   = str->ch;
   Lisp_Coding_System *codesys = str->codesys;
   eol_type_t eol_type         = CODING_SYSTEM_EOL_TYPE (str->codesys);
   int i;
   Lisp_Object charset;
   int half;
+#ifdef UTF2000
+  unsigned int byte1, byte2;
+#endif
 
 #ifdef ENABLE_COMPOSITE_CHARS
   /* flags for handling composite chars.  We do a little switcharoo
@@ -5234,6 +5496,216 @@ encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
 #ifdef ENABLE_COMPOSITE_CHARS
  back_to_square_n:
 #endif
+#ifdef UTF2000
+  while (n--)
+    {
+      c = *src++;
+
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             ch = c & 0x01;
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             ch = c & 0x03;
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             ch = c & 0x07;
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             ch = c & 0x0f;
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             ch = c & 0x1f;
+             char_boundary = 1;
+           }
+         else
+           {
+             ch = 0;
+
+             restore_left_to_right_direction (codesys, dst, &flags, 0);
+             
+             /* Make sure G0 contains ASCII */
+             if ((c > ' ' && c < ISO_CODE_DEL) ||
+                 !CODING_SYSTEM_ISO2022_NO_ASCII_CNTL (codesys))
+               {
+                 ensure_normal_shift (str, dst);
+                 iso2022_designate (Vcharset_ascii, 0, str, dst);
+               }
+             
+             /* If necessary, restore everything to the default state
+                at end-of-line */
+             if (c == '\n' &&
+                 !(CODING_SYSTEM_ISO2022_NO_ASCII_EOL (codesys)))
+               {
+                 restore_left_to_right_direction (codesys, dst, &flags, 0);
+
+                 ensure_normal_shift (str, dst);
+
+                 for (i = 0; i < 4; i++)
+                   {
+                     Lisp_Object initial_charset =
+                       CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i);
+                     iso2022_designate (initial_charset, i, str, dst);
+                   }
+               }
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               {
+                 if (CODING_SYSTEM_ISO2022_ESCAPE_QUOTED (codesys)
+                     && fit_to_be_escape_quoted (c))
+                   Dynarr_add (dst, ISO_CODE_ESC);
+                 Dynarr_add (dst, c);
+               }
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         
+         char_boundary = 0;
+         if ( (0x80 <= ch) && (ch <= 0x9f) )
+           {
+             charmask = (half == 0 ? 0x00 : 0x80);
+         
+             if (CODING_SYSTEM_ISO2022_ESCAPE_QUOTED (codesys)
+                 && fit_to_be_escape_quoted (ch))
+               Dynarr_add (dst, ISO_CODE_ESC);
+             /* you asked for it ... */
+             Dynarr_add (dst, ch);
+           }
+         else
+           {
+             int reg;
+
+             BREAKUP_CHAR (ch, charset, byte1, byte2);
+             ensure_correct_direction (XCHARSET_DIRECTION (charset),
+                                       codesys, dst, &flags, 0);
+
+             /* Now determine which register to use. */
+             reg = -1;
+             for (i = 0; i < 4; i++)
+               {
+                 if (EQ (charset, str->iso2022.charset[i]) ||
+                     EQ (charset,
+                         CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i)))
+                   {
+                     reg = i;
+                     break;
+                   }
+               }
+             
+             if (reg == -1)
+               {
+                 if (XCHARSET_GRAPHIC (charset) != 0)
+                   {
+                     if (!NILP (str->iso2022.charset[1]) &&
+                         (!CODING_SYSTEM_ISO2022_SEVEN (codesys) ||
+                          CODING_SYSTEM_ISO2022_LOCK_SHIFT (codesys)))
+                       reg = 1;
+                     else if (!NILP (str->iso2022.charset[2]))
+                       reg = 2;
+                     else if (!NILP (str->iso2022.charset[3]))
+                       reg = 3;
+                     else
+                       reg = 0;
+                   }
+                 else
+                   reg = 0;
+               }
+             
+             iso2022_designate (charset, reg, str, dst);
+             
+             /* Now invoke that register. */
+             switch (reg)
+               {
+               case 0:
+                 ensure_normal_shift (str, dst);
+                 half = 0;
+                 break;
+                 
+               case 1:
+                 if (CODING_SYSTEM_ISO2022_SEVEN (codesys))
+                   {
+                     ensure_shift_out (str, dst);
+                     half = 0;
+                   }
+                 else
+                   half = 1;
+                 break;
+                 
+               case 2:
+                 if (CODING_SYSTEM_ISO2022_SEVEN (str->codesys))
+                   {
+                     Dynarr_add (dst, ISO_CODE_ESC);
+                     Dynarr_add (dst, 'N');
+                     half = 0;
+                   }
+                 else
+                   {
+                     Dynarr_add (dst, ISO_CODE_SS2);
+                     half = 1;
+                   }
+                 break;
+                 
+               case 3:
+                 if (CODING_SYSTEM_ISO2022_SEVEN (str->codesys))
+                   {
+                     Dynarr_add (dst, ISO_CODE_ESC);
+                     Dynarr_add (dst, 'O');
+                     half = 0;
+                   }
+                 else
+                   {
+                     Dynarr_add (dst, ISO_CODE_SS3);
+                     half = 1;
+                   }
+                 break;
+                 
+               default:
+                 abort ();
+               }
+             
+             charmask = (half == 0 ? 0x00 : 0x80);
+             
+             switch (XCHARSET_DIMENSION (charset))
+               {
+               case 1:
+                 Dynarr_add (dst, byte1 | charmask);
+                 break;
+               case 2:
+                 Dynarr_add (dst, byte1 | charmask);
+                 Dynarr_add (dst, byte2 | charmask);
+                 break;
+               default:
+                 abort ();
+               }
+           }
+         ch =0;
+         break;
+       default:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         char_boundary--;
+       }
+    }
+#else /* not UTF2000 */
+
   while (n--)
     {
       c = *src++;
@@ -5383,7 +5855,7 @@ encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
                  break;
 
                default:
-                 abort ();
+                 ABORT ();
                }
            }
          char_boundary = 0;
@@ -5466,11 +5938,12 @@ encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
                    }
                  break;
                default:
-                 abort ();
+                 ABORT ();
                }
            }
        }
     }
+#endif /* not UTF2000 */
 
 #ifdef ENABLE_COMPOSITE_CHARS
   if (in_composite)
@@ -5484,7 +5957,11 @@ encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
     }
 #endif /* ENABLE_COMPOSITE_CHARS */
 
+#ifdef UTF2000
+  if ( (char_boundary == 0) && flags & CODING_STATE_END)
+#else
   if (char_boundary && flags & CODING_STATE_END)
+#endif
     {
       restore_left_to_right_direction (codesys, dst, &flags, 0);
       ensure_normal_shift (str, dst);
@@ -5515,7 +5992,7 @@ encode_coding_iso2022 (Lstream *encoding, const Bufbyte *src,
    interpreted as being in any particular decoding. */
 static void
 decode_coding_no_conversion (Lstream *decoding, const Extbyte *src,
-                            unsigned_char_dynarr *dst, size_t n)
+                            unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (decoding);
   unsigned int flags  = str->flags;
@@ -5539,17 +6016,75 @@ decode_coding_no_conversion (Lstream *decoding, const Extbyte *src,
 
 static void
 encode_coding_no_conversion (Lstream *encoding, const Bufbyte *src,
-                            unsigned_char_dynarr *dst, size_t n)
+                            unsigned_char_dynarr *dst, Lstream_data_count n)
 {
   unsigned char c;
   struct encoding_stream *str = ENCODING_STREAM_DATA (encoding);
   unsigned int flags  = str->flags;
   unsigned int ch     = str->ch;
   eol_type_t eol_type = CODING_SYSTEM_EOL_TYPE (str->codesys);
+#ifdef UTF2000
+  unsigned char char_boundary = str->iso2022.current_char_boundary;
+#endif
 
   while (n--)
     {
-      c = *src++;
+      c = *src++;        
+#ifdef UTF2000
+      switch (char_boundary)
+       {
+       case 0:
+         if ( c >= 0xfc )
+           {
+             ch = c & 0x01;
+             char_boundary = 5;
+           }
+         else if ( c >= 0xf8 )
+           {
+             ch = c & 0x03;
+             char_boundary = 4;
+           }
+         else if ( c >= 0xf0 )
+           {
+             ch = c & 0x07;
+             char_boundary = 3;
+           }
+         else if ( c >= 0xe0 )
+           {
+             ch = c & 0x0f;
+             char_boundary = 2;
+           }
+         else if ( c >= 0xc0 )
+           {
+             ch = c & 0x1f;
+             char_boundary = 1;
+           }
+         else
+           {
+             ch = 0;
+
+             if (c == '\n')
+               {
+                 if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
+                   Dynarr_add (dst, '\r');
+                 if (eol_type != EOL_CR)
+                   Dynarr_add (dst, c);
+               }
+             else
+               Dynarr_add (dst, c);
+             char_boundary = 0;
+           }
+         break;
+       case 1:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         Dynarr_add (dst, ch & 0xff);
+         char_boundary = 0;
+         break;
+       default:
+         ch = ( ch << 6 ) | ( c & 0x3f );
+         char_boundary--;
+       }
+#else /* not UTF2000 */
       if (c == '\n')
        {
          if (eol_type != EOL_LF && eol_type != EOL_AUTODETECT)
@@ -5585,10 +6120,14 @@ encode_coding_no_conversion (Lstream *encoding, const Bufbyte *src,
             untranslatable character, so ignore it */
          ch = 0;
        }
+#endif /* not UTF2000 */
     }
 
   str->flags = flags;
   str->ch    = ch;
+#ifdef UTF2000
+  str->iso2022.current_char_boundary = char_boundary;
+#endif
 }
 
 \f
@@ -5638,10 +6177,12 @@ syms_of_file_coding (void)
   DEFSUBR (Fencode_shift_jis_char);
   DEFSUBR (Fdecode_big5_char);
   DEFSUBR (Fencode_big5_char);
+#ifndef UTF2000
   DEFSUBR (Fset_ucs_char);
   DEFSUBR (Fucs_char);
   DEFSUBR (Fset_char_ucs);
   DEFSUBR (Fchar_ucs);
+#endif /* not UTF2000 */
 #endif /* MULE */
   defsymbol (&Qcoding_systemp, "coding-system-p");
   defsymbol (&Qno_conversion, "no-conversion");
@@ -5738,7 +6279,7 @@ vars_of_file_coding (void)
   int i;
 
   fcd = xnew (struct file_coding_dump);
-  dumpstruct (&fcd, &fcd_description);
+  dump_add_root_struct_ptr (&fcd, &fcd_description);
 
   /* Initialize to something reasonable ... */
   for (i = 0; i < CODING_CATEGORY_LAST; i++)
@@ -5805,7 +6346,7 @@ complex_vars_of_file_coding (void)
     make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
 
   the_codesys_prop_dynarr = Dynarr_new (codesys_prop);
-  dumpstruct (&the_codesys_prop_dynarr, &codesys_prop_dynarr_description);
+  dump_add_root_struct_ptr (&the_codesys_prop_dynarr, &codesys_prop_dynarr_description);
 
 #define DEFINE_CODESYS_PROP(Prop_Type, Sym) do \
 {                                              \
@@ -5856,6 +6397,13 @@ complex_vars_of_file_coding (void)
      list4 (Qeol_type, Qlf,
            Qmnemonic, build_string ("Binary")));
 
+#ifdef UTF2000
+  Fmake_coding_system
+    (Qutf8, Qutf8,
+     build_string ("Coding-system of ISO/IEC 10646 UTF-8."),
+     list2 (Qmnemonic, build_string ("UTF8")));
+#endif
+
   Fdefine_coding_system_alias (Qno_conversion, Qraw_text);
 
   Fdefine_coding_system_alias (Qfile_name, Qbinary);
@@ -5867,7 +6415,12 @@ complex_vars_of_file_coding (void)
   fcd->coding_category_system[CODING_CATEGORY_NO_CONVERSION] =
     Fget_coding_system (Qraw_text);
 
-#ifdef MULE
+#ifdef UTF2000
+  fcd->coding_category_system[CODING_CATEGORY_UTF8]
+   = Fget_coding_system (Qutf8);
+#endif
+
+#if defined(MULE) && !defined(UTF2000)
   {
     size_t i;
 
@@ -5876,5 +6429,5 @@ complex_vars_of_file_coding (void)
   }
   staticpro (&mule_to_ucs_table);
   mule_to_ucs_table = Fmake_char_table(Qgeneric);
-#endif /* MULE */
+#endif /* defined(MULE) && !defined(UTF2000) */
 }