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.
This commit is contained in:
Tim J. Robbins 2002-09-18 12:17:28 +00:00
parent bddc6280f2
commit 0b7bc80226
2 changed files with 48 additions and 8 deletions

View File

@ -36,8 +36,30 @@ __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;
@ -45,11 +67,9 @@ fgetwc(FILE *fp)
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);
}

View File

@ -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);
}