diff options
author | tjr <tjr@FreeBSD.org> | 2002-09-18 12:17:28 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2002-09-18 12:17:28 +0000 |
commit | aef6a01e62c6a07fc147d9fb374637729c123e76 (patch) | |
tree | 8c2b286725e30957651db56d4e146c20a54c9a4c /lib/libc/stdio | |
parent | bb655f01d394e53797a84b0158e8017980c464a7 (diff) | |
download | FreeBSD-src-aef6a01e62c6a07fc147d9fb374637729c123e76.zip FreeBSD-src-aef6a01e62c6a07fc147d9fb374637729c123e76.tar.gz |
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.
Diffstat (limited to 'lib/libc/stdio')
-rw-r--r-- | lib/libc/stdio/fgetwc.c | 28 | ||||
-rw-r--r-- | lib/libc/stdio/fputwc.c | 28 |
2 files changed, 48 insertions, 8 deletions
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 <errno.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <wchar.h> @@ -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); } |