From aef6a01e62c6a07fc147d9fb374637729c123e76 Mon Sep 17 00:00:00 2001 From: tjr Date: Wed, 18 Sep 2002 12:17:28 +0000 Subject: Optimise the common case where no special encoding is in use (LC_CTYPE is "C" or "POSIX", other European locales). Use __sgetc() and __sputc() where possible to avoid a wasteful lock and unlock for each byte and to avoid function call overhead. --- lib/libc/stdio/fgetwc.c | 28 +++++++++++++++++++++++++--- lib/libc/stdio/fputwc.c | 28 +++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 8 deletions(-) (limited to 'lib/libc') diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c index 9d168cc..90b17ea 100644 --- a/lib/libc/stdio/fgetwc.c +++ b/lib/libc/stdio/fgetwc.c @@ -36,20 +36,40 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" #include "local.h" +static __inline wint_t __fgetwc_nbf(FILE *); + wint_t fgetwc(FILE *fp) { + wint_t wc; + + FLOCKFILE(fp); + ORIENT(fp, 1); + if (MB_CUR_MAX == 1) { + /* + * Assume we're using a single-byte locale. A safer test + * might be to check _CurrentRuneLocale->encoding. + */ + wc = (wint_t)__sgetc(fp); + } else + wc = __fgetwc_nbf(fp); + FUNLOCKFILE(fp); + + return (wc); +} + +static __inline wint_t +__fgetwc_nbf(FILE *fp) +{ char buf[MB_LEN_MAX]; mbstate_t mbs; size_t n, nconv; int c; wchar_t wc; - ORIENTLOCK(fp, 1); - n = 0; while (n < MB_CUR_MAX) { - if ((c = fgetc(fp)) == EOF) { + if ((c = __sgetc(fp)) == EOF) { if (n == 0) return (WEOF); break; @@ -65,8 +85,10 @@ fgetwc(FILE *fp) break; } + FUNLOCKFILE(fp); while (n-- != 0) ungetc((unsigned char)buf[n], fp); + FLOCKFILE(fp); errno = EILSEQ; return (WEOF); } diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c index c12581c..34751dd 100644 --- a/lib/libc/stdio/fputwc.c +++ b/lib/libc/stdio/fputwc.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include +#include #include #include #include @@ -43,15 +44,32 @@ fputwc(wchar_t wc, FILE *fp) mbstate_t mbs; size_t i, len; - ORIENTLOCK(fp, 1); + FLOCKFILE(fp); + ORIENT(fp, 1); - memset(&mbs, 0, sizeof(mbs)); - if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) - return (WEOF); + if (MB_LEN_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) { + /* + * Assume single-byte locale with no special encoding. + * A more careful test would be to check + * _CurrentRuneLocale->encoding. + */ + *buf = (unsigned char)wc; + len = 1; + } else { + memset(&mbs, 0, sizeof(mbs)); + if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) { + FUNLOCKFILE(fp); + return (WEOF); + } + } for (i = 0; i < len; i++) - if (fputc((unsigned char)buf[i], fp) == EOF) + if (__sputc((unsigned char)buf[i], fp) == EOF) { + FUNLOCKFILE(fp); return (WEOF); + } + + FUNLOCKFILE(fp); return ((wint_t)wc); } -- cgit v1.1