mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 13:50:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			240 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2015 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package width
 | |
| 
 | |
| import (
 | |
| 	"unicode/utf8"
 | |
| 
 | |
| 	"golang.org/x/text/transform"
 | |
| )
 | |
| 
 | |
| type foldTransform struct {
 | |
| 	transform.NopResetter
 | |
| }
 | |
| 
 | |
| func (foldTransform) Span(src []byte, atEOF bool) (n int, err error) {
 | |
| 	for n < len(src) {
 | |
| 		if src[n] < utf8.RuneSelf {
 | |
| 			// ASCII fast path.
 | |
| 			for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
 | |
| 			}
 | |
| 			continue
 | |
| 		}
 | |
| 		v, size := trie.lookup(src[n:])
 | |
| 		if size == 0 { // incomplete UTF-8 encoding
 | |
| 			if !atEOF {
 | |
| 				err = transform.ErrShortSrc
 | |
| 			} else {
 | |
| 				n = len(src)
 | |
| 			}
 | |
| 			break
 | |
| 		}
 | |
| 		if elem(v)&tagNeedsFold != 0 {
 | |
| 			err = transform.ErrEndOfSpan
 | |
| 			break
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return n, err
 | |
| }
 | |
| 
 | |
| func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 | |
| 	for nSrc < len(src) {
 | |
| 		if src[nSrc] < utf8.RuneSelf {
 | |
| 			// ASCII fast path.
 | |
| 			start, end := nSrc, len(src)
 | |
| 			if d := len(dst) - nDst; d < end-start {
 | |
| 				end = nSrc + d
 | |
| 			}
 | |
| 			for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ {
 | |
| 			}
 | |
| 			n := copy(dst[nDst:], src[start:nSrc])
 | |
| 			if nDst += n; nDst == len(dst) {
 | |
| 				nSrc = start + n
 | |
| 				if nSrc == len(src) {
 | |
| 					return nDst, nSrc, nil
 | |
| 				}
 | |
| 				if src[nSrc] < utf8.RuneSelf {
 | |
| 					return nDst, nSrc, transform.ErrShortDst
 | |
| 				}
 | |
| 			}
 | |
| 			continue
 | |
| 		}
 | |
| 		v, size := trie.lookup(src[nSrc:])
 | |
| 		if size == 0 { // incomplete UTF-8 encoding
 | |
| 			if !atEOF {
 | |
| 				return nDst, nSrc, transform.ErrShortSrc
 | |
| 			}
 | |
| 			size = 1 // gobble 1 byte
 | |
| 		}
 | |
| 		if elem(v)&tagNeedsFold == 0 {
 | |
| 			if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
 | |
| 				return nDst, nSrc, transform.ErrShortDst
 | |
| 			}
 | |
| 			nDst += size
 | |
| 		} else {
 | |
| 			data := inverseData[byte(v)]
 | |
| 			if len(dst)-nDst < int(data[0]) {
 | |
| 				return nDst, nSrc, transform.ErrShortDst
 | |
| 			}
 | |
| 			i := 1
 | |
| 			for end := int(data[0]); i < end; i++ {
 | |
| 				dst[nDst] = data[i]
 | |
| 				nDst++
 | |
| 			}
 | |
| 			dst[nDst] = data[i] ^ src[nSrc+size-1]
 | |
| 			nDst++
 | |
| 		}
 | |
| 		nSrc += size
 | |
| 	}
 | |
| 	return nDst, nSrc, nil
 | |
| }
 | |
| 
 | |
| type narrowTransform struct {
 | |
| 	transform.NopResetter
 | |
| }
 | |
| 
 | |
| func (narrowTransform) Span(src []byte, atEOF bool) (n int, err error) {
 | |
| 	for n < len(src) {
 | |
| 		if src[n] < utf8.RuneSelf {
 | |
| 			// ASCII fast path.
 | |
| 			for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
 | |
| 			}
 | |
| 			continue
 | |
| 		}
 | |
| 		v, size := trie.lookup(src[n:])
 | |
| 		if size == 0 { // incomplete UTF-8 encoding
 | |
| 			if !atEOF {
 | |
| 				err = transform.ErrShortSrc
 | |
| 			} else {
 | |
| 				n = len(src)
 | |
| 			}
 | |
| 			break
 | |
| 		}
 | |
| 		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
 | |
| 		} else {
 | |
| 			err = transform.ErrEndOfSpan
 | |
| 			break
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return n, err
 | |
| }
 | |
| 
 | |
