OSDN Git Service

hidden_def/hidden_proto: convert all users (I hope) termios split, add some missing...
[uclinux-h8/uClibc.git] / libc / stdio / _fwrite.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
10 libc_hidden_proto(memchr)
11 libc_hidden_proto(memcpy)
12 libc_hidden_proto(memrchr)
13
14 #ifdef __STDIO_BUFFERS
15
16 /* Either buffer data or (commit buffer if necessary and) write. */
17
18 size_t attribute_hidden __stdio_fwrite(const unsigned char * __restrict buffer,
19                                           size_t bytes,
20                                           register FILE * __restrict stream)
21 {
22         size_t pending;
23         const unsigned char *p;
24
25         __STDIO_STREAM_VALIDATE(stream);
26         assert(__STDIO_STREAM_IS_WRITING(stream));
27         assert(buffer);
28         assert(bytes);
29
30         if (!__STDIO_STREAM_IS_NBF(stream)) { /* FBF or LBF. */
31 #ifdef __UCLIBC_MJN3_ONLY__
32 #warning CONSIDER: Try to consolidate some of the code?
33 #endif
34                 if (__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream)) {
35                         pending = __STDIO_STREAM_BUFFER_WAVAIL(stream);
36                         if (pending > bytes) {
37                                 pending = bytes;
38                         }
39                         memcpy(stream->__bufpos, buffer, pending);
40                         stream->__bufpos += pending;
41                         __STDIO_STREAM_VALIDATE(stream);
42                         return bytes;
43                 }
44
45 /*      RETRY: */
46                 if (bytes <= __STDIO_STREAM_BUFFER_WAVAIL(stream)) {
47                         memcpy(stream->__bufpos, buffer, bytes);
48                         stream->__bufpos += bytes;
49                         if (__STDIO_STREAM_IS_LBF(stream)
50                                 && memrchr(buffer, '\n', bytes) /* Search backwards. */
51                                 ) {
52                                 if ((pending = __STDIO_COMMIT_WRITE_BUFFER(stream)) > 0) {
53                                         if (pending > bytes) {
54                                                 pending = bytes;
55                                         }
56                                         buffer += (bytes - pending);
57                                         if ((p = memchr(buffer, '\n', pending)) != NULL) {
58                                                 pending = (buffer + pending) - p;
59                                                 bytes -= pending;
60                                                 stream->__bufpos -= pending;
61                                         }
62                                 }
63                         }
64                         __STDIO_STREAM_VALIDATE(stream);
65                         return bytes;
66                 }
67                 /* FBF or LBF and not enough space in buffer. */
68                 if (__STDIO_STREAM_BUFFER_WUSED(stream)) { /* Buffered data. */
69                         if (__STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */
70                                 return 0;
71                         }
72 #ifdef __UCLIBC_MJN3_ONLY__
73 #warning CONSIDER: Do we want to try again if data now fits in buffer?
74 #endif
75 /*                      goto RETRY; */
76                 }
77         }
78
79         return __stdio_WRITE(stream, buffer, bytes);
80 }
81
82 #endif