diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index 1e03860d1b..5f516f700e 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -3312,8 +3312,7 @@ static MZ_INLINE intptr_t get_one_byte(GC_CAN_IGNORE const char *who, return get_one_byte_slow(who, port, buffer, 0, 0); } -int -scheme_getc(Scheme_Object *port) +int scheme_getc(Scheme_Object *port) { char s[MAX_UTF8_CHAR_BYTES]; unsigned int r[1]; @@ -3362,7 +3361,7 @@ scheme_getc(Scheme_Object *port) } int -scheme_get_byte(Scheme_Object *port) +scheme_get_byte(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION { char s[1]; int v; @@ -4194,10 +4193,10 @@ int scheme_close_should_force_port_closed() /****************************** main output writer ******************************/ -intptr_t -scheme_put_byte_string(const char *who, Scheme_Object *port, - const char *str, intptr_t d, intptr_t len, - int rarely_block) +static intptr_t +put_byte_string_slow(const char *who, Scheme_Object *port, + const char *str, intptr_t d, intptr_t len, + int rarely_block) { /* Unlike the main reader, the main writer is simple. It doesn't have to deal with peeks and specials, so it's a thin wrapper on @@ -4262,6 +4261,32 @@ scheme_put_byte_string(const char *who, Scheme_Object *port, return oout; } +intptr_t +scheme_put_byte_string(GC_CAN_IGNORE const char *who, Scheme_Object *port, + GC_CAN_IGNORE const char *str, intptr_t d, intptr_t len, + int rarely_block) +{ + intptr_t out; + + if (SCHEME_OUTPORTP(port) + && !((Scheme_Output_Port *)port)->closed + && (rarely_block != -1) + && (len == 1) + && !((Scheme_Output_Port *)port)->p.count_lines) { + Scheme_Output_Port *op = (Scheme_Output_Port *)port; + Scheme_Write_String_Fun ws; + ws = op->write_string_fun; + out = ws(op, str, d, 1, rarely_block, 0); + if (out) { + op->p.position += out; + return out; + } else if (rarely_block) + return 0; + } + + return put_byte_string_slow(who, port, str, d, len, rarely_block); +} + void scheme_write_byte_string(const char *str, intptr_t len, Scheme_Object *port) { (void)scheme_put_byte_string("write-string", port, str, 0, len, 0); @@ -6923,9 +6948,10 @@ static intptr_t fd_get_string_slow(Scheme_Input_Port *port, } static intptr_t fd_get_string(Scheme_Input_Port *port, - char *buffer, intptr_t offset, intptr_t size, - int nonblock, - Scheme_Object *unless) + char *buffer, intptr_t offset, intptr_t size, + int nonblock, + Scheme_Object *unless) + XFORM_ASSERT_NO_CONVERSION { Scheme_FD *fip; intptr_t bc; @@ -8206,9 +8232,9 @@ static intptr_t flush_fd(Scheme_Output_Port *op, } static intptr_t -fd_write_string(Scheme_Output_Port *port, - const char *str, intptr_t d, intptr_t len, - int rarely_block, int enable_break) +fd_write_string_slow(Scheme_Output_Port *port, + const char *str, intptr_t d, intptr_t len, + int rarely_block, int enable_break) { /* Note: !flush => !rarely_block, !len => flush */ @@ -8280,6 +8306,30 @@ fd_write_string(Scheme_Output_Port *port, return len; } +static intptr_t +fd_write_string(Scheme_Output_Port *port, + const char *str, intptr_t d, intptr_t len, + int rarely_block, int enable_break) + XFORM_ASSERT_NO_CONVERSION +{ + Scheme_FD *fop; + intptr_t l; + int flush = (!len || rarely_block); + + fop = (Scheme_FD *)port->port_data; + + if (!flush && !fop->flushing && (fop->flush != MZ_FLUSH_ALWAYS)) { + l = MZPORT_FD_BUFFSIZE - fop->bufcount; + if (len <= l) { + memcpy(fop->buffer + fop->bufcount, str + d, len); + fop->bufcount += len; + return len; + } + } + + return fd_write_string_slow(port, str, d, len, rarely_block, enable_break); +} + static void fd_close_output(Scheme_Output_Port *port) { diff --git a/racket/src/racket/src/portfun.c b/racket/src/racket/src/portfun.c index 94500aabfa..86d9ef9568 100644 --- a/racket/src/racket/src/portfun.c +++ b/racket/src/racket/src/portfun.c @@ -3112,9 +3112,24 @@ do_read_char(char *name, int argc, Scheme_Object *argv[], int peek, int spec, in return _scheme_make_char(ch); } -static Scheme_Object * -read_char (int argc, Scheme_Object *argv[]) +static Scheme_Object *read_char_fast(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION { + int ch; + + ch = scheme_getc(port); + + if (ch == EOF) + return scheme_eof; + else + return _scheme_make_char(ch); +} + +static Scheme_Object * +read_char (int argc, Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION +{ + if (argc && SCHEME_INPUT_PORTP(argv[0])) + return read_char_fast(argv[0]); + return do_read_char("read-char", argc, argv, 0, 0, 0); } @@ -3136,9 +3151,24 @@ peek_char_spec (int argc, Scheme_Object *argv[]) return do_read_char("peek-char-or-special", argc, argv, 1, 1, 0); } -static Scheme_Object * -read_byte (int argc, Scheme_Object *argv[]) +static Scheme_Object *read_byte_fast(Scheme_Object *port) XFORM_ASSERT_NO_CONVERSION { + int ch; + + ch = scheme_get_byte(port); + + if (ch == EOF) + return scheme_eof; + else + return scheme_make_integer(ch); +} + +static Scheme_Object * +read_byte (int argc, Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION +{ + if (argc && SCHEME_INPUT_PORTP(argv[0])) + return read_byte_fast(argv[0]); + return do_read_char("read-byte", argc, argv, 0, 0, 1); } @@ -4107,13 +4137,13 @@ newline (int argc, Scheme_Object *argv[]) } static Scheme_Object * -write_byte (int argc, Scheme_Object *argv[]) +write_byte_slow (int argc, Scheme_Object *argv[]) { Scheme_Object *port; int v; unsigned char buffer[1]; - if (argc && !SCHEME_INTP(argv[0])) + if (!SCHEME_INTP(argv[0])) scheme_wrong_contract("write-byte", "byte?", 0, argc, argv); v = SCHEME_INT_VAL(argv[0]); if ((v < 0) || (v > 255)) @@ -4136,14 +4166,31 @@ write_byte (int argc, Scheme_Object *argv[]) } static Scheme_Object * -write_char (int argc, Scheme_Object *argv[]) +write_byte (int argc, GC_CAN_IGNORE Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION +{ + if (SCHEME_INTP(argv[0]) + && (SCHEME_INT_VAL(argv[0]) >= 0) + && (SCHEME_INT_VAL(argv[0]) <= 255) + && SCHEME_OUTPUT_PORTP(argv[1])) { + char buffer[1]; + buffer[0] = SCHEME_INT_VAL(argv[0]); + scheme_put_byte_string("write-byte", argv[1], + buffer, 0, 1, + 0); + return scheme_void; + } else + return write_byte_slow(argc, argv); +} + +static Scheme_Object * +write_char_slow (int argc, Scheme_Object *argv[]) { Scheme_Object *port; unsigned char buffer[MAX_UTF8_CHAR_BYTES]; unsigned int ubuffer[1]; int len; - if (argc && !SCHEME_CHARP(argv[0])) + if (!SCHEME_CHARP(argv[0])) scheme_wrong_contract("write-char", "char?", 0, argc, argv); if (argc > 1) { if (!SCHEME_OUTPUT_PORTP(argv[1])) @@ -4162,6 +4209,23 @@ write_char (int argc, Scheme_Object *argv[]) return scheme_void; } +static Scheme_Object * +write_char (int argc, GC_CAN_IGNORE Scheme_Object *argv[]) XFORM_ASSERT_NO_CONVERSION +{ + if (argc + && SCHEME_CHARP(argv[0]) + && (SCHEME_CHAR_VAL(argv[0]) < 128) + && SCHEME_OUTPUT_PORTP(argv[1])) { + char buffer[1]; + buffer[0] = SCHEME_CHAR_VAL(argv[0]); + scheme_put_byte_string("write-char", argv[1], + buffer, 0, 1, + 0); + return scheme_void; + } else + return write_char_slow(argc, argv); +} + static Scheme_Object *port_read_handler(int argc, Scheme_Object *argv[]) { Scheme_Input_Port *ip;