+ if (STRINGP (table))
+ {
+ Lisp_String *stable = XSTRING (table);
+ Charcount size = string_char_length (stable);
+#ifdef MULE
+ /* Under Mule, string_char(n) is O(n), so for large tables or
+ large regions it makes sense to create an array of Emchars. */
+ if (size * (stop - pos) > 65536)
+ {
+ Emchar *etable = alloca_array (Emchar, size);
+ convert_bufbyte_string_into_emchar_string
+ (string_data (stable), string_length (stable), etable);
+ for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
+ {
+ if (oc < size)
+ {
+ Emchar nc = etable[oc];
+ if (nc != oc)
+ {
+ buffer_replace_char (buf, pos, nc, 0, 0);
+ ++cnt;
+ }
+ }
+ }
+ }
+ else
+#endif /* MULE */
+ {
+ for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
+ {
+ if (oc < size)
+ {
+ Emchar nc = string_char (stable, oc);
+ if (nc != oc)
+ {
+ buffer_replace_char (buf, pos, nc, 0, 0);
+ ++cnt;
+ }
+ }
+ }
+ }
+ }
+ else if (VECTORP (table))
+ {
+ Charcount size = XVECTOR_LENGTH (table);
+ Lisp_Object *vtable = XVECTOR_DATA (table);
+
+ for (; pos < stop && (oc = BUF_FETCH_CHAR (buf, pos), 1); pos++)
+ {
+ if (oc < size)
+ {
+ Lisp_Object replacement = vtable[oc];
+ retry:
+ if (CHAR_OR_CHAR_INTP (replacement))
+ {
+ Emchar nc = XCHAR_OR_CHAR_INT (replacement);
+ if (nc != oc)
+ {
+ buffer_replace_char (buf, pos, nc, 0, 0);
+ ++cnt;
+ }
+ }
+ else if (STRINGP (replacement))
+ {
+ Charcount incr = XSTRING_CHAR_LENGTH (replacement) - 1;
+ buffer_delete_range (buf, pos, pos + 1, 0);
+ buffer_insert_lisp_string_1 (buf, pos, replacement, 0);
+ pos += incr, stop += incr;
+ ++cnt;
+ }
+ else if (!NILP (replacement))
+ {
+ replacement = wrong_type_argument (Qchar_or_string_p, replacement);
+ goto retry;
+ }
+ }
+ }
+ }
+ else if (CHAR_TABLEP (table)
+ && (XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_GENERIC
+ || XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_CHAR))