natOutput_EUCJIS.cc 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* Copyright (C) 1999 Free Software Foundation
  2. This file is part of libgcj.
  3. This software is copyrighted work licensed under the terms of the
  4. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  5. details. */
  6. #include <config.h>
  7. #include <gcj/cni.h>
  8. #include <gnu/gcj/convert/Output_EUCJIS.h>
  9. /* A trie structure to map unicode values to JIS codes.
  10. * code == -1: the character is undefined.
  11. * code >= 0 && code < 128: JIS-Roman - mostly Ascii.
  12. * code >= 128 && code < 256: Half-width Katakana.
  13. * code >= 256 && code < 0x8000: JIS X 0208:1997.
  14. * code >= 0x8000 && code < 0xFFFF: JIX X 0212-1990.
  15. */
  16. extern unsigned short Unicode_to_JIS[];
  17. int
  18. trie_lookup (unsigned short *trie, unsigned short key)
  19. {
  20. unsigned short branch = trie[(key >> 12) & 0xf];
  21. if (branch == 0)
  22. return -1;
  23. branch = trie[branch + ((key >> 8) & 0xf)];
  24. if (branch == 0)
  25. return -1;
  26. branch = trie[branch + ((key >> 4) & 0xf)];
  27. if (branch == 0)
  28. return -1;
  29. return trie[branch + (key & 0xf)];
  30. }
  31. static jint
  32. convert_TO_EUCJIS (gnu::gcj::convert::Output_EUCJIS *encoder,
  33. jchar *ptr, jint inlength)
  34. {
  35. int orig_inlength = inlength;
  36. jint outbuf_length = encoder->buf->length;
  37. for (;;)
  38. {
  39. if (encoder->count >= outbuf_length)
  40. break;
  41. if (encoder->pending1 >= 0)
  42. {
  43. elements(encoder->buf)[encoder->count++] = encoder->pending1;
  44. encoder->pending1 = encoder->pending2;
  45. encoder->pending2 = -1;
  46. continue;
  47. }
  48. if (inlength == 0)
  49. break;
  50. jchar ch = *ptr++;
  51. inlength--;
  52. unsigned short val = trie_lookup(Unicode_to_JIS, ch);
  53. if (val < 0x80)
  54. {
  55. if (val == 0xffff)
  56. val = '?';
  57. }
  58. else if (val <= 0xFF)
  59. {
  60. encoder->pending1 = val;
  61. encoder->pending2 = -1;
  62. val = 0x8e;
  63. }
  64. else if (val < 0x8000)
  65. {
  66. val |= 0x8080;
  67. encoder->pending1 = val & 0xff;
  68. val = val >> 8;
  69. encoder->pending2 = -1;
  70. }
  71. else
  72. {
  73. val |= 0x8080;
  74. encoder->pending1 = val >> 8;
  75. encoder->pending2 = val & 0xff;
  76. val = 0x8f;
  77. }
  78. elements(encoder->buf)[encoder->count++] = val;
  79. }
  80. return orig_inlength - inlength;
  81. }
  82. jint
  83. gnu::gcj::convert::Output_EUCJIS::write (jcharArray inbuffer,
  84. jint inpos, jint inlength)
  85. {
  86. return convert_TO_EUCJIS(this, &elements(inbuffer)[inpos], inlength);
  87. }
  88. jint
  89. gnu::gcj::convert::Output_EUCJIS::write (jstring str, jint inpos,
  90. jint inlength, jcharArray)
  91. {
  92. return convert_TO_EUCJIS(this, _Jv_GetStringChars(str)+inpos, inlength);
  93. }