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:
parent
33e48d06ba
commit
ea4ac135ff
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user