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