+ /* Here, the excluded region by shrinking contains only ASCIIs. */
+ from += (from_byte - from_byte_orig);
+ to += (to_byte - to_byte_orig);
+ len = to - from;
+ len_byte = to_byte - from_byte;
+
+ /* For converion, we must put the gap before the text in addition to
+ making the gap larger for efficient decoding. The required gap
+ size starts from 2000 which is the magic number used in make_gap.
+ But, after one batch of conversion, it will be incremented if we
+ find that it is not enough . */
+ require = 2000;
+
+ if (GAP_SIZE < require)
+ make_gap (require - GAP_SIZE);
+ move_gap_both (from, from_byte);
+
+ if (replace)
+ adjust_before_replace (from, from_byte, to, to_byte);
+
+ if (GPT - BEG < beg_unchanged)
+ beg_unchanged = GPT - BEG;
+ if (Z - GPT < end_unchanged)
+ end_unchanged = Z - GPT;
+
+ inserted = inserted_byte = 0;
+ src = GAP_END_ADDR, dst = GPT_ADDR;
+
+ GAP_SIZE += len_byte;
+ ZV -= len;
+ Z -= len;
+ ZV_BYTE -= len_byte;
+ Z_BYTE -= len_byte;
+
+ for (;;)
+ {
+ int result;
+
+ /* The buffer memory is changed from:
+ +--------+converted-text+---------+-------original-text------+---+
+ |<-from->|<--inserted-->|---------|<-----------len---------->|---|
+ |<------------------- GAP_SIZE -------------------->| */
+ if (encodep)
+ result = encode_coding (coding, src, dst, len_byte, 0);
+ else
+ result = decode_coding (coding, src, dst, len_byte, 0);
+ /* to:
+ +--------+-------converted-text--------+--+---original-text--+---+
+ |<-from->|<--inserted-->|<--produced-->|--|<-(len-consumed)->|---|
+ |<------------------- GAP_SIZE -------------------->| */
+ if (coding->fake_multibyte)
+ fake_multibyte = 1;
+
+ if (!encodep && !multibyte)
+ coding->produced_char = coding->produced;
+ inserted += coding->produced_char;
+ inserted_byte += coding->produced;
+ len_byte -= coding->consumed;
+ src += coding->consumed;
+ dst += inserted_byte;
+
+ if (! encodep && result == CODING_FINISH_INCONSISTENT_EOL)
+ {
+ unsigned char *pend = dst, *p = pend - inserted_byte;
+
+ /* Encode LFs back to the original eol format (CR or CRLF). */
+ if (coding->eol_type == CODING_EOL_CR)
+ {
+ while (p < pend) if (*p++ == '\n') p[-1] = '\r';
+ }
+ else
+ {
+ int count = 0;
+
+ while (p < pend) if (*p++ == '\n') count++;
+ if (src - dst < count)
+ {
+ /* We don't have sufficient room for putting LFs
+ back to CRLF. We must record converted and
+ not-yet-converted text back to the buffer
+ content, enlarge the gap, then record them out of
+ the buffer contents again. */
+ int add = len_byte + inserted_byte;
+
+ GAP_SIZE -= add;
+ ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
+ GPT += inserted_byte; GPT_BYTE += inserted_byte;
+ make_gap (count - GAP_SIZE);
+ GAP_SIZE += add;
+ ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
+ GPT -= inserted_byte; GPT_BYTE -= inserted_byte;
+ /* Don't forget to update SRC, DST, and PEND. */
+ src = GAP_END_ADDR - len_byte;
+ dst = GPT_ADDR + inserted_byte;
+ pend = dst;
+ }
+ inserted += count;
+ inserted_byte += count;
+ coding->produced += count;
+ p = dst = pend + count;
+ while (count)
+ {
+ *--p = *--pend;
+ if (*p == '\n') count--, *--p = '\r';
+ }
+ }
+
+ /* Suppress eol-format conversion in the further conversion. */
+ coding->eol_type = CODING_EOL_LF;
+
+ /* Restore the original symbol. */
+ coding->symbol = saved_coding_symbol;
+
+ continue;
+ }
+ if (len_byte <= 0)
+ break;
+ if (result == CODING_FINISH_INSUFFICIENT_SRC)
+ {
+ /* The source text ends in invalid codes. Let's just
+ make them valid buffer contents, and finish conversion. */
+ inserted += len_byte;
+ inserted_byte += len_byte;
+ while (len_byte--)
+ *src++ = *dst++;
+ fake_multibyte = 1;
+ break;
+ }
+ if (first)
+ {
+ /* We have just done the first batch of conversion which was
+ stoped because of insufficient gap. Let's reconsider the
+ required gap size (i.e. SRT - DST) now.
+
+ We have converted ORIG bytes (== coding->consumed) into
+ NEW bytes (coding->produced). To convert the remaining
+ LEN bytes, we may need REQUIRE bytes of gap, where:
+ REQUIRE + LEN_BYTE = LEN_BYTE * (NEW / ORIG)
+ REQUIRE = LEN_BYTE * (NEW - ORIG) / ORIG
+ Here, we are sure that NEW >= ORIG. */
+ float ratio = coding->produced - coding->consumed;
+ ratio /= coding->consumed;
+ require = len_byte * ratio;
+ first = 0;
+ }
+ if ((src - dst) < (require + 2000))
+ {
+ /* See the comment above the previous call of make_gap. */
+ int add = len_byte + inserted_byte;
+
+ GAP_SIZE -= add;
+ ZV += add; Z += add; ZV_BYTE += add; Z_BYTE += add;
+ GPT += inserted_byte; GPT_BYTE += inserted_byte;
+ make_gap (require + 2000);
+ GAP_SIZE += add;
+ ZV -= add; Z -= add; ZV_BYTE -= add; Z_BYTE -= add;
+ GPT -= inserted_byte; GPT_BYTE -= inserted_byte;
+ /* Don't forget to update SRC, DST. */
+ src = GAP_END_ADDR - len_byte;
+ dst = GPT_ADDR + inserted_byte;
+ }
+ }
+ if (src - dst > 0) *dst = 0; /* Put an anchor. */
+
+ if (multibyte
+ && (fake_multibyte || !encodep && (to - from) != (to_byte - from_byte)))
+ inserted = multibyte_chars_in_text (GPT_ADDR, inserted_byte);
+
+ adjust_after_replace (from, from_byte, to, to_byte,
+ inserted, inserted_byte, replace);
+ if (from_byte_orig == from_byte)
+ from_byte_orig = from_byte = PT_BYTE;
+
+ if (! encodep && ! NILP (coding->post_read_conversion))
+ {
+ Lisp_Object val;
+ int orig_inserted = inserted, pos = PT;
+
+ if (from != pos)
+ temp_set_point_both (current_buffer, from, from_byte);
+ val = call1 (coding->post_read_conversion, make_number (inserted));
+ if (! NILP (val))
+ {
+ CHECK_NUMBER (val, 0);
+ inserted = XFASTINT (val);
+ }
+ if (pos >= from + orig_inserted)
+ temp_set_point (current_buffer, pos + (inserted - orig_inserted));
+ }
+
+ signal_after_change (from, to - from, inserted);
+
+ {
+ int skip = (to_byte_orig - to_byte) + (from_byte - from_byte_orig);
+
+ coding->consumed = to_byte_orig - from_byte_orig;
+ coding->consumed_char = skip + (to - from);
+ coding->produced = skip + inserted_byte;
+ coding->produced_char = skip + inserted;
+ }
+
+ return 0;