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_MBRTOWC 15 #ifdef TRACE_MBRTOWC 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 __mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps) 29 { 30 if (ps == NULL) { 31 static mbstate_t internalMbState; 32 ps = &internalMbState; 33 } 34 35 if (s == NULL) 36 return __mbrtowc(NULL, "", 1, ps); 37 38 LocaleBackend* backend = GetCurrentLocaleBackend(); 39 40 if (backend == NULL) { 41 if (*s == '\0') { 42 memset(ps, 0, sizeof(mbstate_t)); 43 44 if (pwc != NULL) 45 *pwc = 0; 46 47 return 0; 48 } 49 50 /* 51 * The POSIX locale is active. Since the POSIX locale only contains 52 * chars 0-127 and those ASCII chars are compatible with the UTF32 53 * values used in wint_t, we can just return the byte. 54 */ 55 56 if (*s < 0) { 57 // char is non-ASCII 58 __set_errno(EILSEQ); 59 return (size_t)-1; 60 } 61 62 if (pwc != NULL) 63 *pwc = *s; 64 65 return 1; 66 } 67 68 size_t lengthUsed; 69 status_t status = backend->MultibyteToWchar(pwc, s, n, ps, lengthUsed); 70 71 if (status == B_BAD_INDEX) 72 return (size_t)-2; 73 74 if (status == B_BAD_DATA) { 75 TRACE(("mbrtowc(): setting errno to EILSEQ\n")); 76 __set_errno(EILSEQ); 77 return (size_t)-1; 78 } 79 80 if (status != B_OK) { 81 TRACE(("mbrtowc(): setting errno to EINVAL (status: %lx)\n", status)); 82 __set_errno(EINVAL); 83 return (size_t)-1; 84 } 85 86 return lengthUsed; 87 } 88 89 90 B_DEFINE_WEAK_ALIAS(__mbrtowc, mbrtowc); 91