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