blob: 19f910c60a9c43348923b47e97137c2738ba7658 [file] [log] [blame]
Hye-Shik Chang3e2a3062004-01-17 14:29:29 +00001/*
2 * _hz.c: the HZ codec (RFC1843)
3 *
4 * Written by Hye-Shik Chang <perky@FreeBSD.org>
5 * $CJKCodecs: _hz.c,v 1.2 2003/12/31 05:46:55 perky Exp $
6 */
7
8#include "codeccommon.h"
9
10ENCMAP(gbcommon)
11DECMAP(gb2312)
12
13#define HAVE_ENCODER_INIT
14ENCODER_INIT(hz)
15{
16 state->i = 0;
17 return 0;
18}
19
20#define HAVE_ENCODER_RESET
21ENCODER_RESET(hz)
22{
23 if (state->i != 0) {
24 WRITE2('~', '}')
25 state->i = 0;
26 NEXT_OUT(2)
27 }
28 return 0;
29}
30
31ENCODER(hz)
32{
33 while (inleft > 0) {
34 Py_UNICODE c = IN1;
35 DBCHAR code;
36
37 if (c < 0x80) {
38 if (state->i == 0) {
Hye-Shik Changd210a5b2004-01-23 14:36:17 +000039 WRITE1((unsigned char)c)
Hye-Shik Chang3e2a3062004-01-17 14:29:29 +000040 NEXT(1, 1)
41 } else {
Hye-Shik Changd210a5b2004-01-23 14:36:17 +000042 WRITE3('~', '}', (unsigned char)c)
Hye-Shik Chang3e2a3062004-01-17 14:29:29 +000043 NEXT(1, 3)
44 state->i = 0;
45 }
46 continue;
47 }
48
49 UCS4INVALID(c)
50
51 TRYMAP_ENC(gbcommon, code, c);
52 else return 1;
53
54 if (code & 0x8000) /* MSB set: GBK */
55 return 1;
56
57 if (state->i == 0) {
58 WRITE4('~', '{', code >> 8, code & 0xff)
59 NEXT(1, 4)
60 state->i = 1;
61 } else {
62 WRITE2(code >> 8, code & 0xff)
63 NEXT(1, 2)
64 }
65 }
66
67 return 0;
68}
69
70#define HAVE_DECODER_INIT
71DECODER_INIT(hz)
72{
73 state->i = 0;
74 return 0;
75}
76
77#define HAVE_DECODER_RESET
78DECODER_RESET(hz)
79{
80 state->i = 0;
81 return 0;
82}
83
84DECODER(hz)
85{
86 while (inleft > 0) {
87 unsigned char c = IN1;
88
89 if (c == '~') {
90 unsigned char c2 = IN2;
91
92 RESERVE_INBUF(2)
93 if (c2 == '~') {
94 WRITE1('~')
95 NEXT(2, 1)
96 continue;
97 } else if (c2 == '{' && state->i == 0)
98 state->i = 1; /* set GB */
99 else if (c2 == '}' && state->i == 1)
100 state->i = 0; /* set ASCII */
101 else if (c2 == '\n')
102 ; /* line-continuation */
103 else
104 return 2;
105 NEXT(2, 0);
106 continue;
107 }
108
109 if (c & 0x80)
110 return 1;
111
112 if (state->i == 0) { /* ASCII mode */
113 WRITE1(c)
114 NEXT(1, 1)
115 } else { /* GB mode */
116 RESERVE_INBUF(2)
117 RESERVE_OUTBUF(1)
118 TRYMAP_DEC(gb2312, **outbuf, c, IN2) {
119 NEXT(2, 1)
120 } else
121 return 2;
122 }
123 }
124
125 return 0;
126}
127
128#include "codecentry.h"
129BEGIN_CODEC_REGISTRY(hz)
130 MAPOPEN(zh_CN)
131 IMPORTMAP_DEC(gb2312)
132 IMPORTMAP_ENC(gbcommon)
133 MAPCLOSE()
134END_CODEC_REGISTRY(hz)