diff options
Diffstat (limited to 'libc/bionic/wchar.cpp')
-rw-r--r-- | libc/bionic/wchar.cpp | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp index 8367817..a507808 100644 --- a/libc/bionic/wchar.cpp +++ b/libc/bionic/wchar.cpp @@ -243,21 +243,42 @@ size_t wcsftime(wchar_t* wcs, size_t maxsize, const wchar_t* format, const stru return strftime(reinterpret_cast<char*>(wcs), maxsize, reinterpret_cast<const char*>(format), timptr); } -size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* /*ps*/) { - const char* s = reinterpret_cast<const char*>(*src); - const char* s2 = reinterpret_cast<const char*>(memchr(s, 0, len)); - if (s2 != NULL) { - len = (s2 - s)+1; +size_t wcsrtombs(char* dst, const wchar_t** src, size_t n, mbstate_t* /*ps*/) { + size_t i = 0; // Number of input characters read. + size_t o = 0; // Number of output bytes written. + for (; (*src)[i] != 0; ++i) { + // TODO: UTF-8 support. + if ((*src)[i] > 0x7f) { + errno = EILSEQ; + return static_cast<size_t>(-1); + } + if (dst != NULL) { + if (o + 1 > n) { + break; + } + dst[o++] = static_cast<char>((*src)[i]); + } else { + ++o; + } } + // If we consumed all the input, terminate the output. + if (dst != NULL && o < n) { + dst[o] = 0; + } + // If we were actually consuming input, record how far we got. if (dst != NULL) { - memcpy( dst, s, len ); + if ((*src)[i] != 0) { + *src = &(*src)[i]; // This is where the next call should pick up. + } else { + *src = NULL; // We consumed everything. + } } - *src = (wchar_t*)(s + len); - return len; + return o; } size_t wcstombs(char* dst, const wchar_t* src, size_t len) { - return wcsrtombs(dst, &src, len, NULL); + const wchar_t* p = src; + return wcsrtombs(dst, &p, len, NULL); } double wcstod(const wchar_t* nptr, wchar_t** endptr) { |