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:
parent
d0834d4dc8
commit
87275e436a
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)); \
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user