diff options
author | Andy Wingo <wingo@pobox.com> | 2013-08-31 10:44:07 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2013-08-31 10:44:07 +0200 |
commit | be7ecef05c1eea66f30360f658c610710c5cb22e (patch) | |
tree | e014d8314071a644bd1dcef5fc9116b38376d41b /libguile | |
parent | 8ac8e2dfeb88172deab6fe453d7a2f0ad03729d6 (diff) | |
download | guile-be7ecef05c1eea66f30360f658c610710c5cb22e.tar.gz |
unread-char: inline conversion from codepoint to bytes
* libguile/ports.c (scm_ungetc_unlocked): Inline the conversion from
codepoint to bytes for UTF-8 and latin-1 ports. Speeds up a
numbers-reading test case by 100% (!).
Diffstat (limited to 'libguile')
-rw-r--r-- | libguile/ports.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/libguile/ports.c b/libguile/ports.c index 7934379d0..44416cb6c 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -2105,15 +2105,36 @@ scm_ungetc_unlocked (scm_t_wchar c, SCM port) #define FUNC_NAME "scm_ungetc" { scm_t_port *pt = SCM_PTAB_ENTRY (port); + scm_t_port_internal *pti = SCM_PORT_GET_INTERNAL (port); char *result; char result_buf[10]; size_t len; len = sizeof (result_buf); - result = u32_conv_to_encoding (pt->encoding, - (enum iconv_ilseq_handler) pt->ilseq_handler, - (uint32_t *) &c, 1, NULL, - result_buf, &len); + + if (pti->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8) + { + if (c < 0xf0) + { + result_buf[0] = (char) c; + result = result_buf; + len = 1; + } + else + result = + (char *) u32_to_u8 ((uint32_t *) &c, 1, (uint8_t *) result_buf, &len); + } + else if (pti->encoding_mode == SCM_PORT_ENCODING_MODE_LATIN1 && c <= 0xff) + { + result_buf[0] = (char) c; + result = result_buf; + len = 1; + } + else + result = u32_conv_to_encoding (pt->encoding, + (enum iconv_ilseq_handler) pt->ilseq_handler, + (uint32_t *) &c, 1, NULL, + result_buf, &len); if (SCM_UNLIKELY (result == NULL || len == 0)) scm_encoding_error (FUNC_NAME, errno, |