github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/mahonia/iso2022jp.go (about) 1 package mahonia 2 3 import ( 4 "unicode/utf8" 5 ) 6 7 // converters for ISO-2022-JP encoding 8 9 const esc = 27 10 11 func init() { 12 type jpEncoding int 13 const ( 14 ascii jpEncoding = iota 15 jisX0201Roman 16 jisX0208 17 ) 18 19 RegisterCharset(&Charset{ 20 Name: "ISO-2022-JP", 21 NewDecoder: func() Decoder { 22 encoding := ascii 23 return func(p []byte) (c rune, size int, status Status) { 24 if len(p) == 0 { 25 return 0, 0, NO_ROOM 26 } 27 28 b := p[0] 29 if b == esc { 30 if len(p) < 3 { 31 return 0, 0, NO_ROOM 32 } 33 switch p[1] { 34 case '(': 35 switch p[2] { 36 case 'B': 37 encoding = ascii 38 return 0, 3, STATE_ONLY 39 40 case 'J': 41 encoding = jisX0201Roman 42 return 0, 3, STATE_ONLY 43 } 44 45 case '$': 46 switch p[2] { 47 case '@', 'B': 48 encoding = jisX0208 49 return 0, 3, STATE_ONLY 50 } 51 } 52 } 53 54 switch encoding { 55 case ascii: 56 if b > 127 { 57 return utf8.RuneError, 1, INVALID_CHAR 58 } 59 return rune(b), 1, SUCCESS 60 61 case jisX0201Roman: 62 if b > 127 { 63 return utf8.RuneError, 1, INVALID_CHAR 64 } 65 switch b { 66 case '\\': 67 return 0xA5, 1, SUCCESS 68 case '~': 69 return 0x203E, 1, SUCCESS 70 } 71 return rune(b), 1, SUCCESS 72 73 case jisX0208: 74 return jis0208Table.DecodeLow(p) 75 } 76 panic("unreachable") 77 } 78 }, 79 NewEncoder: func() Encoder { 80 jis0208Table.Reverse() 81 encoding := ascii 82 return func(p []byte, c rune) (size int, status Status) { 83 if len(p) == 0 { 84 return 0, NO_ROOM 85 } 86 87 if c < 128 { 88 if encoding != ascii { 89 if len(p) < 4 { 90 return 0, NO_ROOM 91 } 92 p[0], p[1], p[2] = esc, '(', 'B' 93 p[3] = byte(c) 94 encoding = ascii 95 return 4, SUCCESS 96 } 97 p[0] = byte(c) 98 return 1, SUCCESS 99 } 100 101 if c > 65535 { 102 return 0, INVALID_CHAR 103 } 104 jis := jis0208Table.FromUnicode[c] 105 if jis == [2]byte{0, 0} && c != rune(jis0208Table.Data[0][0]) { 106 return 0, INVALID_CHAR 107 } 108 109 if encoding != jisX0208 { 110 if len(p) < 3 { 111 return 0, NO_ROOM 112 } 113 p[0], p[1], p[2] = esc, '$', 'B' 114 encoding = jisX0208 115 return 3, STATE_ONLY 116 } 117 118 p[0] = jis[0] + 0x21 119 p[1] = jis[1] + 0x21 120 return 2, SUCCESS 121 } 122 }, 123 }) 124 }