Associate a multibyte conversion state object with each stream. Reset it

to the initial state when a stream is opened or seeked upon. Use the
stream's conversion state object instead of a freshly-zeroed one in
fgetwc(), fputwc() and ungetwc().

This is only a performance improvement for now, but it would also be
required in order to support state-dependent encodings.
This commit is contained in:
Tim J. Robbins 2004-05-22 15:19:41 +00:00
parent d0834d4dc8
commit 87275e436a
7 changed files with 24 additions and 42 deletions

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2002 Tim J. Robbins.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -77,34 +77,31 @@ fgetwc(FILE *fp)
static __inline wint_t
__fgetwc_nbf(FILE *fp)
{
static const mbstate_t initial;
mbstate_t mbs;
char buf[MB_LEN_MAX];
size_t n, nconv;
int c;
char cc;
wchar_t wc;
n = 0;
while (n < MB_CUR_MAX) {
for (;;) {
if ((c = __sgetc(fp)) == EOF) {
if (n == 0)
return (WEOF);
break;
}
buf[n++] = (char)c;
mbs = initial;
nconv = mbrtowc(&wc, buf, n, &mbs);
if (nconv == n)
return (wc);
else if (nconv == 0)
return (L'\0');
n++;
cc = (char)c;
nconv = mbrtowc(&wc, &cc, 1, &fp->_extra->mbstate);
if (nconv == (size_t)-2)
continue;
else if (nconv == (size_t)-1)
break;
else if (nconv == 0)
return (L'\0');
else
return (wc);
}
while (n-- != 0)
__ungetc((unsigned char)buf[n], fp);
errno = EILSEQ;
fp->_flags |= __SERR;
errno = EILSEQ;
return (WEOF);
}

View File

@ -180,11 +180,7 @@ found:
fp->_lb._size = 0;
/* fp->_lock = NULL; */ /* once set always set (reused) */
fp->_extra->orientation = 0;
#ifdef notdef
/* Stateful encoding/decoding is not yet supported. */
memset(&fp->_extra->wstate, 0, sizeof(mbstate_t));
memset(&fp->_extra->rstate, 0, sizeof(mbstate_t));
#endif
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
return (fp);
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2002 Tim J. Robbins.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -43,8 +43,6 @@ __FBSDID("$FreeBSD$");
wint_t
__fputwc(wchar_t wc, FILE *fp)
{
static const mbstate_t initial;
mbstate_t mbs;
char buf[MB_LEN_MAX];
size_t i, len;
@ -57,8 +55,8 @@ __fputwc(wchar_t wc, FILE *fp)
*buf = (unsigned char)wc;
len = 1;
} else {
mbs = initial;
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
if ((len = wcrtomb(buf, wc, &fp->_extra->mbstate)) ==
(size_t)-1) {
fp->_flags |= __SERR;
return (WEOF);
}

View File

@ -188,6 +188,7 @@ finish:
FREELB(fp);
fp->_lb._size = 0;
fp->_extra->orientation = 0;
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
if (f < 0) { /* did not get it after all */
fp->_flags = 0; /* set it free */

View File

@ -259,6 +259,7 @@ _fseeko(fp, offset, whence, ltest)
if (HASUB(fp))
FREEUB(fp);
fp->_flags &= ~__SEOF;
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
return (0);
}
@ -303,6 +304,7 @@ dumb:
fp->_r = 0;
/* fp->_w = 0; */ /* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
if (ltest && ret > LONG_MAX) {
fp->_flags |= __SERR;
errno = EOVERFLOW;

View File

@ -89,15 +89,7 @@ struct __sFILEX {
pthread_t fl_owner; /* current owner */
int fl_count; /* recursive lock count */
int orientation; /* orientation for fwide() */
#ifdef notdef
/*
* XXX These are not used yet -- they will be used to store the
* multibyte conversion state for writing and reading when
* stateful encodings are supported by the locale framework.
*/
mbstate_t wstate; /* write conversion state */
mbstate_t rstate; /* read conversion state */
#endif
mbstate_t mbstate; /* multibyte conversion state */
};
/*
@ -134,8 +126,7 @@ struct __sFILEX {
(fp)->_extra->fl_owner = NULL; \
(fp)->_extra->fl_count = 0; \
(fp)->_extra->orientation = 0; \
/* memset(&(fp)->_extra->wstate, 0, sizeof(mbstate_t)); */ \
/* memset(&(fp)->_extra->rstate, 0, sizeof(mbstate_t)); */ \
memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \
}
/*

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2002 Tim J. Robbins.
* Copyright (c) 2002-2004 Tim J. Robbins.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -42,15 +42,12 @@ __FBSDID("$FreeBSD$");
wint_t
__ungetwc(wint_t wc, FILE *fp)
{
static const mbstate_t initial;
mbstate_t mbs;
char buf[MB_LEN_MAX];
size_t len;
if (wc == WEOF)
return (WEOF);
mbs = initial;
if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
if ((len = wcrtomb(buf, wc, &fp->_extra->mbstate)) == (size_t)-1) {
fp->_flags |= __SERR;
return (WEOF);
}