1*0Sstevel@tonic-gate // Copyright (c) 1994 James Clark
2*0Sstevel@tonic-gate // See the file COPYING for copying permission.
3*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
4*0Sstevel@tonic-gate
5*0Sstevel@tonic-gate #include "splib.h"
6*0Sstevel@tonic-gate
7*0Sstevel@tonic-gate #ifdef SP_MULTI_BYTE
8*0Sstevel@tonic-gate
9*0Sstevel@tonic-gate #include "EUCJPCodingSystem.h"
10*0Sstevel@tonic-gate
11*0Sstevel@tonic-gate #ifdef SP_NAMESPACE
12*0Sstevel@tonic-gate namespace SP_NAMESPACE {
13*0Sstevel@tonic-gate #endif
14*0Sstevel@tonic-gate
15*0Sstevel@tonic-gate class EUCJPDecoder : public Decoder {
16*0Sstevel@tonic-gate public:
EUCJPDecoder()17*0Sstevel@tonic-gate EUCJPDecoder() { }
18*0Sstevel@tonic-gate size_t decode(Char *, const char *, size_t, const char **);
19*0Sstevel@tonic-gate private:
20*0Sstevel@tonic-gate };
21*0Sstevel@tonic-gate
22*0Sstevel@tonic-gate class EUCJPEncoder : public Encoder {
23*0Sstevel@tonic-gate public:
EUCJPEncoder()24*0Sstevel@tonic-gate EUCJPEncoder() { }
25*0Sstevel@tonic-gate void output(const Char *, size_t, OutputByteStream *);
output(Char * tmp_char,size_t tmp_size_t,OutputByteStream * tmp_obs)26*0Sstevel@tonic-gate void output(Char *tmp_char, size_t tmp_size_t, OutputByteStream *tmp_obs) {
27*0Sstevel@tonic-gate output((const Char *)tmp_char, (size_t) tmp_size_t, (OutputByteStream *)tmp_obs);
28*0Sstevel@tonic-gate }
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gate };
31*0Sstevel@tonic-gate
makeDecoder() const32*0Sstevel@tonic-gate Decoder *EUCJPCodingSystem::makeDecoder() const
33*0Sstevel@tonic-gate {
34*0Sstevel@tonic-gate return new EUCJPDecoder;
35*0Sstevel@tonic-gate }
36*0Sstevel@tonic-gate
makeEncoder() const37*0Sstevel@tonic-gate Encoder *EUCJPCodingSystem::makeEncoder() const
38*0Sstevel@tonic-gate {
39*0Sstevel@tonic-gate return new EUCJPEncoder;
40*0Sstevel@tonic-gate }
41*0Sstevel@tonic-gate
decode(Char * to,const char * s,size_t slen,const char ** rest)42*0Sstevel@tonic-gate size_t EUCJPDecoder::decode(Char *to, const char *s,
43*0Sstevel@tonic-gate size_t slen, const char **rest)
44*0Sstevel@tonic-gate {
45*0Sstevel@tonic-gate Char *start = to;
46*0Sstevel@tonic-gate const unsigned char *us = (const unsigned char *)s;
47*0Sstevel@tonic-gate while (slen > 0) {
48*0Sstevel@tonic-gate if (!(*us & 0x80)) {
49*0Sstevel@tonic-gate // G0
50*0Sstevel@tonic-gate *to++ = *us++;
51*0Sstevel@tonic-gate slen--;
52*0Sstevel@tonic-gate }
53*0Sstevel@tonic-gate else if (*us == 0x8e) {
54*0Sstevel@tonic-gate // G2
55*0Sstevel@tonic-gate if (slen < 2)
56*0Sstevel@tonic-gate break;
57*0Sstevel@tonic-gate slen -= 2;
58*0Sstevel@tonic-gate ++us;
59*0Sstevel@tonic-gate *to++ = *us++ | 0x80;
60*0Sstevel@tonic-gate }
61*0Sstevel@tonic-gate else if (*us == 0x8f) {
62*0Sstevel@tonic-gate // G3
63*0Sstevel@tonic-gate if (slen < 3)
64*0Sstevel@tonic-gate break;
65*0Sstevel@tonic-gate slen -= 3;
66*0Sstevel@tonic-gate ++us;
67*0Sstevel@tonic-gate unsigned short n = (*us++ | 0x80) << 8;
68*0Sstevel@tonic-gate n |= (*us++ & ~0x80);
69*0Sstevel@tonic-gate *to++ = n;
70*0Sstevel@tonic-gate }
71*0Sstevel@tonic-gate else {
72*0Sstevel@tonic-gate // G1
73*0Sstevel@tonic-gate if (slen < 2)
74*0Sstevel@tonic-gate break;
75*0Sstevel@tonic-gate slen -= 2;
76*0Sstevel@tonic-gate unsigned short n = *us++ << 8;
77*0Sstevel@tonic-gate n |= (*us++ | 0x80);
78*0Sstevel@tonic-gate *to++ = n;
79*0Sstevel@tonic-gate }
80*0Sstevel@tonic-gate }
81*0Sstevel@tonic-gate *rest = (const char *)us;
82*0Sstevel@tonic-gate return to - start;
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate
output(const Char * s,size_t n,OutputByteStream * sb)86*0Sstevel@tonic-gate void EUCJPEncoder::output(const Char *s, size_t n, OutputByteStream *sb)
87*0Sstevel@tonic-gate {
88*0Sstevel@tonic-gate for (; n > 0; s++, n--) {
89*0Sstevel@tonic-gate Char c = *s;
90*0Sstevel@tonic-gate unsigned short mask = (unsigned short)(c & 0x8080);
91*0Sstevel@tonic-gate if (mask == 0)
92*0Sstevel@tonic-gate sb->sputc((unsigned char)(c & 0xff));
93*0Sstevel@tonic-gate else if (mask == 0x8080) {
94*0Sstevel@tonic-gate sb->sputc((unsigned char)((c >> 8) & 0xff));
95*0Sstevel@tonic-gate sb->sputc((unsigned char)(c & 0xff));
96*0Sstevel@tonic-gate }
97*0Sstevel@tonic-gate else if (mask == 0x0080) {
98*0Sstevel@tonic-gate sb->sputc((unsigned char)0x8e);
99*0Sstevel@tonic-gate sb->sputc((unsigned char)(c & 0xff));
100*0Sstevel@tonic-gate }
101*0Sstevel@tonic-gate else {
102*0Sstevel@tonic-gate // mask == 0x8000
103*0Sstevel@tonic-gate sb->sputc((unsigned char)0x8f);
104*0Sstevel@tonic-gate sb->sputc((unsigned char)((c >> 8) & 0xff));
105*0Sstevel@tonic-gate sb->sputc((unsigned char)(c & 0x7f));
106*0Sstevel@tonic-gate }
107*0Sstevel@tonic-gate }
108*0Sstevel@tonic-gate }
109*0Sstevel@tonic-gate
110*0Sstevel@tonic-gate #ifdef SP_NAMESPACE
111*0Sstevel@tonic-gate }
112*0Sstevel@tonic-gate #endif
113*0Sstevel@tonic-gate
114*0Sstevel@tonic-gate #else /* not SP_MULTI_BYTE */
115*0Sstevel@tonic-gate
116*0Sstevel@tonic-gate #ifndef __GNUG__
117*0Sstevel@tonic-gate static char non_empty_translation_unit; // sigh
118*0Sstevel@tonic-gate #endif
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gate #endif /* not SP_MULTI_BYTE */
121