| func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 | |
| 	for nSrc < len(src) {
 | |
| 		if src[nSrc] < utf8.RuneSelf {
 | |
| 			// ASCII fast path.
 | |
| 			start, end := nSrc, len(src)
 | |
| 			if d := len(dst) - nDst; d < end-start {
 | |
| 				end = nSrc + d
 | |
| 			}
 | |
| 			for nSrc++; nSrc < end && src[nSrc] < utf8.RuneSelf; nSrc++ {
 | |
| 			}
 | |
| 			n := copy(dst[nDst:], src[start:nSrc])
 | |
| 			if nDst += n; nDst == len(dst) {
 | |
| 				nSrc = start + n
 | |
| 				if nSrc == len(src) {
 | |
| 					return nDst, nSrc, nil
 | |
| 				}
 | |
| 				if src[nSrc] < utf8.RuneSelf {
 | |
| 					return nDst, nSrc, transform.ErrShortDst
 | |
| 				}
 | |
| 			}
 | |
| 			continue
 | |
| 		}
 | |
| 		v, size := trie.lookup(src[nSrc:])
 | |
| 		if size == 0 { // incomplete UTF-8 encoding
 | |
| 			if !atEOF {
 | |
| 				return nDst, nSrc, transform.ErrShortSrc
 | |
| 			}
 | |
| 			size = 1 // gobble 1 byte
 | |
| 		}
 | |
| 		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
 | |
| 			if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
 | |
| 				return nDst, nSrc, transform.ErrShortDst
 | |
| 			}
 | |
| 			nDst += size
 | |
| 		} else {
 | |
| 			data := inverseData[byte(v)]
 | |
| 			if len(dst)-nDst < int(data[0]) {
 | |
| 				return nDst, nSrc, transform.ErrShortDst
 | |
| 			}
 | |
| 			i := 1
 | |
| 			for end := int(data[0]); i < end; i++ {
 | |
| 				dst[nDst] = data[i]
 | |
| 				nDst++
 | |
| 			}
 | |
| 			dst[nDst] = data[i] ^ src[nSrc+size-1]
 | |
| 			nDst++
 | |
| 		}
 | |
| 		nSrc += size
 | |
| 	}
 | |
| 	return nDst, nSrc, nil
 | |
| }
 | |
| 
 | |
| type wideTransform struct {
 | |
| 	transform.NopResetter
 | |
| }
 | |
| 
 | |
| func (wideTransform) Span(src []byte, atEOF bool) (n int, err error) {
 | |
| 	for n < len(src) {
 | |
| 		// TODO: Consider ASCII fast path. Special-casing ASCII handling can
 | |
| 		// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
 | |
| 		// not enough to warrant the extra code and complexity.
 | |
| 		v, size := trie.lookup(src[n:])
 | |
| 		if size == 0 { // incomplete UTF-8 encoding
 | |
| 			if !atEOF {
 | |
| 				err = transform.ErrShortSrc
 | |
| 			} else {
 | |
| 				n = len(src)
 | |
| 			}
 | |
| 			break
 | |
| 		}
 | |
| 		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
 | |
| 		} else {
 | |
| 			err = transform.ErrEndOfSpan
 | |
| 			break
 | |
| 		}
 | |
| 		n += size
 | |
| 	}
 | |
| 	return n, err
 | |
| }
 | |
| 
 | |
| func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 | |
| 	for nSrc < len(src) {
 | |
| 		// TODO: Consider ASCII fast path. Special-casing ASCII handling can
 | |
| 		// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
 | |
| 		// not enough to warrant the extra code and complexity.
 | |
| 		v, size := trie.lookup(src[nSrc:])
 | |
| 		if size == 0 { // incomplete UTF-8 encoding
 | |
| 			if !atEOF {
 | |
| 				return nDst, nSrc, transform.ErrShortSrc
 | |
| 			}
 | |
| 			size = 1 // gobble 1 byte
 | |
| 		}
 | |
| 		if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
 | |
| 			if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
 | |
| 				return nDst, nSrc, transform.ErrShortDst
 | |
| 			}
 | |
| 			nDst += size
 | |
| 		} else {
 | |
| 			data := inverseData[byte(v)]
 | |
| 			if len(dst)-nDst < int(data[0]) {
 | |
| 				return nDst, nSrc, transform.ErrShortDst
 | |
| 			}
 | |
| 			i := 1
 | |
| 			for end := int(data[0]); i < end; i++ {
 | |
| 				dst[nDst] = data[i]
 | |
| 				nDst++
 | |
| 			}
 | |
| 			dst[nDst] = data[i] ^ src[nSrc+size-1]
 | |
| 			nDst++
 | |
| 		}
 | |
| 		nSrc += size
 | |
| 	}
 | |
| 	return nDst, nSrc, nil
 | |
| }
 |