c16rtomb.c 573 B

1234567891011121314151617181920212223242526272829303132333435
  1. #include <uchar.h>
  2. #include <errno.h>
  3. #include <wchar.h>
  4. size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
  5. {
  6. static unsigned internal_state;
  7. if (!ps) ps = (void *)&internal_state;
  8. unsigned *x = (unsigned *)ps;
  9. wchar_t wc;
  10. if (!s) {
  11. if (*x) goto ilseq;
  12. return 1;
  13. }
  14. if (!*x && c16 - 0xd800u < 0x400) {
  15. *x = c16 - 0xd7c0 << 10;
  16. return 0;
  17. }
  18. if (*x) {
  19. if (c16 - 0xdc00u >= 0x400) goto ilseq;
  20. else wc = *x + c16 - 0xdc00;
  21. *x = 0;
  22. } else {
  23. wc = c16;
  24. }
  25. return wcrtomb(s, wc, 0);
  26. ilseq:
  27. *x = 0;
  28. errno = EILSEQ;
  29. return -1;
  30. }