mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-05 11:21:04 -08:00
(MINIMUM_CONVERSION_BUFFER_SIZE): Macro deleted.
(conversion_buffer, conversion_buffer_size): Variables deleted. (get_conversion_buffer): Function deleted. (struct conversion_buffer): New structure. (MAX_ALLOCA): New macro. (allocate_conversion_buffer): New macro. (extend_conversion_buffer, free_conversion_buffer): New functions. (ccl_coding_driver): Set coding->result. (decode_coding): Set coding->result to CODING_FINISH_NORMAL if this is the last block of source. (encode_coding): Likewise. Handle the source block as the last one only when the whole source text is consumed. (decode_coding_string): Handle the case that the output buffer is too small to decode the whole source text. Use allocate_conversion_buffer, extend_conversion_buffer and free_conversion_buffer, not get_conversion_buffer. (encode_coding_string): Likewise. (init_coding): Function deleted. (init_coding_once): Delete code to initialize conversion_buffer_size.
This commit is contained in:
parent
0749a60833
commit
73be902c32
1 changed files with 152 additions and 82 deletions
234
src/coding.c
234
src/coding.c
|
|
@ -3870,33 +3870,60 @@ encoding_buffer_size (coding, src_bytes)
|
||||||
return (src_bytes * magnification + CONVERSION_BUFFER_EXTRA_ROOM);
|
return (src_bytes * magnification + CONVERSION_BUFFER_EXTRA_ROOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MINIMUM_CONVERSION_BUFFER_SIZE
|
/* Working buffer for code conversion. */
|
||||||
#define MINIMUM_CONVERSION_BUFFER_SIZE 1024
|
struct conversion_buffer
|
||||||
#endif
|
|
||||||
|
|
||||||
char *conversion_buffer;
|
|
||||||
int conversion_buffer_size;
|
|
||||||
|
|
||||||
/* Return a pointer to a SIZE bytes of buffer to be used for encoding
|
|
||||||
or decoding. Sufficient memory is allocated automatically. If we
|
|
||||||
run out of memory, return NULL. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
get_conversion_buffer (size)
|
|
||||||
int size;
|
|
||||||
{
|
{
|
||||||
if (size > conversion_buffer_size)
|
int size; /* size of data. */
|
||||||
{
|
int on_stack; /* 1 if allocated by alloca. */
|
||||||
char *buf;
|
unsigned char *data;
|
||||||
int real_size = conversion_buffer_size * 2;
|
};
|
||||||
|
|
||||||
while (real_size < size) real_size *= 2;
|
/* Don't use alloca for allocating memory space larger than this, lest
|
||||||
buf = (char *) xmalloc (real_size);
|
we overflow their stack. */
|
||||||
xfree (conversion_buffer);
|
#define MAX_ALLOCA 16*1024
|
||||||
conversion_buffer = buf;
|
|
||||||
conversion_buffer_size = real_size;
|
/* Allocate LEN bytes of memory for BUF (struct conversion_buffer). */
|
||||||
|
#define allocate_conversion_buffer(buf, len) \
|
||||||
|
do { \
|
||||||
|
if (len < MAX_ALLOCA) \
|
||||||
|
{ \
|
||||||
|
buf.data = (unsigned char *) alloca (len); \
|
||||||
|
buf.on_stack = 1; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
buf.data = (unsigned char *) xmalloc (len); \
|
||||||
|
buf.on_stack = 0; \
|
||||||
|
} \
|
||||||
|
buf.size = len; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Double the allocated memory for *BUF. */
|
||||||
|
static void
|
||||||
|
extend_conversion_buffer (buf)
|
||||||
|
struct conversion_buffer *buf;
|
||||||
|
{
|
||||||
|
if (buf->on_stack)
|
||||||
|
{
|
||||||
|
unsigned char *save = buf->data;
|
||||||
|
buf->data = (unsigned char *) xmalloc (buf->size * 2);
|
||||||
|
bcopy (save, buf->data, buf->size);
|
||||||
|
buf->on_stack = 0;
|
||||||
}
|
}
|
||||||
return conversion_buffer;
|
else
|
||||||
|
{
|
||||||
|
buf->data = (unsigned char *) xrealloc (buf->data, buf->size * 2);
|
||||||
|
}
|
||||||
|
buf->size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the allocated memory for BUF if it is not on stack. */
|
||||||
|
static void
|
||||||
|
free_conversion_buffer (buf)
|
||||||
|
struct conversion_buffer *buf;
|
||||||
|
{
|
||||||
|
if (!buf->on_stack)
|
||||||
|
xfree (buf->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -3929,20 +3956,20 @@ ccl_coding_driver (coding, source, destination, src_bytes, dst_bytes, encodep)
|
||||||
switch (ccl->status)
|
switch (ccl->status)
|
||||||
{
|
{
|
||||||
case CCL_STAT_SUSPEND_BY_SRC:
|
case CCL_STAT_SUSPEND_BY_SRC:
|
||||||
result = CODING_FINISH_INSUFFICIENT_SRC;
|
coding->result = CODING_FINISH_INSUFFICIENT_SRC;
|
||||||
break;
|
break;
|
||||||
case CCL_STAT_SUSPEND_BY_DST:
|
case CCL_STAT_SUSPEND_BY_DST:
|
||||||
result = CODING_FINISH_INSUFFICIENT_DST;
|
coding->result = CODING_FINISH_INSUFFICIENT_DST;
|
||||||
break;
|
break;
|
||||||
case CCL_STAT_QUIT:
|
case CCL_STAT_QUIT:
|
||||||
case CCL_STAT_INVALID_CMD:
|
case CCL_STAT_INVALID_CMD:
|
||||||
result = CODING_FINISH_INTERRUPT;
|
coding->result = CODING_FINISH_INTERRUPT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = CODING_FINISH_NORMAL;
|
coding->result = CODING_FINISH_NORMAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return coding->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decode EOL format of the text at PTR of BYTES length destructively
|
/* Decode EOL format of the text at PTR of BYTES length destructively
|
||||||
|
|
@ -4170,6 +4197,7 @@ decode_coding (coding, source, destination, src_bytes, dst_bytes)
|
||||||
}
|
}
|
||||||
coding->consumed = coding->consumed_char = src - source;
|
coding->consumed = coding->consumed_char = src - source;
|
||||||
coding->produced = dst - destination;
|
coding->produced = dst - destination;
|
||||||
|
coding->result = CODING_FINISH_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!coding->dst_multibyte)
|
if (!coding->dst_multibyte)
|
||||||
|
|
@ -4231,7 +4259,8 @@ encode_coding (coding, source, destination, src_bytes, dst_bytes)
|
||||||
&& coding->consumed == src_bytes)
|
&& coding->consumed == src_bytes)
|
||||||
coding->result = CODING_FINISH_NORMAL;
|
coding->result = CODING_FINISH_NORMAL;
|
||||||
|
|
||||||
if (coding->mode & CODING_MODE_LAST_BLOCK)
|
if (coding->mode & CODING_MODE_LAST_BLOCK
|
||||||
|
&& coding->result == CODING_FINISH_INSUFFICIENT_SRC)
|
||||||
{
|
{
|
||||||
unsigned char *src = source + coding->consumed;
|
unsigned char *src = source + coding->consumed;
|
||||||
unsigned char *src_end = src + src_bytes;
|
unsigned char *src_end = src + src_bytes;
|
||||||
|
|
@ -4252,6 +4281,7 @@ encode_coding (coding, source, destination, src_bytes, dst_bytes)
|
||||||
coding->consumed = src_bytes;
|
coding->consumed = src_bytes;
|
||||||
}
|
}
|
||||||
coding->produced = coding->produced_char = dst - destination;
|
coding->produced = coding->produced_char = dst - destination;
|
||||||
|
coding->result = CODING_FINISH_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return coding->result;
|
return coding->result;
|
||||||
|
|
@ -5197,12 +5227,15 @@ decode_coding_string (str, coding, nocopy)
|
||||||
int nocopy;
|
int nocopy;
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *buf;
|
struct conversion_buffer buf;
|
||||||
int from, to, to_byte;
|
int from, to, to_byte;
|
||||||
struct gcpro gcpro1;
|
struct gcpro gcpro1;
|
||||||
Lisp_Object saved_coding_symbol;
|
Lisp_Object saved_coding_symbol;
|
||||||
int result;
|
int result;
|
||||||
int require_decoding;
|
int require_decoding;
|
||||||
|
int shrinked_bytes = 0;
|
||||||
|
Lisp_Object newstr;
|
||||||
|
int consumed, produced, produced_char;
|
||||||
|
|
||||||
from = 0;
|
from = 0;
|
||||||
to = XSTRING (str)->size;
|
to = XSTRING (str)->size;
|
||||||
|
|
@ -5247,12 +5280,11 @@ decode_coding_string (str, coding, nocopy)
|
||||||
/* Try to skip the heading and tailing ASCIIs. */
|
/* Try to skip the heading and tailing ASCIIs. */
|
||||||
if (require_decoding && coding->type != coding_type_ccl)
|
if (require_decoding && coding->type != coding_type_ccl)
|
||||||
{
|
{
|
||||||
int from_orig = from;
|
|
||||||
|
|
||||||
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data,
|
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data,
|
||||||
0);
|
0);
|
||||||
if (from == to_byte)
|
if (from == to_byte)
|
||||||
require_decoding = 0;
|
require_decoding = 0;
|
||||||
|
shrinked_bytes = from + (STRING_BYTES (XSTRING (str)) - to_byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!require_decoding)
|
if (!require_decoding)
|
||||||
|
|
@ -5271,46 +5303,77 @@ decode_coding_string (str, coding, nocopy)
|
||||||
|
|
||||||
if (coding->composing != COMPOSITION_DISABLED)
|
if (coding->composing != COMPOSITION_DISABLED)
|
||||||
coding_allocate_composition_data (coding, from);
|
coding_allocate_composition_data (coding, from);
|
||||||
|
|
||||||
len = decoding_buffer_size (coding, to_byte - from);
|
len = decoding_buffer_size (coding, to_byte - from);
|
||||||
len += from + STRING_BYTES (XSTRING (str)) - to_byte;
|
allocate_conversion_buffer (buf, len);
|
||||||
GCPRO1 (str);
|
|
||||||
buf = get_conversion_buffer (len);
|
|
||||||
UNGCPRO;
|
|
||||||
|
|
||||||
if (from > 0)
|
consumed = produced = produced_char = 0;
|
||||||
bcopy (XSTRING (str)->data, buf, from);
|
while (1)
|
||||||
result = decode_coding (coding, XSTRING (str)->data + from,
|
|
||||||
buf + from, to_byte - from, len);
|
|
||||||
if (result == CODING_FINISH_INCONSISTENT_EOL)
|
|
||||||
{
|
{
|
||||||
/* We simply try to decode the whole string again but without
|
result = decode_coding (coding, XSTRING (str)->data + from + consumed,
|
||||||
eol-conversion this time. */
|
buf.data + produced, to_byte - from - consumed,
|
||||||
coding->eol_type = CODING_EOL_LF;
|
buf.size - produced);
|
||||||
coding->symbol = saved_coding_symbol;
|
consumed += coding->consumed;
|
||||||
coding_free_composition_data (coding);
|
produced += coding->produced;
|
||||||
return decode_coding_string (str, coding, nocopy);
|
produced_char += coding->produced_char;
|
||||||
|
if (result == CODING_FINISH_NORMAL)
|
||||||
|
break;
|
||||||
|
if (result == CODING_FINISH_INSUFFICIENT_CMP)
|
||||||
|
coding_allocate_composition_data (coding, from + produced_char);
|
||||||
|
else if (result == CODING_FINISH_INSUFFICIENT_DST)
|
||||||
|
extend_conversion_buffer (&buf);
|
||||||
|
else if (result == CODING_FINISH_INCONSISTENT_EOL)
|
||||||
|
{
|
||||||
|
/* Recover the original EOL format. */
|
||||||
|
if (coding->eol_type == CODING_EOL_CR)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
for (p = buf.data; p < buf.data + produced; p++)
|
||||||
|
if (*p == '\n') *p = '\r';
|
||||||
|
}
|
||||||
|
else if (coding->eol_type == CODING_EOL_CRLF)
|
||||||
|
{
|
||||||
|
int num_eol = 0;
|
||||||
|
unsigned char *p0, *p1;
|
||||||
|
for (p0 = buf.data, p1 = p0 + produced; p0 < p1; p0++)
|
||||||
|
if (*p0 == '\n') num_eol++;
|
||||||
|
if (produced + num_eol >= buf.size)
|
||||||
|
extend_conversion_buffer (&buf);
|
||||||
|
for (p0 = buf.data + produced, p1 = p0 + num_eol; p0 > buf.data;)
|
||||||
|
{
|
||||||
|
*--p1 = *--p0;
|
||||||
|
if (*p0 == '\n') *--p1 = '\r';
|
||||||
|
}
|
||||||
|
produced += num_eol;
|
||||||
|
produced_char += num_eol;
|
||||||
|
}
|
||||||
|
coding->eol_type = CODING_EOL_LF;
|
||||||
|
coding->symbol = saved_coding_symbol;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bcopy (XSTRING (str)->data + to_byte, buf + from + coding->produced,
|
|
||||||
STRING_BYTES (XSTRING (str)) - to_byte);
|
|
||||||
|
|
||||||
len = from + STRING_BYTES (XSTRING (str)) - to_byte;
|
|
||||||
if (coding->dst_multibyte)
|
if (coding->dst_multibyte)
|
||||||
str = make_multibyte_string (buf, len + coding->produced_char,
|
newstr = make_uninit_multibyte_string (produced_char + shrinked_bytes,
|
||||||
len + coding->produced);
|
produced + shrinked_bytes);
|
||||||
else
|
else
|
||||||
str = make_unibyte_string (buf, len + coding->produced);
|
newstr = make_uninit_string (produced + shrinked_bytes);
|
||||||
|
if (from > 0)
|
||||||
|
bcopy (XSTRING (str)->data, XSTRING (newstr)->data, from);
|
||||||
|
bcopy (buf.data, XSTRING (newstr)->data + from, produced);
|
||||||
|
if (shrinked_bytes > from)
|
||||||
|
bcopy (XSTRING (str)->data + to_byte,
|
||||||
|
XSTRING (newstr)->data + from + produced,
|
||||||
|
shrinked_bytes - from);
|
||||||
|
free_conversion_buffer (&buf);
|
||||||
|
|
||||||
if (coding->cmp_data && coding->cmp_data->used)
|
if (coding->cmp_data && coding->cmp_data->used)
|
||||||
coding_restore_composition (coding, str);
|
coding_restore_composition (coding, newstr);
|
||||||
coding_free_composition_data (coding);
|
coding_free_composition_data (coding);
|
||||||
|
|
||||||
if (SYMBOLP (coding->post_read_conversion)
|
if (SYMBOLP (coding->post_read_conversion)
|
||||||
&& !NILP (Ffboundp (coding->post_read_conversion)))
|
&& !NILP (Ffboundp (coding->post_read_conversion)))
|
||||||
str = run_pre_post_conversion_on_str (str, coding, 0);
|
newstr = run_pre_post_conversion_on_str (newstr, coding, 0);
|
||||||
|
|
||||||
return str;
|
return newstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object
|
Lisp_Object
|
||||||
|
|
@ -5320,11 +5383,14 @@ encode_coding_string (str, coding, nocopy)
|
||||||
int nocopy;
|
int nocopy;
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *buf;
|
struct conversion_buffer buf;
|
||||||
int from, to, to_byte;
|
int from, to, to_byte;
|
||||||
struct gcpro gcpro1;
|
struct gcpro gcpro1;
|
||||||
Lisp_Object saved_coding_symbol;
|
Lisp_Object saved_coding_symbol;
|
||||||
int result;
|
int result;
|
||||||
|
int shrinked_bytes = 0;
|
||||||
|
Lisp_Object newstr;
|
||||||
|
int consumed, consumed_char, produced;
|
||||||
|
|
||||||
if (SYMBOLP (coding->pre_write_conversion)
|
if (SYMBOLP (coding->pre_write_conversion)
|
||||||
&& !NILP (Ffboundp (coding->pre_write_conversion)))
|
&& !NILP (Ffboundp (coding->pre_write_conversion)))
|
||||||
|
|
@ -5356,32 +5422,44 @@ encode_coding_string (str, coding, nocopy)
|
||||||
/* Try to skip the heading and tailing ASCIIs. */
|
/* Try to skip the heading and tailing ASCIIs. */
|
||||||
if (coding->type != coding_type_ccl)
|
if (coding->type != coding_type_ccl)
|
||||||
{
|
{
|
||||||
int from_orig = from;
|
|
||||||
|
|
||||||
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data,
|
SHRINK_CONVERSION_REGION (&from, &to_byte, coding, XSTRING (str)->data,
|
||||||
1);
|
1);
|
||||||
if (from == to_byte)
|
if (from == to_byte)
|
||||||
return (nocopy ? str : Fcopy_sequence (str));
|
return (nocopy ? str : Fcopy_sequence (str));
|
||||||
|
shrinked_bytes = from + (STRING_BYTES (XSTRING (str)) - to_byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = encoding_buffer_size (coding, to_byte - from);
|
len = encoding_buffer_size (coding, to_byte - from);
|
||||||
len += from + STRING_BYTES (XSTRING (str)) - to_byte;
|
allocate_conversion_buffer (buf, len);
|
||||||
GCPRO1 (str);
|
|
||||||
buf = get_conversion_buffer (len);
|
|
||||||
UNGCPRO;
|
|
||||||
|
|
||||||
|
consumed = consumed_char = produced = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
result = encode_coding (coding, XSTRING (str)->data + from + consumed,
|
||||||
|
buf.data + produced, to_byte - from - consumed,
|
||||||
|
buf.size - produced);
|
||||||
|
consumed += coding->consumed;
|
||||||
|
produced += coding->produced;
|
||||||
|
if (result == CODING_FINISH_NORMAL)
|
||||||
|
break;
|
||||||
|
/* Now result should be CODING_FINISH_INSUFFICIENT_DST. */
|
||||||
|
extend_conversion_buffer (&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
newstr = make_uninit_string (produced + shrinked_bytes);
|
||||||
if (from > 0)
|
if (from > 0)
|
||||||
bcopy (XSTRING (str)->data, buf, from);
|
bcopy (XSTRING (str)->data, XSTRING (newstr)->data, from);
|
||||||
result = encode_coding (coding, XSTRING (str)->data + from,
|
bcopy (buf.data, XSTRING (newstr)->data + from, produced);
|
||||||
buf + from, to_byte - from, len);
|
if (shrinked_bytes > from)
|
||||||
bcopy (XSTRING (str)->data + to_byte, buf + from + coding->produced,
|
bcopy (XSTRING (str)->data + to_byte,
|
||||||
STRING_BYTES (XSTRING (str)) - to_byte);
|
XSTRING (newstr)->data + from + produced,
|
||||||
|
shrinked_bytes - from);
|
||||||
|
|
||||||
len = from + STRING_BYTES (XSTRING (str)) - to_byte;
|
free_conversion_buffer (&buf);
|
||||||
str = make_unibyte_string (buf, len + coding->produced);
|
|
||||||
coding_free_composition_data (coding);
|
coding_free_composition_data (coding);
|
||||||
|
|
||||||
return str;
|
return newstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6207,12 +6285,6 @@ This function is internal use only.")
|
||||||
|
|
||||||
/*** 9. Post-amble ***/
|
/*** 9. Post-amble ***/
|
||||||
|
|
||||||
void
|
|
||||||
init_coding ()
|
|
||||||
{
|
|
||||||
conversion_buffer = (char *) xmalloc (MINIMUM_CONVERSION_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_coding_once ()
|
init_coding_once ()
|
||||||
{
|
{
|
||||||
|
|
@ -6253,8 +6325,6 @@ init_coding_once ()
|
||||||
iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;
|
iso_code_class[ISO_CODE_SS3] = ISO_single_shift_3;
|
||||||
iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;
|
iso_code_class[ISO_CODE_CSI] = ISO_control_sequence_introducer;
|
||||||
|
|
||||||
conversion_buffer_size = MINIMUM_CONVERSION_BUFFER_SIZE;
|
|
||||||
|
|
||||||
setup_coding_system (Qnil, &keyboard_coding);
|
setup_coding_system (Qnil, &keyboard_coding);
|
||||||
setup_coding_system (Qnil, &terminal_coding);
|
setup_coding_system (Qnil, &terminal_coding);
|
||||||
setup_coding_system (Qnil, &safe_terminal_coding);
|
setup_coding_system (Qnil, &safe_terminal_coding);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue