toucs.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * toucs.c - convert charsets to Unicode.
  3. */
  4. #include "charset.h"
  5. #include "internal.h"
  6. struct unicode_emit_param {
  7. wchar_t *output;
  8. int outlen;
  9. const wchar_t *errstr;
  10. int errlen;
  11. int stopped;
  12. };
  13. static void unicode_emit(void *ctx, long int output)
  14. {
  15. struct unicode_emit_param *param = (struct unicode_emit_param *)ctx;
  16. wchar_t outval;
  17. wchar_t const *p;
  18. int outlen;
  19. if (output == ERROR) {
  20. if (param->errstr) {
  21. p = param->errstr;
  22. outlen = param->errlen;
  23. } else {
  24. outval = 0xFFFD; /* U+FFFD REPLACEMENT CHARACTER */
  25. p = &outval;
  26. outlen = 1;
  27. }
  28. } else {
  29. outval = output;
  30. p = &outval;
  31. outlen = 1;
  32. }
  33. if (param->outlen >= outlen) {
  34. while (outlen > 0) {
  35. *param->output++ = *p++;
  36. param->outlen--;
  37. outlen--;
  38. }
  39. } else {
  40. param->stopped = 1;
  41. }
  42. }
  43. int charset_to_unicode(const char **input, int *inlen,
  44. wchar_t *output, int outlen,
  45. int charset, charset_state *state,
  46. const wchar_t *errstr, int errlen)
  47. {
  48. charset_spec const *spec = charset_find_spec(charset);
  49. charset_state localstate;
  50. struct unicode_emit_param param;
  51. param.output = output;
  52. param.outlen = outlen;
  53. param.errstr = errstr;
  54. param.errlen = errlen;
  55. param.stopped = 0;
  56. if (!state) {
  57. localstate.s0 = 0;
  58. } else {
  59. localstate = *state; /* structure copy */
  60. }
  61. while (*inlen > 0) {
  62. int lenbefore = param.output - output;
  63. spec->read(spec, (unsigned char)**input, &localstate,
  64. unicode_emit, &param);
  65. if (param.stopped) {
  66. /*
  67. * The emit function has _tried_ to output some
  68. * characters, but ran up against the end of the
  69. * buffer. Leave immediately, and return what happened
  70. * _before_ attempting to process this character.
  71. */
  72. return lenbefore;
  73. }
  74. if (state)
  75. *state = localstate; /* structure copy */
  76. (*input)++;
  77. (*inlen)--;
  78. }
  79. return param.output - output;
  80. }