Commit 5947970f authored by Marius Gerbershagen's avatar Marius Gerbershagen

printer: optimize printing of strings. Fixes #403

parent f104b1f4
......@@ -487,8 +487,10 @@ cl_char_name(cl_object c)
cl_object output;
if (code <= 127) {
output = ecl_gethash_safe(ecl_make_fixnum(code), cl_core.char_names, ECL_NIL);
#ifdef ECL_UNICODE
} else if (!Null(output = _ecl_ucd_code_to_name(code))) {
(void)0;
#endif
} else {
ecl_base_char name[8];
ecl_base_char *start;
......@@ -521,10 +523,12 @@ cl_name_char(cl_object name)
if (c != ECL_NIL) {
ecl_return1(the_env, ECL_CODE_CHAR(ecl_fixnum(c)));
}
#ifdef ECL_UNICODE
c = _ecl_ucd_name_to_code(name);
if (c != ECL_NIL) {
ecl_return1(the_env, cl_code_char(c));
}
#endif
if (ecl_stringp(name) && (l = ecl_length(name))) {
c = cl_char(name, ecl_make_fixnum(0));
if (l == 1) {
......
......@@ -60,6 +60,8 @@
* with 4 being the charset prefix, 2 for the character.
*/
#define ENCODING_BUFFER_MAX_SIZE 6
/* Size of the encoding buffer for vectors */
#define VECTOR_ENCODING_BUFFER_SIZE 2048
static cl_index ecl_read_byte8(cl_object stream, unsigned char *c, cl_index n);
static cl_index ecl_write_byte8(cl_object stream, unsigned char *c, cl_index n);
......@@ -583,20 +585,25 @@ eformat_read_char(cl_object strm)
return c;
}
static ecl_character
eformat_write_char(cl_object strm, ecl_character c)
static inline void
write_char_increment_column(cl_object strm, ecl_character c)
{
unsigned char buffer[ENCODING_BUFFER_MAX_SIZE];
ecl_character nbytes;
nbytes = strm->stream.encoder(strm, buffer, c);
strm->stream.ops->write_byte8(strm, buffer, nbytes);
if (c == '\n')
strm->stream.column = 0;
else if (c == '\t')
strm->stream.column = (strm->stream.column & ~((cl_index)07)) + 8;
else
strm->stream.column++;
fflush(stdout);
}
static ecl_character
eformat_write_char(cl_object strm, ecl_character c)
{
unsigned char buffer[ENCODING_BUFFER_MAX_SIZE];
ecl_character nbytes;
nbytes = strm->stream.encoder(strm, buffer, c);
strm->stream.ops->write_byte8(strm, buffer, nbytes);
write_char_increment_column(strm, c);
return c;
}
......@@ -1335,13 +1342,7 @@ const struct ecl_file_ops clos_stream_ops = {
static ecl_character
str_out_write_char(cl_object strm, ecl_character c)
{
int column = strm->stream.column;
if (c == '\n')
strm->stream.column = 0;
else if (c == '\t')
strm->stream.column = (column&~(cl_index)7) + 8;
else
strm->stream.column++;
write_char_increment_column(strm, c);
ecl_string_push_extend(STRING_OUTPUT_STRING(strm), c);
return c;
}
......@@ -2892,7 +2893,40 @@ io_file_write_vector(cl_object strm, cl_object data, cl_index start, cl_index en
bytes = strm->stream.ops->write_byte8(strm, aux, bytes);
return start + bytes / sizeof(cl_fixnum);
}
} else if (t == ecl_aet_bc) {
unsigned char buffer[VECTOR_ENCODING_BUFFER_SIZE + ENCODING_BUFFER_MAX_SIZE];
cl_index nbytes = 0;
cl_index i;
for (i = start; i < end; i++) {
ecl_character c = *(data->vector.self.bc + i);
nbytes += strm->stream.encoder(strm, buffer + nbytes, c);
write_char_increment_column(strm, c);
if (nbytes >= VECTOR_ENCODING_BUFFER_SIZE) {
strm->stream.ops->write_byte8(strm, buffer, nbytes);
nbytes = 0;
}
}
strm->stream.ops->write_byte8(strm, buffer, nbytes);
return end;
}
#ifdef ECL_UNICODE
else if (t == ecl_aet_ch) {
unsigned char buffer[VECTOR_ENCODING_BUFFER_SIZE + ENCODING_BUFFER_MAX_SIZE];
cl_index nbytes = 0;
cl_index i;
for (i = start; i < end; i++) {
ecl_character c = *(data->vector.self.c + i);
nbytes += strm->stream.encoder(strm, buffer + nbytes, c);
write_char_increment_column(strm, c);
if (nbytes >= VECTOR_ENCODING_BUFFER_SIZE) {
strm->stream.ops->write_byte8(strm, buffer, nbytes);
nbytes = 0;
}
}
strm->stream.ops->write_byte8(strm, buffer, nbytes);
return end;
}
#endif
return generic_write_vector(strm, data, start, end);
}
......@@ -4696,6 +4730,7 @@ ecl_peek_char(cl_object strm)
* SEQUENCES I/O
*/
/* FIXME: We can optimize this to write the whole string at once */
void
writestr_stream(const char *s, cl_object strm)
{
......
......@@ -220,7 +220,7 @@ ecl_print_circle(void)
@(defun write-string (strng &o strm &k (start ecl_make_fixnum(0)) end)
@
unlikely_if (!ECL_STRINGP(strng))
FEwrong_type_nth_arg(@[write-string], 1, strng, @[string]);
FEwrong_type_nth_arg(@[write-string], 1, strng, @[string]);
strm = _ecl_stream_or_default_output(strm);
#ifdef ECL_CLOS_STREAMS
if (!ECL_ANSI_STREAM_P(strm))
......@@ -234,7 +234,7 @@ ecl_print_circle(void)
@(defun write-line (strng &o strm &k (start ecl_make_fixnum(0)) end)
@
unlikely_if (!ECL_STRINGP(strng))
FEwrong_type_nth_arg(@[write-line], 1, strng, @[string]);
FEwrong_type_nth_arg(@[write-line], 1, strng, @[string]);
strm = _ecl_stream_or_default_output(strm);
#ifdef ECL_CLOS_STREAMS
if (!ECL_ANSI_STREAM_P(strm))
......@@ -364,24 +364,7 @@ ecl_terpri(cl_object strm)
void
ecl_write_string(cl_object strng, cl_object strm)
{
cl_index i;
strm = _ecl_stream_or_default_output(strm);
switch(ecl_t_of(strng)) {
#ifdef ECL_UNICODE
case t_string:
for (i = 0; i < strng->string.fillp; i++)
ecl_write_char(strng->string.self[i], strm);
break;
#endif
case t_base_string:
for (i = 0; i < strng->base_string.fillp; i++)
ecl_write_char(strng->base_string.self[i], strm);
break;
default:
FEwrong_type_nth_arg(@[write-string], 1, strng, @[string]);
}
cl_write_string(2, strng, strm);
ecl_force_output(strm);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment