SJISCodingSystem.C 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: SJISCodingSystem.C /main/1 1996/07/29 17:03:20 cde-hp $ */
  24. // Copyright (c) 1994 James Clark
  25. // See the file COPYING for copying permission.
  26. #include "splib.h"
  27. #ifdef SP_MULTI_BYTE
  28. #include "SJISCodingSystem.h"
  29. #if defined(__linux__) || defined(CSRG_BASED) || defined(sun)
  30. #include <iostream>
  31. #else
  32. #include <iostream.h>
  33. #endif
  34. #ifdef SP_NAMESPACE
  35. namespace SP_NAMESPACE {
  36. #endif
  37. class SJISDecoder : public Decoder {
  38. public:
  39. SJISDecoder();
  40. size_t decode(Char *, const char *, size_t, const char **);
  41. private:
  42. };
  43. class SJISEncoder : public Encoder {
  44. public:
  45. SJISEncoder();
  46. void output(const Char *, size_t, streambuf *);
  47. };
  48. Decoder *SJISCodingSystem::makeDecoder() const
  49. {
  50. return new SJISDecoder;
  51. }
  52. Encoder *SJISCodingSystem::makeEncoder() const
  53. {
  54. return new SJISEncoder;
  55. }
  56. SJISDecoder::SJISDecoder()
  57. {
  58. }
  59. size_t SJISDecoder::decode(Char *to, const char *s,
  60. size_t slen, const char **rest)
  61. {
  62. Char *start = to;
  63. while (slen > 0) {
  64. unsigned char c = *(unsigned char *)s;
  65. if (!(c & 0x80)) {
  66. *to++ = c;
  67. s++;
  68. slen--;
  69. }
  70. else if (129 <= c && c <= 159) {
  71. if (slen < 2)
  72. break;
  73. s++;
  74. slen -= 2;
  75. unsigned char c2 = *(unsigned char *)s++;
  76. unsigned short n = ((c - 112) << 9) | c2;
  77. if (64 <= c2 && c2 <= 127)
  78. n -= 31 + (1 << 8);
  79. else if (c2 <= 158)
  80. n -= 32 + (1 << 8);
  81. else if (c2 <= 252)
  82. n -= 126;
  83. else
  84. continue;
  85. n |= 0x8080;
  86. *to++ = n;
  87. }
  88. else if (224 <= c && c <= 239) {
  89. if (slen < 2)
  90. break;
  91. s++;
  92. slen -= 2;
  93. unsigned char c2 = *(unsigned char *)s++;
  94. unsigned short n = ((c - 176) << 9) | c2;
  95. if (64 <= c2 && c2 <= 127)
  96. n -= 31 + (1 << 8);
  97. else if (c2 <= 158)
  98. n -= 32 + (1 << 8);
  99. else if (c2 <= 252)
  100. n -= 126;
  101. else
  102. continue;
  103. n |= 0x8080;
  104. *to++ = n;
  105. }
  106. else if (161 <= c && c <= 223) {
  107. slen--;
  108. s++;
  109. *to++ = c;
  110. }
  111. else {
  112. // 128, 160, 240-255
  113. slen--;
  114. s++;
  115. }
  116. }
  117. *rest = s;
  118. return to - start;
  119. }
  120. SJISEncoder::SJISEncoder()
  121. {
  122. }
  123. // FIXME handle errors from streambuf::sputc
  124. void SJISEncoder::output(const Char *s, size_t n, streambuf *sb)
  125. {
  126. for (; n > 0; s++, n--) {
  127. Char c = *s;
  128. unsigned short mask = (unsigned short)(c & 0x8080);
  129. if (mask == 0)
  130. sb->sputc(char(c & 0xff));
  131. else if (mask == 0x8080) {
  132. unsigned char c1 = (c >> 8) & 0x7f;
  133. unsigned char c2 = c & 0x7f;
  134. char out1;
  135. if (c1 < 33)
  136. out1 = 0;
  137. else if (c1 < 95)
  138. out1 = ((c1 + 1) >> 1) + 112;
  139. else if (c1 < 127)
  140. out1 = ((c1 + 1) >> 1) + 176;
  141. else
  142. out1 = 0;
  143. if (out1) {
  144. char out2;
  145. if (c1 & 1) {
  146. if (c2 < 33)
  147. out2 = 0;
  148. else if (c2 <= 95)
  149. out2 = c2 + 31;
  150. else if (c2 <= 126)
  151. out2 = c2 + 32;
  152. else
  153. out2 = 0;
  154. }
  155. else {
  156. if (33 <= c2 && c2 <= 126)
  157. out2 = c2 + 126;
  158. else
  159. out2 = 0;
  160. }
  161. if (out2) {
  162. sb->sputc(out1);
  163. sb->sputc(out2);
  164. }
  165. else
  166. handleUnencodable(c, sb);
  167. }
  168. else
  169. handleUnencodable(c, sb);
  170. }
  171. else if (mask == 0x0080) {
  172. if (161 <= c && c <= 223)
  173. sb->sputc(char(c & 0xff));
  174. else
  175. handleUnencodable(c, sb);
  176. }
  177. else
  178. handleUnencodable(c, sb);
  179. }
  180. }
  181. #ifdef SP_NAMESPACE
  182. }
  183. #endif
  184. #else /* not SP_MULTI_BYTE */
  185. #ifndef __GNUG__
  186. static char non_empty_translation_unit; // sigh
  187. #endif
  188. #endif /* not SP_MULTI_BYTE */