github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/text/width/transform.go (about) 1 // Copyright 2015 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 width 6 7 import ( 8 "unicode/utf8" 9 10 "golang.org/x/text/transform" 11 ) 12 13 type foldTransform struct { 14 transform.NopResetter 15 } 16 17 func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 18 for nSrc < len(src) { 19 if src[nSrc] < utf8.RuneSelf { 20 // ASCII fast path. 21 start, end := nSrc, len(src) 22 if d := len(dst) - nDst; d < end-start { 23 end = nSrc + d 24 } 25 for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ { 26 } 27 nDst += copy(dst[nDst:], src[start:nSrc]) 28 if nDst == len(dst) && nSrc < len(src) && src[nSrc] < utf8.RuneSelf { 29 return nDst, nSrc, transform.ErrShortDst 30 } 31 continue 32 } 33 v, size := trie.lookup(src[nSrc:]) 34 if size == 0 { // incomplete UTF-8 encoding 35 if !atEOF { 36 return nDst, nSrc, transform.ErrShortSrc 37 } 38 size = 1 // gobble 1 byte 39 } 40 if elem(v)&tagNeedsFold == 0 { 41 if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { 42 return nDst, nSrc, transform.ErrShortDst 43 } 44 nDst += size 45 } else { 46 data := inverseData[byte(v)] 47 if len(dst)-nDst < int(data[0]) { 48 return nDst, nSrc, transform.ErrShortDst 49 } 50 i := 1 51 for end := int(data[0]); i < end; i++ { 52 dst[nDst] = data[i] 53 nDst++ 54 } 55 dst[nDst] = data[i] ^ src[nSrc+size-1] 56 nDst++ 57 } 58 nSrc += size 59 } 60 return nDst, nSrc, nil 61 } 62 63 type narrowTransform struct { 64 transform.NopResetter 65 } 66 67 func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 68 for nSrc < len(src) { 69 if src[nSrc] < utf8.RuneSelf { 70 // ASCII fast path. 71 start, end := nSrc, len(src) 72 if d := len(dst) - nDst; d < end-start { 73 end = nSrc + d 74 } 75 for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ { 76 } 77 nDst += copy(dst[nDst:], src[start:nSrc]) 78 if nDst == len(dst) && nSrc < len(src) && src[nSrc] < utf8.RuneSelf { 79 return nDst, nSrc, transform.ErrShortDst 80 } 81 continue 82 } 83 v, size := trie.lookup(src[nSrc:]) 84 if size == 0 { // incomplete UTF-8 encoding 85 if !atEOF { 86 return nDst, nSrc, transform.ErrShortSrc 87 } 88 size = 1 // gobble 1 byte 89 } 90 if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous { 91 if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { 92 return nDst, nSrc, transform.ErrShortDst 93 } 94 nDst += size 95 } else { 96 data := inverseData[byte(v)] 97 if len(dst)-nDst < int(data[0]) { 98 return nDst, nSrc, transform.ErrShortDst 99 } 100 i := 1 101 for end := int(data[0]); i < end; i++ { 102 dst[nDst] = data[i] 103 nDst++ 104 } 105 dst[nDst] = data[i] ^ src[nSrc+size-1] 106 nDst++ 107 } 108 nSrc += size 109 } 110 return nDst, nSrc, nil 111 } 112 113 type wideTransform struct { 114 transform.NopResetter 115 } 116 117 func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 118 for nSrc < len(src) { 119 // TODO: Consider ASCII fast path. Special-casing ASCII handling can 120 // reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably 121 // not enough to warrant the extra code and complexity. 122 v, size := trie.lookup(src[nSrc:]) 123 if size == 0 { // incomplete UTF-8 encoding 124 if !atEOF { 125 return nDst, nSrc, transform.ErrShortSrc 126 } 127 size = 1 // gobble 1 byte 128 } 129 if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow { 130 if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { 131 return nDst, nSrc, transform.ErrShortDst 132 } 133 nDst += size 134 } else { 135 data := inverseData[byte(v)] 136 if len(dst)-nDst < int(data[0]) { 137 return nDst, nSrc, transform.ErrShortDst 138 } 139 i := 1 140 for end := int(data[0]); i < end; i++ { 141 dst[nDst] = data[i] 142 nDst++ 143 } 144 dst[nDst] = data[i] ^ src[nSrc+size-1] 145 nDst++ 146 } 147 nSrc += size 148 } 149 return nDst, nSrc, nil 150 }