~vtuson/scopecreator/twitter-template

« back to all changes in this revision

Viewing changes to src/go/src/code.google.com/p/go.text/encoding/korean/euckr.go

  • Committer: Victor Palau
  • Date: 2015-03-11 14:24:42 UTC
  • Revision ID: vtuson@gmail.com-20150311142442-f2pxp111c8ynv232
public release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
4
 
 
5
package korean
 
6
 
 
7
import (
 
8
        "errors"
 
9
        "unicode/utf8"
 
10
 
 
11
        "code.google.com/p/go.text/encoding"
 
12
        "code.google.com/p/go.text/transform"
 
13
)
 
14
 
 
15
// EUCKR is the EUC-KR encoding, also known as Code Page 949.
 
16
var EUCKR encoding.Encoding = eucKR{}
 
17
 
 
18
type eucKR struct{}
 
19
 
 
20
func (eucKR) NewDecoder() transform.Transformer {
 
21
        return eucKRDecoder{}
 
22
}
 
23
 
 
24
func (eucKR) NewEncoder() transform.Transformer {
 
25
        return eucKREncoder{}
 
26
}
 
27
 
 
28
func (eucKR) String() string {
 
29
        return "EUC-KR"
 
30
}
 
31
 
 
32
var errInvalidEUCKR = errors.New("korean: invalid EUC-KR encoding")
 
33
 
 
34
type eucKRDecoder struct{}
 
35
 
 
36
func (eucKRDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 
37
        r, size := rune(0), 0
 
38
loop:
 
39
        for ; nSrc < len(src); nSrc += size {
 
40
                switch c0 := src[nSrc]; {
 
41
                case c0 < utf8.RuneSelf:
 
42
                        r, size = rune(c0), 1
 
43
 
 
44
                case 0x81 <= c0 && c0 < 0xff:
 
45
                        if nSrc+1 >= len(src) {
 
46
                                err = transform.ErrShortSrc
 
47
                                break loop
 
48
                        }
 
49
                        c1 := src[nSrc+1]
 
50
                        if c0 < 0xc7 {
 
51
                                r = 178 * rune(c0-0x81)
 
52
                                switch {
 
53
                                case 0x41 <= c1 && c1 < 0x5b:
 
54
                                        r += rune(c1) - (0x41 - 0*26)
 
55
                                case 0x61 <= c1 && c1 < 0x7b:
 
56
                                        r += rune(c1) - (0x61 - 1*26)
 
57
                                case 0x81 <= c1 && c1 < 0xff:
 
58
                                        r += rune(c1) - (0x81 - 2*26)
 
59
                                default:
 
60
                                        err = errInvalidEUCKR
 
61
                                        break loop
 
62
                                }
 
63
                        } else if 0xa1 <= c1 && c1 < 0xff {
 
64
                                r = 178*(0xc7-0x81) + rune(c0-0xc7)*94 + rune(c1-0xa1)
 
65
                        } else {
 
66
                                err = errInvalidEUCKR
 
67
                                break loop
 
68
                        }
 
69
                        if int(r) < len(decode) {
 
70
                                r = rune(decode[r])
 
71
                                if r == 0 {
 
72
                                        r = '\ufffd'
 
73
                                }
 
74
                        } else {
 
75
                                r = '\ufffd'
 
76
                        }
 
77
                        size = 2
 
78
 
 
79
                default:
 
80
                        err = errInvalidEUCKR
 
81
                        break loop
 
82
                }
 
83
 
 
84
                if nDst+utf8.RuneLen(r) > len(dst) {
 
85
                        err = transform.ErrShortDst
 
86
                        break loop
 
87
                }
 
88
                nDst += utf8.EncodeRune(dst[nDst:], r)
 
89
        }
 
90
        if atEOF && err == transform.ErrShortSrc {
 
91
                err = errInvalidEUCKR
 
92
        }
 
93
        return nDst, nSrc, err
 
94
}
 
95
 
 
96
type eucKREncoder struct{}
 
97
 
 
98
func (eucKREncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 
99
        r, size := rune(0), 0
 
100
        for ; nSrc < len(src); nSrc += size {
 
101
                r = rune(src[nSrc])
 
102
 
 
103
                // Decode a 1-byte rune.
 
104
                if r < utf8.RuneSelf {
 
105
                        size = 1
 
106
 
 
107
                } else {
 
108
                        // Decode a multi-byte rune.
 
109
                        r, size = utf8.DecodeRune(src[nSrc:])
 
110
                        if size == 1 {
 
111
                                // All valid runes of size 1 (those below utf8.RuneSelf) were
 
112
                                // handled above. We have invalid UTF-8 or we haven't seen the
 
113
                                // full character yet.
 
114
                                if !atEOF && !utf8.FullRune(src[nSrc:]) {
 
115
                                        err = transform.ErrShortSrc
 
116
                                        break
 
117
                                }
 
118
                        }
 
119
 
 
120
                        // func init checks that the switch covers all tables.
 
121
                        switch {
 
122
                        case encode0Low <= r && r < encode0High:
 
123
                                if r = rune(encode0[r-encode0Low]); r != 0 {
 
124
                                        goto write2
 
125
                                }
 
126
                        case encode1Low <= r && r < encode1High:
 
127
                                if r = rune(encode1[r-encode1Low]); r != 0 {
 
128
                                        goto write2
 
129
                                }
 
130
                        case encode2Low <= r && r < encode2High:
 
131
                                if r = rune(encode2[r-encode2Low]); r != 0 {
 
132
                                        goto write2
 
133
                                }
 
134
                        case encode3Low <= r && r < encode3High:
 
135
                                if r = rune(encode3[r-encode3Low]); r != 0 {
 
136
                                        goto write2
 
137
                                }
 
138
                        case encode4Low <= r && r < encode4High:
 
139
                                if r = rune(encode4[r-encode4Low]); r != 0 {
 
140
                                        goto write2
 
141
                                }
 
142
                        case encode5Low <= r && r < encode5High:
 
143
                                if r = rune(encode5[r-encode5Low]); r != 0 {
 
144
                                        goto write2
 
145
                                }
 
146
                        case encode6Low <= r && r < encode6High:
 
147
                                if r = rune(encode6[r-encode6Low]); r != 0 {
 
148
                                        goto write2
 
149
                                }
 
150
                        }
 
151
                        r = encoding.ASCIISub
 
152
                }
 
153
 
 
154
                if nDst >= len(dst) {
 
155
                        err = transform.ErrShortDst
 
156
                        break
 
157
                }
 
158
                dst[nDst] = uint8(r)
 
159
                nDst++
 
160
                continue
 
161
 
 
162
        write2:
 
163
                if nDst+2 > len(dst) {
 
164
                        err = transform.ErrShortDst
 
165
                        break
 
166
                }
 
167
                dst[nDst+0] = uint8(r >> 8)
 
168
                dst[nDst+1] = uint8(r)
 
169
                nDst += 2
 
170
                continue
 
171
        }
 
172
        return nDst, nSrc, err
 
173
}
 
174
 
 
175
func init() {
 
176
        // Check that the hard-coded encode switch covers all tables.
 
177
        if numEncodeTables != 7 {
 
178
                panic("bad numEncodeTables")
 
179
        }
 
180
}