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
11 #ifdef __STDIO_BUFFERS
12
13 /* Either buffer data or (commit buffer if necessary and) write. */
14
__stdio_fwrite(const unsigned char * __restrict buffer,size_t bytes,register FILE * __restrict stream)15 size_t attribute_hidden __stdio_fwrite(const unsigned char * __restrict buffer,
16 size_t bytes,
17 register FILE * __restrict stream)
18 {
19 size_t pending;
20 const unsigned char *p;
21
22 __STDIO_STREAM_VALIDATE(stream);
23 assert(__STDIO_STREAM_IS_WRITING(stream));
24 assert(buffer);
25 assert(bytes);
26
27 if (!__STDIO_STREAM_IS_NBF(stream)) { /* FBF or LBF. */
28 if (__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream)) {
29 pending = __STDIO_STREAM_BUFFER_WAVAIL(stream);
30 if (pending > bytes) {
31 pending = bytes;
32 }
33 memcpy(stream->__bufpos, buffer, pending);
34 stream->__bufpos += pending;
35 __STDIO_STREAM_VALIDATE(stream);
36 return bytes;
37 }
38
39 /* RETRY: */
40 if (bytes <= __STDIO_STREAM_BUFFER_WAVAIL(stream)) {
41 memcpy(stream->__bufpos, buffer, bytes);
42 stream->__bufpos += bytes;
43 if (__STDIO_STREAM_IS_LBF(stream)
44 && memrchr(buffer, '\n', bytes) /* Search backwards. */
45 ) {
46 if ((pending = __STDIO_COMMIT_WRITE_BUFFER(stream)) > 0) {
47 if (pending > bytes) {
48 pending = bytes;
49 }
50 buffer += (bytes - pending);
51 if ((p = memchr(buffer, '\n', pending)) != NULL) {
52 pending = (buffer + pending) - p;
53 bytes -= pending;
54 stream->__bufpos -= pending;
55 }
56 }
57 }
58 __STDIO_STREAM_VALIDATE(stream);
59 return bytes;
60 }
61 /* FBF or LBF and not enough space in buffer. */
62 if (__STDIO_STREAM_BUFFER_WUSED(stream)) { /* Buffered data. */
63 if (__STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */
64 return 0;
65 }
66 /* goto RETRY; */
67 }
68 }
69
70 return __stdio_WRITE(stream, buffer, bytes);
71 }
72
73 #endif
74