From c230dd7d89730f565df77046d0666d2082e386ee Mon Sep 17 00:00:00 2001 From: Kenichi Handa Date: Sun, 10 Mar 2013 23:36:35 +0900 Subject: [PATCH] On file insertion, skip decoding if all bytes are ASCII. --- src/ChangeLog | 14 ++++++++++++++ src/coding.c | 43 +++++++++++++++++++++++++++++++++++++++---- src/insdel.c | 19 ++++++++++++------- src/lisp.h | 4 ++++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index ae25a3c5d00..2c77950c262 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2013-03-10 handa + + * lisp.h (adjust_after_replace): Extern it. + + * coding.c (detect_coding): Cound the heading ASCII bytes in the + case of detection for coding_category_utf_8_auto. + (decode_coding_gap) [not CODING_DISABLE_ASCII_OPTIMIZATION]: Skip + decoding if all bytes are ASCII. + + * insdel.c (adjust_after_replace): Make it public. New arg + text_at_gap_tail. + (adjust_after_insert): Call adjust_after_replace with the new arg + value 0. + 2013-03-09 Stefan Monnier * keyboard.h (EVENT_START, EVENT_END, POSN_WINDOW, POSN_POSN) diff --git a/src/coding.c b/src/coding.c index 32da72ab626..f33b5e7c7d5 100644 --- a/src/coding.c +++ b/src/coding.c @@ -6349,7 +6349,12 @@ detect_coding (struct coding_system *coding) coding_systems = AREF (CODING_ID_ATTRS (coding->id), coding_attr_utf_bom); detect_info.found = detect_info.rejected = 0; - coding->head_ascii = 0; + for (src = coding->source; src < src_end; src++) + { + if (*src & 0x80) + break; + } + coding->head_ascii = src - coding->source; if (CONSP (coding_systems) && detect_coding_utf_8 (coding, &detect_info)) { @@ -7487,8 +7492,6 @@ decode_coding_gap (struct coding_system *coding, ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object attrs; - code_conversion_save (0, 0); - coding->src_object = Fcurrent_buffer (); coding->src_chars = chars; coding->src_bytes = bytes; @@ -7502,13 +7505,45 @@ decode_coding_gap (struct coding_system *coding, if (CODING_REQUIRE_DETECTION (coding)) detect_coding (coding); + attrs = CODING_ID_ATTRS (coding->id); +#ifndef CODING_DISABLE_ASCII_OPTIMIZATION + if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)) + && NILP (CODING_ATTR_POST_READ (attrs)) + && NILP (get_translation_table (attrs, 0, NULL))) + { + /* We can skip the conversion if all source bytes are ASCII. */ + if (coding->head_ascii < 0) + { + /* We have not yet counted the number of ASCII bytes at the + head of the source. Do it now. */ + const unsigned char *src, *src_end; + + coding_set_source (coding); + src_end = coding->source + coding->src_bytes; + for (src = coding->source; src < src_end; src++) + { + if (*src & 0x80) + break; + } + coding->head_ascii = src - coding->source; + } + if (coding->src_bytes == coding->head_ascii) + { + /* No need of conversion. Use the data in the gap as is. */ + coding->produced_char = chars; + coding->produced = bytes; + adjust_after_replace (PT, PT_BYTE, Qnil, chars, bytes, 1); + return; + } + } +#endif /* not CODING_DISABLE_ASCII_OPTIMIZATION */ + code_conversion_save (0, 0); coding->mode |= CODING_MODE_LAST_BLOCK; current_buffer->text->inhibit_shrinking = 1; decode_coding (coding); current_buffer->text->inhibit_shrinking = 0; - attrs = CODING_ID_ATTRS (coding->id); if (! NILP (CODING_ATTR_POST_READ (attrs))) { ptrdiff_t prev_Z = Z, prev_Z_BYTE = Z_BYTE; diff --git a/src/insdel.c b/src/insdel.c index fc5a4576dc2..992cebb04b0 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1162,14 +1162,16 @@ insert_from_buffer_1 (struct buffer *buf, /* Record undo information and adjust markers and position keepers for a replacement of a text PREV_TEXT at FROM to a new text of LEN - chars (LEN_BYTE bytes) which resides in the gap just after - GPT_ADDR. + chars (LEN_BYTE bytes). If TEXT_AT_GAP_TAIL is zero, the new text + resides in the gap just after GPT_BYTE. Otherwise, the text + resides at the gap tail; i.e. at (GAP_END_ADDR - LEN_BNYTE). PREV_TEXT nil means the new text was just inserted. */ -static void +void adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, - Lisp_Object prev_text, ptrdiff_t len, ptrdiff_t len_byte) + Lisp_Object prev_text, ptrdiff_t len, ptrdiff_t len_byte, + int text_at_gap_tail) { ptrdiff_t nchars_del = 0, nbytes_del = 0; @@ -1189,8 +1191,11 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, GAP_SIZE -= len_byte; ZV += len; Z+= len; ZV_BYTE += len_byte; Z_BYTE += len_byte; - GPT += len; GPT_BYTE += len_byte; - if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ + if (! text_at_gap_tail) + { + GPT += len; GPT_BYTE += len_byte; + if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ + } if (nchars_del > 0) adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del, @@ -1245,7 +1250,7 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, GPT -= len; GPT_BYTE -= len_byte; ZV -= len; ZV_BYTE -= len_byte; Z -= len; Z_BYTE -= len_byte; - adjust_after_replace (from, from_byte, Qnil, newlen, len_byte); + adjust_after_replace (from, from_byte, Qnil, newlen, len_byte, 0); } /* Replace the text from character positions FROM to TO with NEW, diff --git a/src/lisp.h b/src/lisp.h index e4993866b1f..171292f942e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2900,6 +2900,10 @@ extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); +extern void adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, + Lisp_Object prev_text, + ptrdiff_t len, ptrdiff_t len_byte, + int text_at_gap_tail); extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_markers_for_delete (ptrdiff_t, ptrdiff_t, -- 2.39.2