1 /* 2 ** Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>. All rights reserved. 3 ** Distributed under the terms of the Haiku License. 4 */ 5 6 #include <errno.h> 7 #include <string.h> 8 #include <wchar.h> 9 10 #include <errno_private.h> 11 #include <LocaleBackend.h> 12 13 14 //#define TRACE_WCRTOMB 15 #ifdef TRACE_WCRTOMB 16 # include <OS.h> 17 # define TRACE(x) debug_printf x 18 #else 19 # define TRACE(x) ; 20 #endif 21 22 23 using BPrivate::Libroot::gLocaleBackend; 24 25 26 extern "C" size_t 27 __wcrtomb(char* s, wchar_t wc, mbstate_t* ps) 28 { 29 if (ps == NULL) { 30 static mbstate_t internalMbState; 31 ps = &internalMbState; 32 } 33 34 if (s == NULL) 35 wc = 0; 36 37 if (gLocaleBackend == NULL) { 38 /* 39 * The POSIX locale is active. Since the POSIX locale only contains 40 * chars 0-127 and those ASCII chars are compatible with the UTF32 41 * values used in wint_t, we can just return the byte. 42 */ 43 44 if (wc > 127) { 45 // char is non-ASCII 46 __set_errno(EILSEQ); 47 return (size_t)-1; 48 } 49 50 if (s != NULL) 51 *s = char(wc); 52 53 return 1; 54 } 55 56 size_t lengthUsed; 57 status_t status = gLocaleBackend->WcharToMultibyte(s, wc, ps, lengthUsed); 58 59 if (status == B_BAD_INDEX) 60 return (size_t)-2; 61 62 if (status == B_BAD_DATA) { 63 TRACE(("mbrtowc(): setting errno to EILSEQ\n")); 64 __set_errno(EILSEQ); 65 return (size_t)-1; 66 } 67 68 if (status != B_OK) { 69 TRACE(("wcrtomb(): setting errno to EINVAL (status: %lx)\n", status)); 70 __set_errno(EINVAL); 71 return (size_t)-1; 72 } 73 74 return lengthUsed; 75 } 76 77 78 extern "C" 79 B_DEFINE_WEAK_ALIAS(__wcrtomb, wcrtomb); 80