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:
parent
bddc6280f2
commit
0b7bc80226
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user