/* ** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved. ** Distributed under the terms of the MIT License. */ #include #include #include #include #include //#define TRACE_MBRTOWC #ifdef TRACE_MBRTOWC # include # define TRACE(x) debug_printf x #else # define TRACE(x) ; #endif using BPrivate::Libroot::GetCurrentLocaleBackend; using BPrivate::Libroot::LocaleBackend; extern "C" size_t __mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps) { if (ps == NULL) { static mbstate_t internalMbState; ps = &internalMbState; } if (s == NULL) return __mbrtowc(NULL, "", 1, ps); if (n == 0) return (size_t)-2; LocaleBackend* backend = GetCurrentLocaleBackend(); if (backend == NULL) { if (*s == '\0') { memset(ps, 0, sizeof(mbstate_t)); if (pwc != NULL) *pwc = 0; return 0; } /* * The POSIX locale is active. Since the POSIX locale only contains * chars 0-127 and those ASCII chars are compatible with the UTF32 * values used in wint_t, we can just return the byte. */ if (*s < 0) { // char is non-ASCII __set_errno(EILSEQ); return (size_t)-1; } if (pwc != NULL) *pwc = *s; return 1; } size_t lengthUsed; status_t status = backend->MultibyteToWchar(pwc, s, n, ps, lengthUsed); if (status == B_BAD_INDEX) return (size_t)-2; if (status == B_BAD_DATA) { TRACE(("mbrtowc(): setting errno to EILSEQ\n")); __set_errno(EILSEQ); return (size_t)-1; } if (status != B_OK) { TRACE(("mbrtowc(): setting errno to EINVAL (status: %lx)\n", status)); __set_errno(EINVAL); return (size_t)-1; } return lengthUsed; } B_DEFINE_WEAK_ALIAS(__mbrtowc, mbrtowc);