1 /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
2 *
3 * GNU Library General Public License (LGPL) version 2 or later.
4 *
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
7
8 #include "_stdio.h"
9 #include <wchar.h>
10
11 #ifndef __UCLIBC_HAS_WCHAR__
12 #error wide function when no wide support!
13 #endif
14
15 #ifdef __UCLIBC_MJN3_ONLY__
16 #warning TODO: Fix prototype.
17 #endif
18
19
_wstdio_fwrite(const wchar_t * __restrict ws,size_t n,register FILE * __restrict stream)20 size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
21 register FILE *__restrict stream)
22 {
23 size_t r, count;
24 char buf[64];
25 const wchar_t *pw;
26
27 __STDIO_STREAM_VALIDATE(stream);
28
29 #ifdef __STDIO_BUFFERS
30 if (__STDIO_STREAM_IS_FAKE_VSWPRINTF(stream)) {
31 /* We know buffer is wchar aligned for fake streams. */
32 count = (((wchar_t *)(stream->__bufend))
33 - ((wchar_t *)(stream->__bufpos)));
34 if (count > n) {
35 count = n;
36 }
37 if (count) {
38 wmemcpy((wchar_t *)(stream->__bufpos), ws, count);
39 stream->__bufpos = (unsigned char *)(((wchar_t *)(stream->__bufpos)) + count);
40 }
41 __STDIO_STREAM_VALIDATE(stream);
42 return n;
43 }
44 #endif
45
46 count = 0;
47
48 if (__STDIO_STREAM_IS_WIDE_WRITING(stream)
49 || !__STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE)
50 ) {
51
52 pw = ws;
53 while (n > count) {
54 r = wcsnrtombs(buf, &pw, n-count, sizeof(buf), &stream->__state);
55 if (r != ((size_t) -1)) { /* No encoding errors */
56 if (!r) {
57 ++r; /* 0 is returned when nul is reached. */
58 pw = ws + count + r; /* pw was set to NULL, so correct. */
59 }
60 if (__stdio_fwrite((const unsigned char *)buf, r, stream) == r) {
61 count = pw - ws;
62 continue;
63 }
64 }
65 break;
66 }
67
68 /* Note: The count is incorrect if 0 < __stdio_fwrite return < r!!! */
69 }
70
71 __STDIO_STREAM_VALIDATE(stream);
72 return count;
73 }
74