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/fgetwc.c | |
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/fgetwc.c')
-rw-r--r-- | lib/libc/stdio/fgetwc.c | 28 |
1 files changed, 25 insertions, 3 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); } |