123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
- *
- * GNU Library General Public License (LGPL) version 2 or later.
- *
- * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
- */
- #include "_stdio.h"
- #include <wchar.h>
- #ifndef __UCLIBC_HAS_WCHAR__
- #error wide function when no wide support!
- #endif
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Fix prototype.
- #endif
- extern size_t __wcsnrtombs(char *__restrict dst,
- const wchar_t **__restrict src,
- size_t NWC, size_t len, mbstate_t *__restrict ps) attribute_hidden;
- size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
- register FILE *__restrict stream)
- {
- size_t r, count;
- char buf[64];
- const wchar_t *pw;
- __STDIO_STREAM_VALIDATE(stream);
- #ifdef __STDIO_BUFFERS
- if (__STDIO_STREAM_IS_FAKE_VSWPRINTF(stream)) {
- /* We know buffer is wchar aligned for fake streams. */
- count = (((wchar_t *)(stream->__bufend))
- - ((wchar_t *)(stream->__bufpos)));
- if (count > n) {
- count = n;
- }
- if (count) {
- wmemcpy((wchar_t *)(stream->__bufpos), ws, count);
- stream->__bufpos = (char *)(((wchar_t *)(stream->__bufpos)) + count);
- }
- __STDIO_STREAM_VALIDATE(stream);
- return n;
- }
- #endif
- count = 0;
- if (__STDIO_STREAM_IS_WIDE_WRITING(stream)
- || !__STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE)
- ) {
- pw = ws;
- while (n > count) {
- r = __wcsnrtombs(buf, &pw, n-count, sizeof(buf), &stream->__state);
- if (r != ((size_t) -1)) { /* No encoding errors */
- if (!r) {
- ++r; /* 0 is returned when nul is reached. */
- pw = ws + count + r; /* pw was set to NULL, so correct. */
- }
- if (__stdio_fwrite(buf, r, stream) == r) {
- count = pw - ws;
- continue;
- }
- }
- break;
- }
- /* Note: The count is incorrect if 0 < __stdio_fwrite return < r!!! */
- }
- __STDIO_STREAM_VALIDATE(stream);
- return count;
- }
|