_wfwrite.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. #include <wchar.h>
  9. #ifndef __UCLIBC_HAS_WCHAR__
  10. #error wide function when no wide support!
  11. #endif
  12. #ifdef __UCLIBC_MJN3_ONLY__
  13. #warning TODO: Fix prototype.
  14. #endif
  15. /* libc_hidden_proto(wmemcpy) */
  16. /* libc_hidden_proto(wcsnrtombs) */
  17. size_t attribute_hidden _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
  18. register FILE *__restrict stream)
  19. {
  20. size_t r, count;
  21. char buf[64];
  22. const wchar_t *pw;
  23. __STDIO_STREAM_VALIDATE(stream);
  24. #ifdef __STDIO_BUFFERS
  25. if (__STDIO_STREAM_IS_FAKE_VSWPRINTF(stream)) {
  26. /* We know buffer is wchar aligned for fake streams. */
  27. count = (((wchar_t *)(stream->__bufend))
  28. - ((wchar_t *)(stream->__bufpos)));
  29. if (count > n) {
  30. count = n;
  31. }
  32. if (count) {
  33. wmemcpy((wchar_t *)(stream->__bufpos), ws, count);
  34. stream->__bufpos = (unsigned char *)(((wchar_t *)(stream->__bufpos)) + count);
  35. }
  36. __STDIO_STREAM_VALIDATE(stream);
  37. return n;
  38. }
  39. #endif
  40. count = 0;
  41. if (__STDIO_STREAM_IS_WIDE_WRITING(stream)
  42. || !__STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE)
  43. ) {
  44. pw = ws;
  45. while (n > count) {
  46. r = wcsnrtombs(buf, &pw, n-count, sizeof(buf), &stream->__state);
  47. if (r != ((size_t) -1)) { /* No encoding errors */
  48. if (!r) {
  49. ++r; /* 0 is returned when nul is reached. */
  50. pw = ws + count + r; /* pw was set to NULL, so correct. */
  51. }
  52. if (__stdio_fwrite((const unsigned char *)buf, r, stream) == r) {
  53. count = pw - ws;
  54. continue;
  55. }
  56. }
  57. break;
  58. }
  59. /* Note: The count is incorrect if 0 < __stdio_fwrite return < r!!! */
  60. }
  61. __STDIO_STREAM_VALIDATE(stream);
  62. return count;
  63. }