_wfwrite.c 1.9 KB

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