| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | package mahoniaimport (	"unicode/utf8")// converters for ISO-2022-JP encodingconst esc = 27func init() {	type jpEncoding int	const (		ascii jpEncoding = iota		jisX0201Roman		jisX0208	)	RegisterCharset(&Charset{		Name: "ISO-2022-JP",		NewDecoder: func() Decoder {			encoding := ascii			return func(p []byte) (c rune, size int, status Status) {				if len(p) == 0 {					return 0, 0, NO_ROOM				}				b := p[0]				if b == esc {					if len(p) < 3 {						return 0, 0, NO_ROOM					}					switch p[1] {					case '(':						switch p[2] {						case 'B':							encoding = ascii							return 0, 3, STATE_ONLY						case 'J':							encoding = jisX0201Roman							return 0, 3, STATE_ONLY						}					case '$':						switch p[2] {						case '@', 'B':							encoding = jisX0208							return 0, 3, STATE_ONLY						}					}				}				switch encoding {				case ascii:					if b > 127 {						return utf8.RuneError, 1, INVALID_CHAR					}					return rune(b), 1, SUCCESS				case jisX0201Roman:					if b > 127 {						return utf8.RuneError, 1, INVALID_CHAR					}					switch b {					case '\\':						return 0xA5, 1, SUCCESS					case '~':						return 0x203E, 1, SUCCESS					}					return rune(b), 1, SUCCESS				case jisX0208:					return jis0208Table.DecodeLow(p)				}				panic("unreachable")			}		},		NewEncoder: func() Encoder {			jis0208Table.Reverse()			encoding := ascii			return func(p []byte, c rune) (size int, status Status) {				if len(p) == 0 {					return 0, NO_ROOM				}				if c < 128 {					if encoding != ascii {						if len(p) < 4 {							return 0, NO_ROOM						}						p[0], p[1], p[2] = esc, '(', 'B'						p[3] = byte(c)						encoding = ascii						return 4, SUCCESS					}					p[0] = byte(c)					return 1, SUCCESS				}				if c > 65535 {					return 0, INVALID_CHAR				}				jis := jis0208Table.FromUnicode[c]				if jis == [2]byte{0, 0} && c != rune(jis0208Table.Data[0][0]) {					return 0, INVALID_CHAR				}				if encoding != jisX0208 {					if len(p) < 3 {						return 0, NO_ROOM					}					p[0], p[1], p[2] = esc, '$', 'B'					encoding = jisX0208					return 3, STATE_ONLY				}				p[0] = jis[0] + 0x21				p[1] = jis[1] + 0x21				return 2, SUCCESS			}		},	})}
 |