%PAGEREF%(MinGW)

NAME
mbsrtowcs - convert from multibyte to wide character string

SYNOPSIS
#include <wchar.h>

size_t mbsrtowcs( wchar_t *dst, const char **src, size_t len, mbstate_t *ps );

    Feature Test Macro Requirements for libmingwex:

__MSVCRT_VERSION__: since mingwrt-5.3, if this feature test macro is defined, with a value of at least 0x0800, (corresponding to the symbolic constant, __MSCVR80_DLL, and thus declaring intent to link with MSVCR80.DLL, or any later version of Microsoft's non-free runtime library, instead of with MSVCRT.DLL), calls to mbsrtowcs() will be directed to the implementation thereof, within Microsoft's runtime DLL.

_ISOC99_SOURCE, _ISOC11_SOURCE: since mingwrt-5.3.1, when linking with MSVCRT.DLL, or when __MSVCRT_VERSION__ is either undefined, or is defined with any value which is less than 0x0800, (thus denying intent to link with MSVCR80.DLL, or any later non-free version of Microsoft's runtime library), explicitly defining either of these feature test macros will cause any call to mbsrtowcs() to be directed to the libmingwex implementation; if neither macro is defined, calls to mbsrtowcs() will be directed to Microsoft's runtime implementation, if it is available, otherwise falling back to the libmingwex implementation.

Prior to mingwrt-5.3, none of the above feature test macros have any effect on mbsrtowcs(); all calls will be directed to the libmingwex implementation.

DESCRIPTION

Commencing from the conversion state specified in *ps, the mbsrtowcs() function converts the multibyte character sequence, starting at *src, to a sequence of wide characters; each conversion is performed as if by calling the mbrtowc(3) function.

If dst is not a NULL pointer, the resulting sequence of wide characters, up to a maximum of len in number, will be stored as a wide character string, starting at dst; conversion may be curtailed, before len wide characters have been stored, under any of the following conditions:

    •   The result of any one conversion represents the NUL wide character, (in which case the NUL wide character is stored, but is not included in the count of characters converted).

    •   The result of any single multibyte character conversion is a surrogate pair, but the available space, remaining in the conversion buffer, is insufficient to accommodate more than one wchar_t value.

    •   An invalid multibyte character sequence is encountered, (in which case the conversion state becomes undefined).

Conversely, if dst is a NULL pointer, the len argument is ignored, and conversions are performed until either the multibyte equivalent of the NUL character, or an invalid multibyte sequence is encountered, but no wide characters are stored.

The sequence of bytes, pointed to by *src, is interpreted as a multibyte character sequence in the codeset which is associated with the LC_CTYPE category of the active process locale.

If ps is specified as a NULL pointer, mbsrtowcs() will track conversion state using an internal mbstate_t object reference, which is private within the mbsrtowcs() process address space; at process start-up, this internal mbstate_t object is initialized to represent the initial conversion state.

RETURN VALUE
On successful conversion of the multibyte character sequence indirectly pointed to by *src, up to the wide character string length limit specified by len, mbsrtowcs() updates *src, by either:

    •   Replacing it with a NULL pointer, if conversion is terminated by a NUL character, before len wide characters have been evaluated.

    •   Incrementing it, such that it points to the first multibyte character in the *src sequence, which, when converted, would produce wide characters beyond the string length limit specified by len.

In either case, mbsrtowcs() returns the actual number of wchar_t values which have been stored at dst, (if dst is not a NULL pointer, or which would have been stored, otherwise).

ERROR CONDITIONS
If, at any stage of conversion of the multibyte sequence at *src, and, if dst is not a NULL pointer, before len wchar_t values have been evaluated, any sequence within *src, which does not represent a valid multibyte character, is encountered, then errno is set to EILSEQ, and mbsrtowcs() returns (size_t)(-1); the conversion state, including the state of any wchar_t values already stored at *dst, is undefined.

STANDARDS CONFORMANCE
Except in respect of its provisions for handling of surrogate pairs, and to the extent that it may be affected by limitations of the underlying MS-Windows API, the libmingwex implementation of mbsrtowcs() conforms generally to ISO-C99, POSIX.1-2001, and POSIX.1-2008; (prior to mingwrt-5.3, and in those cases where calls may be delegated to a Microsoft runtime DLL implementation, this level of conformity may not be achieved).

CAVEATS AND BUGS
Due to a documented limitation of Microsoft's setlocale() function implementation, it is not possible to directly select an active locale, in which the codeset is represented by any multibyte character sequence with an effective MB_CUR_MAX of more than two bytes. Prior to mingwrt-5.3, this limitation precludes the use of mbsrtowcs() to interpret any codeset with MB_CUR_MAX greater than two bytes, (such as UTF-8). From mingwrt-5.3 onward, the MinGW.org implementation of mbsrtowcs() mitigates this limitation by assignment of the codeset from the LC_CTYPE environment variable, provided the system default has been previously activated for the LC_CTYPE locale category; e.g. execution of:

        #include <stdio.h>
        #include <stdlib.h>
        #include <locale.h>
        #include <wchar.h>
        void print_conv( const char * );
        int main()
        {
          setlocale( LC_CTYPE, "" );
          putenv( "LC_CTYPE=en_GB.65001" );
          print_conv( "\xe6\xb0\xb4\xf0\x9d\x84\x8b" );
          return 0;
        }
        void print_conv( const char *mbs )
        {
          size_t len;
          if( (len = 1 + mbsrtowcs( NULL, &mbs, 0, NULL )) > 0 )
          {
            wchar_t wcs[len];
            len = mbsrtowcs( wch, &mbs, len, NULL );
            printf( "%d wide char%s: ", len, (len == 1) ? "" : "s" );
            while( len > 0 )
            { printf( "0x%04X%c", *wcs++, (--len > 0) : ':' : ' );
            }
          }
          else perror( "mbsrtowcs" );
        }

will convert the UTF-8 encoded multibyte sequence, "\xe6\xb0\xb4\xf0\x9d\x84\x8b", (which represents the two Unicode code points, "\u6c34" and \U0001d10b"), to its equivalent wchar_t sequence, resulting in the three-value output sequence:

        3 wide chars: 0x6C34:0xD834:0xDD0B

Note that, in the preceding example, although the input UTF-8 sequence represents only two Unicode code points, the output shows three distinct wchar_t values, with the second code point being represented by the surrogate pair, "0xD834:0xDD0B". This raises a potential issue, which is consequent on Microsoft's choice of UTF-16LE as the underlying representation of the wchar_t data type: normally, when dst is not a NULL pointer, the MinGW mbsrtowcs() function will simply store a surrogate pair when necessary, but in the particular case where doing so would cause the low surrogate to overrun the buffer length specified by the len argument, then no part of the surrogate pair will be stored, and mbsrtowcs() will stop as if the buffer length limit has been reached, at a count of one less than len. This case may be distinguished from a short count due to conversion of a NUL character, (in which case *src will have been respecified as a NULL pointer), by inspection of *src, which will have been updated to point, in this case, to the start of that part of the multibyte sequence which represents the surrogate pair.

A further issue, also related to surrogate pairs, may arise if the mbstate_t object passed via the *ps argument originates from a preceding mbrtowc(3) call which has returned a high surrogate, but the low surrogate has not been retrieved. In this case, the low surrogate is returned, (and potentially orphaned), as the first wchar_t value to be considered for storage at dst. This may not be what you want, but it is supported as an alternative to the method, formally documented using mbrtowc(3), for completion of a surrogate pair; for example:

        #define _ISOC99_SOURCE
        #include <stdio.h>
        #include <stdlib.h>
        #include <locale.h>
        #include <limits.h>
        #include <winnls.h>
        #include <wchar.h>
        void print_conv( const char * );
        int main()
        {
          setlocale( LC_CTYPE, "" );
          putenv( "LC_CTYPE=en_GB.65001" );
          print_conv( "\U0001d10b" );
          print_conv( "\u6c34" );
          return 0;
        }
        void print_conv( const char *mbs )
        {
          wchar_t wch;
          mbstate_t ps = (mbstate_t)(0);
          size_t n = mbrtowc( &wch, mbs, MB_LEN_MAX, &ps );
          if( (int)(n) > 0 )
          {
            if( IS_HIGH_SURROGATE( wch ) )
            {
              wchar_t wcl;
              mbsrtowcs( &wcl, &mbs, 1, &ps );
              printf( "%u bytes -> 0x%04X:0x%04X\n", n, wch, wcl );
            }
            else printf( "%u bytes -> 0x%04X\n", n, wch );
          }
          else if( n == (size_t)(-1) ) perror( "mbrtowc" );
        }

is equivalent to the example given for surrogate pair completion using mbrtowc(3). Regardless of the method used to complete surrogate pairs, it is the caller's responsibility to ensure that the high surrogate and its complementary low surrogate remain correctly associated.

SEE ALSO
mbsinit(3), and mbrtowc(3)

AUTHOR
This manpage was written by Keith Marshall, <keith@users.osdn.me>, to document the mbsrtowcs() function as it has been implemented for the MinGW.org Project. It may be copied, modified and redistributed, without restriction of copyright, provided this acknowledgement of contribution by the original author remains in place.