libroot_debug: Merge guarded heap into libroot_debug.
[haiku.git] / src / system / libroot / posix / wchar / wcsrtombs.cpp
blob69e38decd52e2a957026aa15918b1c501c5b5496
1 /*
2 ** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
3 ** Distributed under the terms of the Haiku License.
4 */
6 #include <errno.h>
7 #include <string.h>
8 #include <wchar.h>
10 #include <errno_private.h>
11 #include <LocaleBackend.h>
12 #include <wchar_private.h>
15 //#define TRACE_WCSRTOMBS
16 #ifdef TRACE_WCSRTOMBS
17 # include <OS.h>
18 # define TRACE(x) debug_printf x
19 #else
20 # define TRACE(x) ;
21 #endif
24 using BPrivate::Libroot::gLocaleBackend;
27 extern "C" size_t
28 __wcsnrtombs(char* dst, const wchar_t** src, size_t nwc, size_t len,
29 mbstate_t* ps)
31 TRACE(("wcsnrtombs(%p, %p, %lu, %lu) - lb:%p\n", dst, *src, nwc, len,
32 gLocaleBackend));
34 if (ps == NULL) {
35 static mbstate_t internalMbState;
36 ps = &internalMbState;
39 if (gLocaleBackend == NULL) {
41 * The POSIX locale is active. Since the POSIX locale only contains
42 * chars 0-127 and those ASCII chars are compatible with the UTF32
43 * values used in wint_t, we can just copy the codepoint values.
45 size_t count = 0;
46 const wchar_t* srcEnd = *src + nwc;
47 if (dst == NULL) {
48 // only count number of required wide characters
49 const wchar_t* wcSrc = *src;
50 for (; wcSrc < srcEnd; ++wcSrc, ++count) {
51 if (*wcSrc < 0) {
52 // char is non-ASCII
53 __set_errno(EILSEQ);
54 count = (size_t)-1;
55 break;
57 if (*wcSrc == 0) {
58 memset(ps, 0, sizeof(mbstate_t));
59 break;
62 } else {
63 // "convert" the characters
64 for (; *src < srcEnd && count < len; ++*src, ++count) {
65 if (**src < 0) {
66 // char is non-ASCII
67 __set_errno(EILSEQ);
68 count = (size_t)-1;
69 break;
71 *dst++ = (char)**src;
72 if (**src == 0) {
73 memset(ps, 0, sizeof(mbstate_t));
74 *src = NULL;
75 break;
80 TRACE(("wcsnrtombs returns %lx and src %p\n", count, *src));
82 return count;
85 size_t result = 0;
86 status_t status = gLocaleBackend->WcharStringToMultibyte(dst, len, src, nwc,
87 ps, result);
89 if (status == B_BAD_DATA) {
90 TRACE(("wcsnrtomb(): setting errno to EILSEQ\n"));
91 __set_errno(EILSEQ);
92 result = (size_t)-1;
93 } else if (status != B_OK) {
94 TRACE(("wcsnrtomb(): setting errno to EINVAL (status: %lx)\n", status));
95 __set_errno(EINVAL);
96 result = (size_t)-1;
99 TRACE(("wcsnrtombs returns %lx and src %p\n", result, *src));
101 return result;
105 extern "C"
106 B_DEFINE_WEAK_ALIAS(__wcsnrtombs, wcsnrtombs);
109 extern "C" size_t
110 __wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps)
112 if (ps == NULL) {
113 static mbstate_t internalMbState;
114 ps = &internalMbState;
117 return __wcsnrtombs(dst, src, __wcslen(*src) + 1, len, ps);
121 extern "C"
122 B_DEFINE_WEAK_ALIAS(__wcsrtombs, wcsrtombs);