Allow encoding modules to override the default implementations of

mbsrtowcs() and wcsrtombs(). Provide a fast implementation for the
trivial "NONE" encoding.
This commit is contained in:
Tim J. Robbins 2004-05-13 11:20:27 +00:00
parent 33e48d06ba
commit ea4ac135ff
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129179
8 changed files with 113 additions and 9 deletions

View File

@ -37,7 +37,11 @@
extern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict,
size_t, mbstate_t * __restrict);
extern int (*__mbsinit)(const mbstate_t *);
extern size_t (*__mbsrtowcs)(wchar_t * __restrict, const char ** __restrict,
size_t, mbstate_t * __restrict);
extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict);
extern size_t (*__wcsrtombs)(char * __restrict, const wchar_t ** __restrict,
size_t, mbstate_t * __restrict);
/*
* Conversion functions for "NONE"/C/POSIX encoding.
@ -45,8 +49,17 @@ extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict);
extern size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict,
size_t, mbstate_t * __restrict);
extern int _none_mbsinit(const mbstate_t *);
extern size_t _none_mbsrtowcs(wchar_t * __restrict, const char ** __restrict,
size_t, mbstate_t * __restrict);
extern size_t _none_wcrtomb(char * __restrict, wchar_t,
mbstate_t * __restrict);
extern size_t _none_wcsrtombs(char * __restrict, const wchar_t ** __restrict,
size_t, mbstate_t * __restrict);
extern size_t __mbsrtowcs_std(wchar_t * __restrict, const char ** __restrict,
size_t, mbstate_t * __restrict);
extern size_t __wcsrtombs_std(char * __restrict, const wchar_t ** __restrict,
size_t, mbstate_t * __restrict);
/*
* Rune emulation functions.

View File

@ -38,6 +38,16 @@ mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
mbstate_t * __restrict ps)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
return (__mbsrtowcs(dst, src, len, ps));
}
size_t
__mbsrtowcs_std(wchar_t * __restrict dst, const char ** __restrict src,
size_t len, mbstate_t * __restrict ps)
{
const char *s;
size_t nchr;
wchar_t wc;
@ -46,8 +56,6 @@ mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len,
s = *src;
nchr = 0;
if (ps == NULL)
ps = &mbs;
if (dst == NULL) {
for (;;) {
if ((nb = (int)__mbrtowc(&wc, s, MB_CUR_MAX, ps)) < 0)

View File

@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <wchar.h>
#include "mblocal.h"
size_t
mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
@ -37,5 +38,5 @@ mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n)
mbstate_t mbs;
mbs = initial;
return (mbsrtowcs(pwcs, &s, n, &mbs));
return (__mbsrtowcs(pwcs, &s, n, &mbs));
}

View File

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "mblocal.h"
@ -54,7 +55,11 @@ int _none_init(_RuneLocale *);
size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict);
int _none_mbsinit(const mbstate_t *);
size_t _none_mbsrtowcs(wchar_t * __restrict, const char ** __restrict,
size_t, mbstate_t * __restrict);
size_t _none_wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict);
size_t _none_wcsrtombs(char * __restrict, const wchar_t ** __restrict,
size_t, mbstate_t * __restrict);
int
_none_init(_RuneLocale *rl)
@ -62,7 +67,9 @@ _none_init(_RuneLocale *rl)
__mbrtowc = _none_mbrtowc;
__mbsinit = _none_mbsinit;
__mbsrtowcs = _none_mbsrtowcs;
__wcrtomb = _none_wcrtomb;
__wcsrtombs = _none_wcsrtombs;
_CurrentRuneLocale = rl;
__mb_cur_max = 1;
return(0);
@ -110,3 +117,53 @@ _none_wcrtomb(char * __restrict s, wchar_t wc,
*s = (unsigned char)wc;
return (1);
}
size_t
_none_mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src,
size_t len, mbstate_t * __restrict ps __unused)
{
const char *s;
size_t nchr;
if (dst == NULL)
return (strlen(*src));
s = *src;
nchr = 0;
while (len-- > 0) {
if ((*dst++ = (unsigned char)*s++) == L'\0') {
*src = NULL;
return (nchr);
}
nchr++;
}
*src = s;
return (nchr);
}
size_t
_none_wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src,
size_t len, mbstate_t * __restrict ps __unused)
{
const wchar_t *s;
size_t nchr;
if (dst == NULL)
return (wcslen(*src));
s = *src;
nchr = 0;
while (len-- > 0) {
if (*s < 0 || *s > UCHAR_MAX) {
errno = EILSEQ;
return ((size_t)-1);
}
if ((*dst++ = *s++) == '\0') {
*src = NULL;
return (nchr);
}
nchr++;
}
*src = s;
return (nchr);
}

View File

@ -100,6 +100,10 @@ __setrunelocale(const char *encoding)
static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t,
mbstate_t * __restrict);
static int (*Cached__mbsinit)(const mbstate_t *);
static size_t (*Cached__mbsrtowcs)(wchar_t * __restrict,
const char ** __restrict, size_t, mbstate_t * __restrict);
static size_t (*Cached__wcsrtombs)(char * __restrict,
const wchar_t ** __restrict, size_t, mbstate_t * __restrict);
/*
* The "C" and "POSIX" locale are always here.
@ -108,8 +112,10 @@ __setrunelocale(const char *encoding)
_CurrentRuneLocale = &_DefaultRuneLocale;
__mb_cur_max = 1;
__mbrtowc = _none_mbrtowc;
__wcrtomb = _none_wcrtomb;
__mbsinit = _none_mbsinit;
__mbsrtowcs = _none_mbsrtowcs;
__wcrtomb = _none_wcrtomb;
__wcsrtombs = _none_wcsrtombs;
return (0);
}
@ -121,8 +127,10 @@ __setrunelocale(const char *encoding)
_CurrentRuneLocale = CachedRuneLocale;
__mb_cur_max = Cached__mb_cur_max;
__mbrtowc = Cached__mbrtowc;
__wcrtomb = Cached__wcrtomb;
__mbsinit = Cached__mbsinit;
__mbsrtowcs = Cached__mbsrtowcs;
__wcrtomb = Cached__wcrtomb;
__wcsrtombs = Cached__wcsrtombs;
return (0);
}
@ -147,8 +155,10 @@ __setrunelocale(const char *encoding)
(void)fclose(fp);
__mbrtowc = NULL;
__wcrtomb = NULL;
__mbsinit = NULL;
__mbsrtowcs = __mbsrtowcs_std;
__wcrtomb = NULL;
__wcsrtombs = __wcsrtombs_std;
rl->sputrune = __emulated_sputrune;
rl->sgetrune = __emulated_sgetrune;
if (strcmp(rl->encoding, "NONE") == 0)
@ -182,7 +192,9 @@ __setrunelocale(const char *encoding)
Cached__mb_cur_max = __mb_cur_max;
Cached__mbrtowc = __mbrtowc;
Cached__mbsinit = __mbsinit;
Cached__mbsrtowcs = __mbsrtowcs;
Cached__wcrtomb = __wcrtomb;
Cached__wcsrtombs = __wcsrtombs;
(void)strcpy(ctype_encoding, encoding);
} else
free(rl);

View File

@ -255,5 +255,9 @@ int __mb_cur_max = 1;
size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict) = _none_mbrtowc;
int (*__mbsinit)(const mbstate_t *) = _none_mbsinit;
size_t (*__mbsrtowcs)(wchar_t * __restrict, const char ** __restrict,
size_t, mbstate_t * __restrict) = _none_mbsrtowcs;
size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) =
_none_wcrtomb;
size_t (*__wcsrtombs)(char * __restrict, const wchar_t ** __restrict,
size_t, mbstate_t * __restrict) = _none_wcsrtombs;

View File

@ -38,6 +38,16 @@ wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
mbstate_t * __restrict ps)
{
static mbstate_t mbs;
if (ps == NULL)
ps = &mbs;
return (__wcsrtombs(dst, src, len, ps));
}
size_t
__wcsrtombs_std(char * __restrict dst, const wchar_t ** __restrict src,
size_t len, mbstate_t * __restrict ps)
{
mbstate_t mbsbak;
char buf[MB_LEN_MAX];
const wchar_t *s;
@ -47,8 +57,6 @@ wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len,
s = *src;
nbytes = 0;
if (ps == NULL)
ps = &mbs;
if (dst == NULL) {
for (;;) {
if ((nb = (int)__wcrtomb(buf, *s, ps)) < 0)

View File

@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <wchar.h>
#include "mblocal.h"
size_t
wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
@ -37,5 +38,5 @@ wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
mbstate_t mbs;
mbs = initial;
return (wcsrtombs(s, &pwcs, n, &mbs));
return (__wcsrtombs(s, &pwcs, n, &mbs));
}