1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
10 "golang.org/x/text/encoding"
11 "golang.org/x/text/encoding/internal"
12 "golang.org/x/text/encoding/internal/identifier"
13 "golang.org/x/text/transform"
16 // EUCJP is the EUC-JP encoding.
17 var EUCJP encoding.Encoding = &eucJP
19 var eucJP = internal.Encoding{
20 &internal.SimpleEncoding{eucJPDecoder{}, eucJPEncoder{}},
22 identifier.EUCPkdFmtJapanese,
25 type eucJPDecoder struct{ transform.NopResetter }
27 // See https://encoding.spec.whatwg.org/#euc-jp-decoder.
28 func (eucJPDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
31 for ; nSrc < len(src); nSrc += size {
32 switch c0 := src[nSrc]; {
33 case c0 < utf8.RuneSelf:
37 if nSrc+1 >= len(src) {
39 err = transform.ErrShortSrc
42 r, size = utf8.RuneError, 1
48 r, size = utf8.RuneError, 1
50 r, size = utf8.RuneError, 2
55 r, size = rune(c1)+(0xff61-0xa1), 2
58 if nSrc+2 >= len(src) {
60 err = transform.ErrShortSrc
63 r, size = utf8.RuneError, 1
64 if p := nSrc + 1; p < len(src) && 0xa1 <= src[p] && src[p] < 0xfe {
70 if c1 < 0xa1 || 0xfe < c1 {
71 r, size = utf8.RuneError, 1
75 if c2 < 0xa1 || 0xfe < c2 {
76 r, size = utf8.RuneError, 2
79 r, size = utf8.RuneError, 3
80 if i := int(c1-0xa1)*94 + int(c2-0xa1); i < len(jis0212Decode) {
81 r = rune(jis0212Decode[i])
87 case 0xa1 <= c0 && c0 <= 0xfe:
88 if nSrc+1 >= len(src) {
90 err = transform.ErrShortSrc
93 r, size = utf8.RuneError, 1
97 if c1 < 0xa1 || 0xfe < c1 {
98 r, size = utf8.RuneError, 1
101 r, size = utf8.RuneError, 2
102 if i := int(c0-0xa1)*94 + int(c1-0xa1); i < len(jis0208Decode) {
103 r = rune(jis0208Decode[i])
110 r, size = utf8.RuneError, 1
113 if nDst+utf8.RuneLen(r) > len(dst) {
114 err = transform.ErrShortDst
117 nDst += utf8.EncodeRune(dst[nDst:], r)
119 return nDst, nSrc, err
122 type eucJPEncoder struct{ transform.NopResetter }
124 func (eucJPEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
125 r, size := rune(0), 0
126 for ; nSrc < len(src); nSrc += size {
129 // Decode a 1-byte rune.
130 if r < utf8.RuneSelf {
134 // Decode a multi-byte rune.
135 r, size = utf8.DecodeRune(src[nSrc:])
137 // All valid runes of size 1 (those below utf8.RuneSelf) were
138 // handled above. We have invalid UTF-8 or we haven't seen the
139 // full character yet.
140 if !atEOF && !utf8.FullRune(src[nSrc:]) {
141 err = transform.ErrShortSrc
146 // func init checks that the switch covers all tables.
148 case encode0Low <= r && r < encode0High:
149 if r = rune(encode0[r-encode0Low]); r != 0 {
152 case encode1Low <= r && r < encode1High:
153 if r = rune(encode1[r-encode1Low]); r != 0 {
156 case encode2Low <= r && r < encode2High:
157 if r = rune(encode2[r-encode2Low]); r != 0 {
160 case encode3Low <= r && r < encode3High:
161 if r = rune(encode3[r-encode3Low]); r != 0 {
164 case encode4Low <= r && r < encode4High:
165 if r = rune(encode4[r-encode4Low]); r != 0 {
168 case encode5Low <= r && r < encode5High:
169 if 0xff61 <= r && r < 0xffa0 {
172 if r = rune(encode5[r-encode5Low]); r != 0 {
176 err = internal.ErrASCIIReplacement
180 if nDst >= len(dst) {
181 err = transform.ErrShortDst
189 if r>>tableShift == jis0208 {
190 if nDst+2 > len(dst) {
191 err = transform.ErrShortDst
195 if nDst+3 > len(dst) {
196 err = transform.ErrShortDst
202 dst[nDst+0] = 0xa1 + uint8(r>>codeShift)&codeMask
203 dst[nDst+1] = 0xa1 + uint8(r)&codeMask
208 if nDst+2 > len(dst) {
209 err = transform.ErrShortDst
213 dst[nDst+1] = uint8(r - (0xff61 - 0xa1))
217 return nDst, nSrc, err
221 // Check that the hard-coded encode switch covers all tables.
222 if numEncodeTables != 6 {
223 panic("bad numEncodeTables")