_fwrite.c 2.1 KB

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