1 /* 2 ** Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>. All rights reserved. 3 ** Distributed under the terms of the MIT 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::GetCurrentLocaleBackend; 24 using BPrivate::Libroot::LocaleBackend; 25 26 27 extern "C" size_t 28 __wcrtomb(char* s, wchar_t wc, mbstate_t* ps) 29 { 30 LocaleBackend* backend = GetCurrentLocaleBackend(); 31 32 if (ps == NULL) { 33 static mbstate_t internalMbState; 34 ps = &internalMbState; 35 } 36 37 if (s == NULL) 38 wc = 0; 39 40 if (backend == NULL) { 41 /* 42 * The POSIX locale is active. Since the POSIX locale only contains 43 * chars 0-127 and those ASCII chars are compatible with the UTF32 44 * values used in wint_t, we can just return the byte. 45 */ 46 47 if (wc > 127) { 48 // char is non-ASCII 49 __set_errno(EILSEQ); 50 return (size_t)-1; 51 } 52 53 if (s != NULL) 54 *s = char(wc); 55 56 return 1; 57 } 58 59 size_t lengthUsed; 60 status_t status = backend->WcharToMultibyte(s, wc, ps, lengthUsed); 61 62 if (status == B_BAD_INDEX) 63 return (size_t)-2; 64 65 if (status == B_BAD_DATA) { 66 TRACE(("mbrtowc(): setting errno to EILSEQ\n")); 67 __set_errno(EILSEQ); 68 return (size_t)-1; 69 } 70 71 if (status != B_OK) { 72 TRACE(("wcrtomb(): setting errno to EINVAL (status: %lx)\n", status)); 73 __set_errno(EINVAL); 74 return (size_t)-1; 75 } 76 77 return lengthUsed; 78 } 79 80 81 B_DEFINE_WEAK_ALIAS(__wcrtomb, wcrtomb); 82