github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/mahonia/convert_string.go (about) 1 package mahonia 2 3 import ( 4 "unicode/utf8" 5 ) 6 7 // ConvertString converts a string from UTF-8 to e's encoding. 8 func (e Encoder) ConvertString(s string) string { 9 dest := make([]byte, len(s)+10) 10 destPos := 0 11 12 for _, rune := range s { 13 retry: 14 size, status := e(dest[destPos:], rune) 15 16 if status == NO_ROOM { 17 newDest := make([]byte, len(dest)*2) 18 copy(newDest, dest) 19 dest = newDest 20 goto retry 21 } 22 23 if status == STATE_ONLY { 24 destPos += size 25 goto retry 26 } 27 28 destPos += size 29 } 30 31 return string(dest[:destPos]) 32 } 33 34 // ConvertString converts a string from d's encoding to UTF-8. 35 func (d Decoder) ConvertString(s string) string { 36 bytes := []byte(s) 37 runes := make([]rune, len(s)) 38 destPos := 0 39 40 for len(bytes) > 0 { 41 c, size, status := d(bytes) 42 43 if status == STATE_ONLY { 44 bytes = bytes[size:] 45 continue 46 } 47 48 if status == NO_ROOM { 49 c = 0xfffd 50 size = len(bytes) 51 status = INVALID_CHAR 52 } 53 54 bytes = bytes[size:] 55 runes[destPos] = c 56 destPos++ 57 } 58 59 return string(runes[:destPos]) 60 } 61 62 // ConvertStringOK converts a string from UTF-8 to e's encoding. It also 63 // returns a boolean indicating whether every character was converted 64 // successfully. 65 func (e Encoder) ConvertStringOK(s string) (result string, ok bool) { 66 dest := make([]byte, len(s)+10) 67 destPos := 0 68 ok = true 69 70 for i, r := range s { 71 // The following test is copied from utf8.ValidString. 72 if r == utf8.RuneError && ok { 73 _, size := utf8.DecodeRuneInString(s[i:]) 74 if size == 1 { 75 ok = false 76 } 77 } 78 79 retry: 80 size, status := e(dest[destPos:], r) 81 82 switch status { 83 case NO_ROOM: 84 newDest := make([]byte, len(dest)*2) 85 copy(newDest, dest) 86 dest = newDest 87 goto retry 88 89 case STATE_ONLY: 90 destPos += size 91 goto retry 92 93 case INVALID_CHAR: 94 ok = false 95 } 96 97 destPos += size 98 } 99 100 return string(dest[:destPos]), ok 101 } 102 103 // ConvertStringOK converts a string from d's encoding to UTF-8. 104 // It also returns a boolean indicating whether every character was converted 105 // successfully. 106 func (d Decoder) ConvertStringOK(s string) (result string, ok bool) { 107 bytes := []byte(s) 108 runes := make([]rune, len(s)) 109 destPos := 0 110 ok = true 111 112 for len(bytes) > 0 { 113 c, size, status := d(bytes) 114 115 switch status { 116 case STATE_ONLY: 117 bytes = bytes[size:] 118 continue 119 120 case NO_ROOM: 121 c = 0xfffd 122 size = len(bytes) 123 ok = false 124 125 case INVALID_CHAR: 126 ok = false 127 } 128 129 bytes = bytes[size:] 130 runes[destPos] = c 131 destPos++ 132 } 133 134 return string(runes[:destPos]), ok 135 }