1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
/* Copyright (c) 2009 Corinna Vinschen <corinna@vinschen.de> */
/*
FUNCTION
<<wcsrtombs>>, <<wcsnrtombs>>---convert a wide-character string to a character string
INDEX
wcsrtombs
INDEX
_wcsrtombs_r
INDEX
wcsnrtombs
INDEX
_wcsnrtombs_r
SYNOPSIS
#include <wchar.h>
size_t wcsrtombs(char *__restrict <[dst]>,
const wchar_t **__restrict <[src]>, size_t <[len]>,
mbstate_t *__restrict <[ps]>);
#include <wchar.h>
size_t _wcsrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
const wchar_t **<[src]>, size_t <[len]>,
mbstate_t *<[ps]>);
#include <wchar.h>
size_t wcsnrtombs(char *__restrict <[dst]>,
const wchar_t **__restrict <[src]>,
size_t <[nwc]>, size_t <[len]>,
mbstate_t *__restrict <[ps]>);
#include <wchar.h>
size_t _wcsnrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
const wchar_t **<[src]>, size_t <[nwc]>,
size_t <[len]>, mbstate_t *<[ps]>);
DESCRIPTION
The <<wcsrtombs>> function converts a string of wide characters indirectly
pointed to by <[src]> to a corresponding multibyte character string stored in
the array pointed to by <[dst]>. No more than <[len]> bytes are written to
<[dst]>.
If <[dst]> is NULL, no characters are stored.
If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point
to the character after the one that conversion stopped at. If conversion
stops because a null character is encountered, *<[src]> is set to NULL.
The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If
it is NULL, <<wcsrtombs>> uses an internal, static mbstate_t object, which
is initialized to the initial conversion state at program startup.
The <<wcsnrtombs>> function behaves identically to <<wcsrtombs>>, except that
conversion stops after reading at most <[nwc]> characters from the buffer
pointed to by <[src]>.
RETURNS
The <<wcsrtombs>> and <<wcsnrtombs>> functions return the number of bytes
stored in the array pointed to by <[dst]> (not including any terminating
null), if successful, otherwise it returns (size_t)-1.
PORTABILITY
<<wcsrtombs>> is defined by C99 standard.
<<wcsnrtombs>> is defined by the POSIX.1-2008 standard.
*/
#include <newlib.h>
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "local.h"
#include "../locale/setlocale.h"
size_t
_wcsnrtombs_l (char *dst, const wchar_t **src, size_t nwc,
size_t len, mbstate_t *ps, struct __locale_t *loc)
{
char *ptr = dst;
char buff[10];
wchar_t *pwcs;
size_t n;
int i;
#ifdef _MB_CAPABLE
if (ps == NULL)
{
static NEWLIB_THREAD_LOCAL mbstate_t _wcsrtombs_state;
ps = &_wcsrtombs_state;
}
#endif
/* If no dst pointer, treat len as maximum possible value. */
if (dst == NULL)
len = (size_t)-1;
n = 0;
pwcs = (wchar_t *)(*src);
while (n < len && nwc-- > 0)
{
int count = ps->__count;
wint_t wch = ps->__value.__wch;
int bytes = loc->wctomb (buff, *pwcs, ps);
if (bytes == -1)
{
_REENT_ERRNO(r) = EILSEQ;
ps->__count = 0;
return (size_t)-1;
}
if (n + bytes <= len)
{
n += bytes;
if (dst)
{
for (i = 0; i < bytes; ++i)
*ptr++ = buff[i];
++(*src);
}
if (*pwcs++ == 0x00)
{
if (dst)
*src = NULL;
ps->__count = 0;
return n - 1;
}
}
else
{
/* not enough room, we must back up state to before __WCTOMB call */
ps->__count = count;
ps->__value.__wch = wch;
len = 0;
}
}
return n;
}
#ifndef _REENT_ONLY
size_t
wcsnrtombs (char *__restrict dst,
const wchar_t **__restrict src,
size_t nwc,
size_t len,
mbstate_t *__restrict ps)
{
return _wcsnrtombs_l (dst, src, nwc, len, ps,
__get_current_locale ());
}
#endif /* !_REENT_ONLY */
|