]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/stdio/_wfwrite.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / stdio / _wfwrite.c
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
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 }