_fwrite.c 2.1 KB

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