mirror of
				https://gitea.com/gitea/tea.git
				synced 2025-10-31 09:15:26 +01:00 
			
		
		
		
	Use Survey For Interactions With User (#186)
fixes Use Survey For Interactions With User Add Vendor "github.com/AlecAivazis/survey/v2" Co-authored-by: Norwin Roosen <git@nroo.de> Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/186 Reviewed-by: techknowlogick <techknowlogick@gitea.io> Reviewed-by: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
		
							
								
								
									
										3
									
								
								vendor/golang.org/x/text/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/text/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # This source code refers to The Go Authors for copyright purposes. | ||||
| # The master list of authors is in the main Go distribution, | ||||
| # visible at http://tip.golang.org/AUTHORS. | ||||
							
								
								
									
										3
									
								
								vendor/golang.org/x/text/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/text/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # This source code was written by the Go contributors. | ||||
| # The master list of contributors is in the main Go distribution, | ||||
| # visible at http://tip.golang.org/CONTRIBUTORS. | ||||
							
								
								
									
										27
									
								
								vendor/golang.org/x/text/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/golang.org/x/text/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
|  | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
|  | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
|  | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										22
									
								
								vendor/golang.org/x/text/PATENTS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/golang.org/x/text/PATENTS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| Additional IP Rights Grant (Patents) | ||||
|  | ||||
| "This implementation" means the copyrightable works distributed by | ||||
| Google as part of the Go project. | ||||
|  | ||||
| Google hereby grants to You a perpetual, worldwide, non-exclusive, | ||||
| no-charge, royalty-free, irrevocable (except as stated in this section) | ||||
| patent license to make, have made, use, offer to sell, sell, import, | ||||
| transfer and otherwise run, modify and propagate the contents of this | ||||
| implementation of Go, where such license applies only to those patent | ||||
| claims, both currently owned or controlled by Google and acquired in | ||||
| the future, licensable by Google that are necessarily infringed by this | ||||
| implementation of Go.  This grant does not include claims that would be | ||||
| infringed only as a consequence of further modification of this | ||||
| implementation.  If you or your agent or exclusive licensee institute or | ||||
| order or agree to the institution of patent litigation against any | ||||
| entity (including a cross-claim or counterclaim in a lawsuit) alleging | ||||
| that this implementation of Go or any code incorporated within this | ||||
| implementation of Go constitutes direct or contributory patent | ||||
| infringement, or inducement of patent infringement, then any patent | ||||
| rights granted to you under this License for this implementation of Go | ||||
| shall terminate as of the date such litigation is filed. | ||||
							
								
								
									
										705
									
								
								vendor/golang.org/x/text/transform/transform.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										705
									
								
								vendor/golang.org/x/text/transform/transform.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,705 @@ | ||||
| // Copyright 2013 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 transform provides reader and writer wrappers that transform the | ||||
| // bytes passing through as well as various transformations. Example | ||||
| // transformations provided by other packages include normalization and | ||||
| // conversion between character sets. | ||||
| package transform // import "golang.org/x/text/transform" | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// ErrShortDst means that the destination buffer was too short to | ||||
| 	// receive all of the transformed bytes. | ||||
| 	ErrShortDst = errors.New("transform: short destination buffer") | ||||
|  | ||||
| 	// ErrShortSrc means that the source buffer has insufficient data to | ||||
| 	// complete the transformation. | ||||
| 	ErrShortSrc = errors.New("transform: short source buffer") | ||||
|  | ||||
| 	// ErrEndOfSpan means that the input and output (the transformed input) | ||||
| 	// are not identical. | ||||
| 	ErrEndOfSpan = errors.New("transform: input and output are not identical") | ||||
|  | ||||
| 	// errInconsistentByteCount means that Transform returned success (nil | ||||
| 	// error) but also returned nSrc inconsistent with the src argument. | ||||
| 	errInconsistentByteCount = errors.New("transform: inconsistent byte count returned") | ||||
|  | ||||
| 	// errShortInternal means that an internal buffer is not large enough | ||||
| 	// to make progress and the Transform operation must be aborted. | ||||
| 	errShortInternal = errors.New("transform: short internal buffer") | ||||
| ) | ||||
|  | ||||
| // Transformer transforms bytes. | ||||
| type Transformer interface { | ||||
| 	// Transform writes to dst the transformed bytes read from src, and | ||||
| 	// returns the number of dst bytes written and src bytes read. The | ||||
| 	// atEOF argument tells whether src represents the last bytes of the | ||||
| 	// input. | ||||
| 	// | ||||
| 	// Callers should always process the nDst bytes produced and account | ||||
| 	// for the nSrc bytes consumed before considering the error err. | ||||
| 	// | ||||
| 	// A nil error means that all of the transformed bytes (whether freshly | ||||
| 	// transformed from src or left over from previous Transform calls) | ||||
| 	// were written to dst. A nil error can be returned regardless of | ||||
| 	// whether atEOF is true. If err is nil then nSrc must equal len(src); | ||||
| 	// the converse is not necessarily true. | ||||
| 	// | ||||
| 	// ErrShortDst means that dst was too short to receive all of the | ||||
| 	// transformed bytes. ErrShortSrc means that src had insufficient data | ||||
| 	// to complete the transformation. If both conditions apply, then | ||||
| 	// either error may be returned. Other than the error conditions listed | ||||
| 	// here, implementations are free to report other errors that arise. | ||||
| 	Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) | ||||
|  | ||||
| 	// Reset resets the state and allows a Transformer to be reused. | ||||
| 	Reset() | ||||
| } | ||||
|  | ||||
| // SpanningTransformer extends the Transformer interface with a Span method | ||||
| // that determines how much of the input already conforms to the Transformer. | ||||
| type SpanningTransformer interface { | ||||
| 	Transformer | ||||
|  | ||||
| 	// Span returns a position in src such that transforming src[:n] results in | ||||
| 	// identical output src[:n] for these bytes. It does not necessarily return | ||||
| 	// the largest such n. The atEOF argument tells whether src represents the | ||||
| 	// last bytes of the input. | ||||
| 	// | ||||
| 	// Callers should always account for the n bytes consumed before | ||||
| 	// considering the error err. | ||||
| 	// | ||||
| 	// A nil error means that all input bytes are known to be identical to the | ||||
| 	// output produced by the Transformer. A nil error can be returned | ||||
| 	// regardless of whether atEOF is true. If err is nil, then n must | ||||
| 	// equal len(src); the converse is not necessarily true. | ||||
| 	// | ||||
| 	// ErrEndOfSpan means that the Transformer output may differ from the | ||||
| 	// input after n bytes. Note that n may be len(src), meaning that the output | ||||
| 	// would contain additional bytes after otherwise identical output. | ||||
| 	// ErrShortSrc means that src had insufficient data to determine whether the | ||||
| 	// remaining bytes would change. Other than the error conditions listed | ||||
| 	// here, implementations are free to report other errors that arise. | ||||
| 	// | ||||
| 	// Calling Span can modify the Transformer state as a side effect. In | ||||
| 	// effect, it does the transformation just as calling Transform would, only | ||||
| 	// without copying to a destination buffer and only up to a point it can | ||||
| 	// determine the input and output bytes are the same. This is obviously more | ||||
| 	// limited than calling Transform, but can be more efficient in terms of | ||||
| 	// copying and allocating buffers. Calls to Span and Transform may be | ||||
| 	// interleaved. | ||||
| 	Span(src []byte, atEOF bool) (n int, err error) | ||||
| } | ||||
|  | ||||
| // NopResetter can be embedded by implementations of Transformer to add a nop | ||||
| // Reset method. | ||||
| type NopResetter struct{} | ||||
|  | ||||
| // Reset implements the Reset method of the Transformer interface. | ||||
| func (NopResetter) Reset() {} | ||||
|  | ||||
| // Reader wraps another io.Reader by transforming the bytes read. | ||||
| type Reader struct { | ||||
| 	r   io.Reader | ||||
| 	t   Transformer | ||||
| 	err error | ||||
|  | ||||
| 	// dst[dst0:dst1] contains bytes that have been transformed by t but | ||||
| 	// not yet copied out via Read. | ||||
| 	dst        []byte | ||||
| 	dst0, dst1 int | ||||
|  | ||||
| 	// src[src0:src1] contains bytes that have been read from r but not | ||||
| 	// yet transformed through t. | ||||
| 	src        []byte | ||||
| 	src0, src1 int | ||||
|  | ||||
| 	// transformComplete is whether the transformation is complete, | ||||
| 	// regardless of whether or not it was successful. | ||||
| 	transformComplete bool | ||||
| } | ||||
|  | ||||
| const defaultBufSize = 4096 | ||||
|  | ||||
| // NewReader returns a new Reader that wraps r by transforming the bytes read | ||||
| // via t. It calls Reset on t. | ||||
| func NewReader(r io.Reader, t Transformer) *Reader { | ||||
| 	t.Reset() | ||||
| 	return &Reader{ | ||||
| 		r:   r, | ||||
| 		t:   t, | ||||
| 		dst: make([]byte, defaultBufSize), | ||||
| 		src: make([]byte, defaultBufSize), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Read implements the io.Reader interface. | ||||
| func (r *Reader) Read(p []byte) (int, error) { | ||||
| 	n, err := 0, error(nil) | ||||
| 	for { | ||||
| 		// Copy out any transformed bytes and return the final error if we are done. | ||||
| 		if r.dst0 != r.dst1 { | ||||
| 			n = copy(p, r.dst[r.dst0:r.dst1]) | ||||
| 			r.dst0 += n | ||||
| 			if r.dst0 == r.dst1 && r.transformComplete { | ||||
| 				return n, r.err | ||||
| 			} | ||||
| 			return n, nil | ||||
| 		} else if r.transformComplete { | ||||
| 			return 0, r.err | ||||
| 		} | ||||
|  | ||||
| 		// Try to transform some source bytes, or to flush the transformer if we | ||||
| 		// are out of source bytes. We do this even if r.r.Read returned an error. | ||||
| 		// As the io.Reader documentation says, "process the n > 0 bytes returned | ||||
| 		// before considering the error". | ||||
| 		if r.src0 != r.src1 || r.err != nil { | ||||
| 			r.dst0 = 0 | ||||
| 			r.dst1, n, err = r.t.Transform(r.dst, r.src[r.src0:r.src1], r.err == io.EOF) | ||||
| 			r.src0 += n | ||||
|  | ||||
| 			switch { | ||||
| 			case err == nil: | ||||
| 				if r.src0 != r.src1 { | ||||
| 					r.err = errInconsistentByteCount | ||||
| 				} | ||||
| 				// The Transform call was successful; we are complete if we | ||||
| 				// cannot read more bytes into src. | ||||
| 				r.transformComplete = r.err != nil | ||||
| 				continue | ||||
| 			case err == ErrShortDst && (r.dst1 != 0 || n != 0): | ||||
| 				// Make room in dst by copying out, and try again. | ||||
| 				continue | ||||
| 			case err == ErrShortSrc && r.src1-r.src0 != len(r.src) && r.err == nil: | ||||
| 				// Read more bytes into src via the code below, and try again. | ||||
| 			default: | ||||
| 				r.transformComplete = true | ||||
| 				// The reader error (r.err) takes precedence over the | ||||
| 				// transformer error (err) unless r.err is nil or io.EOF. | ||||
| 				if r.err == nil || r.err == io.EOF { | ||||
| 					r.err = err | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Move any untransformed source bytes to the start of the buffer | ||||
| 		// and read more bytes. | ||||
| 		if r.src0 != 0 { | ||||
| 			r.src0, r.src1 = 0, copy(r.src, r.src[r.src0:r.src1]) | ||||
| 		} | ||||
| 		n, r.err = r.r.Read(r.src[r.src1:]) | ||||
| 		r.src1 += n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TODO: implement ReadByte (and ReadRune??). | ||||
|  | ||||
| // Writer wraps another io.Writer by transforming the bytes read. | ||||
| // The user needs to call Close to flush unwritten bytes that may | ||||
| // be buffered. | ||||
| type Writer struct { | ||||
| 	w   io.Writer | ||||
| 	t   Transformer | ||||
| 	dst []byte | ||||
|  | ||||
| 	// src[:n] contains bytes that have not yet passed through t. | ||||
| 	src []byte | ||||
| 	n   int | ||||
| } | ||||
|  | ||||
| // NewWriter returns a new Writer that wraps w by transforming the bytes written | ||||
| // via t. It calls Reset on t. | ||||
| func NewWriter(w io.Writer, t Transformer) *Writer { | ||||
| 	t.Reset() | ||||
| 	return &Writer{ | ||||
| 		w:   w, | ||||
| 		t:   t, | ||||
| 		dst: make([]byte, defaultBufSize), | ||||
| 		src: make([]byte, defaultBufSize), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Write implements the io.Writer interface. If there are not enough | ||||
| // bytes available to complete a Transform, the bytes will be buffered | ||||
| // for the next write. Call Close to convert the remaining bytes. | ||||
| func (w *Writer) Write(data []byte) (n int, err error) { | ||||
| 	src := data | ||||
| 	if w.n > 0 { | ||||
| 		// Append bytes from data to the last remainder. | ||||
| 		// TODO: limit the amount copied on first try. | ||||
| 		n = copy(w.src[w.n:], data) | ||||
| 		w.n += n | ||||
| 		src = w.src[:w.n] | ||||
| 	} | ||||
| 	for { | ||||
| 		nDst, nSrc, err := w.t.Transform(w.dst, src, false) | ||||
| 		if _, werr := w.w.Write(w.dst[:nDst]); werr != nil { | ||||
| 			return n, werr | ||||
| 		} | ||||
| 		src = src[nSrc:] | ||||
| 		if w.n == 0 { | ||||
| 			n += nSrc | ||||
| 		} else if len(src) <= n { | ||||
| 			// Enough bytes from w.src have been consumed. We make src point | ||||
| 			// to data instead to reduce the copying. | ||||
| 			w.n = 0 | ||||
| 			n -= len(src) | ||||
| 			src = data[n:] | ||||
| 			if n < len(data) && (err == nil || err == ErrShortSrc) { | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 		switch err { | ||||
| 		case ErrShortDst: | ||||
| 			// This error is okay as long as we are making progress. | ||||
| 			if nDst > 0 || nSrc > 0 { | ||||
| 				continue | ||||
| 			} | ||||
| 		case ErrShortSrc: | ||||
| 			if len(src) < len(w.src) { | ||||
| 				m := copy(w.src, src) | ||||
| 				// If w.n > 0, bytes from data were already copied to w.src and n | ||||
| 				// was already set to the number of bytes consumed. | ||||
| 				if w.n == 0 { | ||||
| 					n += m | ||||
| 				} | ||||
| 				w.n = m | ||||
| 				err = nil | ||||
| 			} else if nDst > 0 || nSrc > 0 { | ||||
| 				// Not enough buffer to store the remainder. Keep processing as | ||||
| 				// long as there is progress. Without this case, transforms that | ||||
| 				// require a lookahead larger than the buffer may result in an | ||||
| 				// error. This is not something one may expect to be common in | ||||
| 				// practice, but it may occur when buffers are set to small | ||||
| 				// sizes during testing. | ||||
| 				continue | ||||
| 			} | ||||
| 		case nil: | ||||
| 			if w.n > 0 { | ||||
| 				err = errInconsistentByteCount | ||||
| 			} | ||||
| 		} | ||||
| 		return n, err | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Close implements the io.Closer interface. | ||||
| func (w *Writer) Close() error { | ||||
| 	src := w.src[:w.n] | ||||
| 	for { | ||||
| 		nDst, nSrc, err := w.t.Transform(w.dst, src, true) | ||||
| 		if _, werr := w.w.Write(w.dst[:nDst]); werr != nil { | ||||
| 			return werr | ||||
| 		} | ||||
| 		if err != ErrShortDst { | ||||
| 			return err | ||||
| 		} | ||||
| 		src = src[nSrc:] | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type nop struct{ NopResetter } | ||||
|  | ||||
| func (nop) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { | ||||
| 	n := copy(dst, src) | ||||
| 	if n < len(src) { | ||||
| 		err = ErrShortDst | ||||
| 	} | ||||
| 	return n, n, err | ||||
| } | ||||
|  | ||||
| func (nop) Span(src []byte, atEOF bool) (n int, err error) { | ||||
| 	return len(src), nil | ||||
| } | ||||
|  | ||||
| type discard struct{ NopResetter } | ||||
|  | ||||
| func (discard) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { | ||||
| 	return 0, len(src), nil | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// Discard is a Transformer for which all Transform calls succeed | ||||
| 	// by consuming all bytes and writing nothing. | ||||
| 	Discard Transformer = discard{} | ||||
|  | ||||
| 	// Nop is a SpanningTransformer that copies src to dst. | ||||
| 	Nop SpanningTransformer = nop{} | ||||
| ) | ||||
|  | ||||
| // chain is a sequence of links. A chain with N Transformers has N+1 links and | ||||
| // N+1 buffers. Of those N+1 buffers, the first and last are the src and dst | ||||
| // buffers given to chain.Transform and the middle N-1 buffers are intermediate | ||||
| // buffers owned by the chain. The i'th link transforms bytes from the i'th | ||||
| // buffer chain.link[i].b at read offset chain.link[i].p to the i+1'th buffer | ||||
| // chain.link[i+1].b at write offset chain.link[i+1].n, for i in [0, N). | ||||
| type chain struct { | ||||
| 	link []link | ||||
| 	err  error | ||||
| 	// errStart is the index at which the error occurred plus 1. Processing | ||||
| 	// errStart at this level at the next call to Transform. As long as | ||||
| 	// errStart > 0, chain will not consume any more source bytes. | ||||
| 	errStart int | ||||
| } | ||||
|  | ||||
| func (c *chain) fatalError(errIndex int, err error) { | ||||
| 	if i := errIndex + 1; i > c.errStart { | ||||
| 		c.errStart = i | ||||
| 		c.err = err | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type link struct { | ||||
| 	t Transformer | ||||
| 	// b[p:n] holds the bytes to be transformed by t. | ||||
| 	b []byte | ||||
| 	p int | ||||
| 	n int | ||||
| } | ||||
|  | ||||
| func (l *link) src() []byte { | ||||
| 	return l.b[l.p:l.n] | ||||
| } | ||||
|  | ||||
| func (l *link) dst() []byte { | ||||
| 	return l.b[l.n:] | ||||
| } | ||||
|  | ||||
| // Chain returns a Transformer that applies t in sequence. | ||||
| func Chain(t ...Transformer) Transformer { | ||||
| 	if len(t) == 0 { | ||||
| 		return nop{} | ||||
| 	} | ||||
| 	c := &chain{link: make([]link, len(t)+1)} | ||||
| 	for i, tt := range t { | ||||
| 		c.link[i].t = tt | ||||
| 	} | ||||
| 	// Allocate intermediate buffers. | ||||
| 	b := make([][defaultBufSize]byte, len(t)-1) | ||||
| 	for i := range b { | ||||
| 		c.link[i+1].b = b[i][:] | ||||
| 	} | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| // Reset resets the state of Chain. It calls Reset on all the Transformers. | ||||
| func (c *chain) Reset() { | ||||
| 	for i, l := range c.link { | ||||
| 		if l.t != nil { | ||||
| 			l.t.Reset() | ||||
| 		} | ||||
| 		c.link[i].p, c.link[i].n = 0, 0 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TODO: make chain use Span (is going to be fun to implement!) | ||||
|  | ||||
| // Transform applies the transformers of c in sequence. | ||||
| func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { | ||||
| 	// Set up src and dst in the chain. | ||||
| 	srcL := &c.link[0] | ||||
| 	dstL := &c.link[len(c.link)-1] | ||||
| 	srcL.b, srcL.p, srcL.n = src, 0, len(src) | ||||
| 	dstL.b, dstL.n = dst, 0 | ||||
| 	var lastFull, needProgress bool // for detecting progress | ||||
|  | ||||
| 	// i is the index of the next Transformer to apply, for i in [low, high]. | ||||
| 	// low is the lowest index for which c.link[low] may still produce bytes. | ||||
| 	// high is the highest index for which c.link[high] has a Transformer. | ||||
| 	// The error returned by Transform determines whether to increase or | ||||
| 	// decrease i. We try to completely fill a buffer before converting it. | ||||
| 	for low, i, high := c.errStart, c.errStart, len(c.link)-2; low <= i && i <= high; { | ||||
| 		in, out := &c.link[i], &c.link[i+1] | ||||
| 		nDst, nSrc, err0 := in.t.Transform(out.dst(), in.src(), atEOF && low == i) | ||||
| 		out.n += nDst | ||||
| 		in.p += nSrc | ||||
| 		if i > 0 && in.p == in.n { | ||||
| 			in.p, in.n = 0, 0 | ||||
| 		} | ||||
| 		needProgress, lastFull = lastFull, false | ||||
| 		switch err0 { | ||||
| 		case ErrShortDst: | ||||
| 			// Process the destination buffer next. Return if we are already | ||||
| 			// at the high index. | ||||
| 			if i == high { | ||||
| 				return dstL.n, srcL.p, ErrShortDst | ||||
| 			} | ||||
| 			if out.n != 0 { | ||||
| 				i++ | ||||
| 				// If the Transformer at the next index is not able to process any | ||||
| 				// source bytes there is nothing that can be done to make progress | ||||
| 				// and the bytes will remain unprocessed. lastFull is used to | ||||
| 				// detect this and break out of the loop with a fatal error. | ||||
| 				lastFull = true | ||||
| 				continue | ||||
| 			} | ||||
| 			// The destination buffer was too small, but is completely empty. | ||||
| 			// Return a fatal error as this transformation can never complete. | ||||
| 			c.fatalError(i, errShortInternal) | ||||
| 		case ErrShortSrc: | ||||
| 			if i == 0 { | ||||
| 				// Save ErrShortSrc in err. All other errors take precedence. | ||||
| 				err = ErrShortSrc | ||||
| 				break | ||||
| 			} | ||||
| 			// Source bytes were depleted before filling up the destination buffer. | ||||
| 			// Verify we made some progress, move the remaining bytes to the errStart | ||||
| 			// and try to get more source bytes. | ||||
| 			if needProgress && nSrc == 0 || in.n-in.p == len(in.b) { | ||||
| 				// There were not enough source bytes to proceed while the source | ||||
| 				// buffer cannot hold any more bytes. Return a fatal error as this | ||||
| 				// transformation can never complete. | ||||
| 				c.fatalError(i, errShortInternal) | ||||
| 				break | ||||
| 			} | ||||
| 			// in.b is an internal buffer and we can make progress. | ||||
| 			in.p, in.n = 0, copy(in.b, in.src()) | ||||
| 			fallthrough | ||||
| 		case nil: | ||||
| 			// if i == low, we have depleted the bytes at index i or any lower levels. | ||||
| 			// In that case we increase low and i. In all other cases we decrease i to | ||||
| 			// fetch more bytes before proceeding to the next index. | ||||
| 			if i > low { | ||||
| 				i-- | ||||
| 				continue | ||||
| 			} | ||||
| 		default: | ||||
| 			c.fatalError(i, err0) | ||||
| 		} | ||||
| 		// Exhausted level low or fatal error: increase low and continue | ||||
| 		// to process the bytes accepted so far. | ||||
| 		i++ | ||||
| 		low = i | ||||
| 	} | ||||
|  | ||||
| 	// If c.errStart > 0, this means we found a fatal error.  We will clear | ||||
| 	// all upstream buffers. At this point, no more progress can be made | ||||
| 	// downstream, as Transform would have bailed while handling ErrShortDst. | ||||
| 	if c.errStart > 0 { | ||||
| 		for i := 1; i < c.errStart; i++ { | ||||
| 			c.link[i].p, c.link[i].n = 0, 0 | ||||
| 		} | ||||
| 		err, c.errStart, c.err = c.err, 0, nil | ||||
| 	} | ||||
| 	return dstL.n, srcL.p, err | ||||
| } | ||||
|  | ||||
| // Deprecated: Use runes.Remove instead. | ||||
| func RemoveFunc(f func(r rune) bool) Transformer { | ||||
| 	return removeF(f) | ||||
| } | ||||
|  | ||||
| type removeF func(r rune) bool | ||||
|  | ||||
| func (removeF) Reset() {} | ||||
|  | ||||
| // Transform implements the Transformer interface. | ||||
| func (t removeF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { | ||||
| 	for r, sz := rune(0), 0; len(src) > 0; src = src[sz:] { | ||||
|  | ||||
| 		if r = rune(src[0]); r < utf8.RuneSelf { | ||||
| 			sz = 1 | ||||
| 		} else { | ||||
| 			r, sz = utf8.DecodeRune(src) | ||||
|  | ||||
| 			if sz == 1 { | ||||
| 				// Invalid rune. | ||||
| 				if !atEOF && !utf8.FullRune(src) { | ||||
| 					err = ErrShortSrc | ||||
| 					break | ||||
| 				} | ||||
| 				// We replace illegal bytes with RuneError. Not doing so might | ||||
| 				// otherwise turn a sequence of invalid UTF-8 into valid UTF-8. | ||||
| 				// The resulting byte sequence may subsequently contain runes | ||||
| 				// for which t(r) is true that were passed unnoticed. | ||||
| 				if !t(r) { | ||||
| 					if nDst+3 > len(dst) { | ||||
| 						err = ErrShortDst | ||||
| 						break | ||||
| 					} | ||||
| 					nDst += copy(dst[nDst:], "\uFFFD") | ||||
| 				} | ||||
| 				nSrc++ | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if !t(r) { | ||||
| 			if nDst+sz > len(dst) { | ||||
| 				err = ErrShortDst | ||||
| 				break | ||||
| 			} | ||||
| 			nDst += copy(dst[nDst:], src[:sz]) | ||||
| 		} | ||||
| 		nSrc += sz | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // grow returns a new []byte that is longer than b, and copies the first n bytes | ||||
| // of b to the start of the new slice. | ||||
| func grow(b []byte, n int) []byte { | ||||
| 	m := len(b) | ||||
| 	if m <= 32 { | ||||
| 		m = 64 | ||||
| 	} else if m <= 256 { | ||||
| 		m *= 2 | ||||
| 	} else { | ||||
| 		m += m >> 1 | ||||
| 	} | ||||
| 	buf := make([]byte, m) | ||||
| 	copy(buf, b[:n]) | ||||
| 	return buf | ||||
| } | ||||
|  | ||||
| const initialBufSize = 128 | ||||
|  | ||||
| // String returns a string with the result of converting s[:n] using t, where | ||||
| // n <= len(s). If err == nil, n will be len(s). It calls Reset on t. | ||||
| func String(t Transformer, s string) (result string, n int, err error) { | ||||
| 	t.Reset() | ||||
| 	if s == "" { | ||||
| 		// Fast path for the common case for empty input. Results in about a | ||||
| 		// 86% reduction of running time for BenchmarkStringLowerEmpty. | ||||
| 		if _, _, err := t.Transform(nil, nil, true); err == nil { | ||||
| 			return "", 0, nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Allocate only once. Note that both dst and src escape when passed to | ||||
| 	// Transform. | ||||
| 	buf := [2 * initialBufSize]byte{} | ||||
| 	dst := buf[:initialBufSize:initialBufSize] | ||||
| 	src := buf[initialBufSize : 2*initialBufSize] | ||||
|  | ||||
| 	// The input string s is transformed in multiple chunks (starting with a | ||||
| 	// chunk size of initialBufSize). nDst and nSrc are per-chunk (or | ||||
| 	// per-Transform-call) indexes, pDst and pSrc are overall indexes. | ||||
| 	nDst, nSrc := 0, 0 | ||||
| 	pDst, pSrc := 0, 0 | ||||
|  | ||||
| 	// pPrefix is the length of a common prefix: the first pPrefix bytes of the | ||||
| 	// result will equal the first pPrefix bytes of s. It is not guaranteed to | ||||
| 	// be the largest such value, but if pPrefix, len(result) and len(s) are | ||||
| 	// all equal after the final transform (i.e. calling Transform with atEOF | ||||
| 	// being true returned nil error) then we don't need to allocate a new | ||||
| 	// result string. | ||||
| 	pPrefix := 0 | ||||
| 	for { | ||||
| 		// Invariant: pDst == pPrefix && pSrc == pPrefix. | ||||
|  | ||||
| 		n := copy(src, s[pSrc:]) | ||||
| 		nDst, nSrc, err = t.Transform(dst, src[:n], pSrc+n == len(s)) | ||||
| 		pDst += nDst | ||||
| 		pSrc += nSrc | ||||
|  | ||||
| 		// TODO:  let transformers implement an optional Spanner interface, akin | ||||
| 		// to norm's QuickSpan. This would even allow us to avoid any allocation. | ||||
| 		if !bytes.Equal(dst[:nDst], src[:nSrc]) { | ||||
| 			break | ||||
| 		} | ||||
| 		pPrefix = pSrc | ||||
| 		if err == ErrShortDst { | ||||
| 			// A buffer can only be short if a transformer modifies its input. | ||||
| 			break | ||||
| 		} else if err == ErrShortSrc { | ||||
| 			if nSrc == 0 { | ||||
| 				// No progress was made. | ||||
| 				break | ||||
| 			} | ||||
| 			// Equal so far and !atEOF, so continue checking. | ||||
| 		} else if err != nil || pPrefix == len(s) { | ||||
| 			return string(s[:pPrefix]), pPrefix, err | ||||
| 		} | ||||
| 	} | ||||
| 	// Post-condition: pDst == pPrefix + nDst && pSrc == pPrefix + nSrc. | ||||
|  | ||||
| 	// We have transformed the first pSrc bytes of the input s to become pDst | ||||
| 	// transformed bytes. Those transformed bytes are discontiguous: the first | ||||
| 	// pPrefix of them equal s[:pPrefix] and the last nDst of them equal | ||||
| 	// dst[:nDst]. We copy them around, into a new dst buffer if necessary, so | ||||
| 	// that they become one contiguous slice: dst[:pDst]. | ||||
| 	if pPrefix != 0 { | ||||
| 		newDst := dst | ||||
| 		if pDst > len(newDst) { | ||||
| 			newDst = make([]byte, len(s)+nDst-nSrc) | ||||
| 		} | ||||
| 		copy(newDst[pPrefix:pDst], dst[:nDst]) | ||||
| 		copy(newDst[:pPrefix], s[:pPrefix]) | ||||
| 		dst = newDst | ||||
| 	} | ||||
|  | ||||
| 	// Prevent duplicate Transform calls with atEOF being true at the end of | ||||
| 	// the input. Also return if we have an unrecoverable error. | ||||
| 	if (err == nil && pSrc == len(s)) || | ||||
| 		(err != nil && err != ErrShortDst && err != ErrShortSrc) { | ||||
| 		return string(dst[:pDst]), pSrc, err | ||||
| 	} | ||||
|  | ||||
| 	// Transform the remaining input, growing dst and src buffers as necessary. | ||||
| 	for { | ||||
| 		n := copy(src, s[pSrc:]) | ||||
| 		nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], pSrc+n == len(s)) | ||||
| 		pDst += nDst | ||||
| 		pSrc += nSrc | ||||
|  | ||||
| 		// If we got ErrShortDst or ErrShortSrc, do not grow as long as we can | ||||
| 		// make progress. This may avoid excessive allocations. | ||||
| 		if err == ErrShortDst { | ||||
| 			if nDst == 0 { | ||||
| 				dst = grow(dst, pDst) | ||||
| 			} | ||||
| 		} else if err == ErrShortSrc { | ||||
| 			if nSrc == 0 { | ||||
| 				src = grow(src, 0) | ||||
| 			} | ||||
| 		} else if err != nil || pSrc == len(s) { | ||||
| 			return string(dst[:pDst]), pSrc, err | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Bytes returns a new byte slice with the result of converting b[:n] using t, | ||||
| // where n <= len(b). If err == nil, n will be len(b). It calls Reset on t. | ||||
| func Bytes(t Transformer, b []byte) (result []byte, n int, err error) { | ||||
| 	return doAppend(t, 0, make([]byte, len(b)), b) | ||||
| } | ||||
|  | ||||
| // Append appends the result of converting src[:n] using t to dst, where | ||||
| // n <= len(src), If err == nil, n will be len(src). It calls Reset on t. | ||||
| func Append(t Transformer, dst, src []byte) (result []byte, n int, err error) { | ||||
| 	if len(dst) == cap(dst) { | ||||
| 		n := len(src) + len(dst) // It is okay for this to be 0. | ||||
| 		b := make([]byte, n) | ||||
| 		dst = b[:copy(b, dst)] | ||||
| 	} | ||||
| 	return doAppend(t, len(dst), dst[:cap(dst)], src) | ||||
| } | ||||
|  | ||||
| func doAppend(t Transformer, pDst int, dst, src []byte) (result []byte, n int, err error) { | ||||
| 	t.Reset() | ||||
| 	pSrc := 0 | ||||
| 	for { | ||||
| 		nDst, nSrc, err := t.Transform(dst[pDst:], src[pSrc:], true) | ||||
| 		pDst += nDst | ||||
| 		pSrc += nSrc | ||||
| 		if err != ErrShortDst { | ||||
| 			return dst[:pDst], pSrc, err | ||||
| 		} | ||||
|  | ||||
| 		// Grow the destination buffer, but do not grow as long as we can make | ||||
| 		// progress. This may avoid excessive allocations. | ||||
| 		if nDst == 0 { | ||||
| 			dst = grow(dst, pDst) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										28
									
								
								vendor/golang.org/x/text/width/kind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/golang.org/x/text/width/kind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // Code generated by "stringer -type=Kind"; DO NOT EDIT. | ||||
|  | ||||
| package width | ||||
|  | ||||
| import "strconv" | ||||
|  | ||||
| func _() { | ||||
| 	// An "invalid array index" compiler error signifies that the constant values have changed. | ||||
| 	// Re-run the stringer command to generate them again. | ||||
| 	var x [1]struct{} | ||||
| 	_ = x[Neutral-0] | ||||
| 	_ = x[EastAsianAmbiguous-1] | ||||
| 	_ = x[EastAsianWide-2] | ||||
| 	_ = x[EastAsianNarrow-3] | ||||
| 	_ = x[EastAsianFullwidth-4] | ||||
| 	_ = x[EastAsianHalfwidth-5] | ||||
| } | ||||
|  | ||||
| const _Kind_name = "NeutralEastAsianAmbiguousEastAsianWideEastAsianNarrowEastAsianFullwidthEastAsianHalfwidth" | ||||
|  | ||||
| var _Kind_index = [...]uint8{0, 7, 25, 38, 53, 71, 89} | ||||
|  | ||||
| func (i Kind) String() string { | ||||
| 	if i < 0 || i >= Kind(len(_Kind_index)-1) { | ||||
| 		return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] | ||||
| } | ||||
							
								
								
									
										1318
									
								
								vendor/golang.org/x/text/width/tables10.0.0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1318
									
								
								vendor/golang.org/x/text/width/tables10.0.0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1330
									
								
								vendor/golang.org/x/text/width/tables11.0.0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1330
									
								
								vendor/golang.org/x/text/width/tables11.0.0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1286
									
								
								vendor/golang.org/x/text/width/tables9.0.0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1286
									
								
								vendor/golang.org/x/text/width/tables9.0.0.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										239
									
								
								vendor/golang.org/x/text/width/transform.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								vendor/golang.org/x/text/width/transform.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,239 @@ | ||||
| // 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 | ||||
| } | ||||
							
								
								
									
										30
									
								
								vendor/golang.org/x/text/width/trieval.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/golang.org/x/text/width/trieval.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. | ||||
|  | ||||
| package width | ||||
|  | ||||
| // elem is an entry of the width trie. The high byte is used to encode the type | ||||
| // of the rune. The low byte is used to store the index to a mapping entry in | ||||
| // the inverseData array. | ||||
| type elem uint16 | ||||
|  | ||||
| const ( | ||||
| 	tagNeutral elem = iota << typeShift | ||||
| 	tagAmbiguous | ||||
| 	tagWide | ||||
| 	tagNarrow | ||||
| 	tagFullwidth | ||||
| 	tagHalfwidth | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	numTypeBits = 3 | ||||
| 	typeShift   = 16 - numTypeBits | ||||
|  | ||||
| 	// tagNeedsFold is true for all fullwidth and halfwidth runes except for | ||||
| 	// the Won sign U+20A9. | ||||
| 	tagNeedsFold = 0x1000 | ||||
|  | ||||
| 	// The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide | ||||
| 	// variant. | ||||
| 	wonSign rune = 0x20A9 | ||||
| ) | ||||
							
								
								
									
										206
									
								
								vendor/golang.org/x/text/width/width.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								vendor/golang.org/x/text/width/width.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,206 @@ | ||||
| // 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. | ||||
|  | ||||
| //go:generate stringer -type=Kind | ||||
| //go:generate go run gen.go gen_common.go gen_trieval.go | ||||
|  | ||||
| // Package width provides functionality for handling different widths in text. | ||||
| // | ||||
| // Wide characters behave like ideographs; they tend to allow line breaks after | ||||
| // each character and remain upright in vertical text layout. Narrow characters | ||||
| // are kept together in words or runs that are rotated sideways in vertical text | ||||
| // layout. | ||||
| // | ||||
| // For more information, see https://unicode.org/reports/tr11/. | ||||
| package width // import "golang.org/x/text/width" | ||||
|  | ||||
| import ( | ||||
| 	"unicode/utf8" | ||||
|  | ||||
| 	"golang.org/x/text/transform" | ||||
| ) | ||||
|  | ||||
| // TODO | ||||
| // 1) Reduce table size by compressing blocks. | ||||
| // 2) API proposition for computing display length | ||||
| //    (approximation, fixed pitch only). | ||||
| // 3) Implement display length. | ||||
|  | ||||
| // Kind indicates the type of width property as defined in https://unicode.org/reports/tr11/. | ||||
| type Kind int | ||||
|  | ||||
| const ( | ||||
| 	// Neutral characters do not occur in legacy East Asian character sets. | ||||
| 	Neutral Kind = iota | ||||
|  | ||||
| 	// EastAsianAmbiguous characters that can be sometimes wide and sometimes | ||||
| 	// narrow and require additional information not contained in the character | ||||
| 	// code to further resolve their width. | ||||
| 	EastAsianAmbiguous | ||||
|  | ||||
| 	// EastAsianWide characters are wide in its usual form. They occur only in | ||||
| 	// the context of East Asian typography. These runes may have explicit | ||||
| 	// halfwidth counterparts. | ||||
| 	EastAsianWide | ||||
|  | ||||
| 	// EastAsianNarrow characters are narrow in its usual form. They often have | ||||
| 	// fullwidth counterparts. | ||||
| 	EastAsianNarrow | ||||
|  | ||||
| 	// Note: there exist Narrow runes that do not have fullwidth or wide | ||||
| 	// counterparts, despite what the definition says (e.g. U+27E6). | ||||
|  | ||||
| 	// EastAsianFullwidth characters have a compatibility decompositions of type | ||||
| 	// wide that map to a narrow counterpart. | ||||
| 	EastAsianFullwidth | ||||
|  | ||||
| 	// EastAsianHalfwidth characters have a compatibility decomposition of type | ||||
| 	// narrow that map to a wide or ambiguous counterpart, plus U+20A9 ₩ WON | ||||
| 	// SIGN. | ||||
| 	EastAsianHalfwidth | ||||
|  | ||||
| 	// Note: there exist runes that have a halfwidth counterparts but that are | ||||
| 	// classified as Ambiguous, rather than wide (e.g. U+2190). | ||||
| ) | ||||
|  | ||||
| // TODO: the generated tries need to return size 1 for invalid runes for the | ||||
| // width to be computed correctly (each byte should render width 1) | ||||
|  | ||||
| var trie = newWidthTrie(0) | ||||
|  | ||||
| // Lookup reports the Properties of the first rune in b and the number of bytes | ||||
| // of its UTF-8 encoding. | ||||
| func Lookup(b []byte) (p Properties, size int) { | ||||
| 	v, sz := trie.lookup(b) | ||||
| 	return Properties{elem(v), b[sz-1]}, sz | ||||
| } | ||||
|  | ||||
| // LookupString reports the Properties of the first rune in s and the number of | ||||
| // bytes of its UTF-8 encoding. | ||||
| func LookupString(s string) (p Properties, size int) { | ||||
| 	v, sz := trie.lookupString(s) | ||||
| 	return Properties{elem(v), s[sz-1]}, sz | ||||
| } | ||||
|  | ||||
| // LookupRune reports the Properties of rune r. | ||||
| func LookupRune(r rune) Properties { | ||||
| 	var buf [4]byte | ||||
| 	n := utf8.EncodeRune(buf[:], r) | ||||
| 	v, _ := trie.lookup(buf[:n]) | ||||
| 	last := byte(r) | ||||
| 	if r >= utf8.RuneSelf { | ||||
| 		last = 0x80 + byte(r&0x3f) | ||||
| 	} | ||||
| 	return Properties{elem(v), last} | ||||
| } | ||||
|  | ||||
| // Properties provides access to width properties of a rune. | ||||
| type Properties struct { | ||||
| 	elem elem | ||||
| 	last byte | ||||
| } | ||||
|  | ||||
| func (e elem) kind() Kind { | ||||
| 	return Kind(e >> typeShift) | ||||
| } | ||||
|  | ||||
| // Kind returns the Kind of a rune as defined in Unicode TR #11. | ||||
| // See https://unicode.org/reports/tr11/ for more details. | ||||
| func (p Properties) Kind() Kind { | ||||
| 	return p.elem.kind() | ||||
| } | ||||
|  | ||||
| // Folded returns the folded variant of a rune or 0 if the rune is canonical. | ||||
| func (p Properties) Folded() rune { | ||||
| 	if p.elem&tagNeedsFold != 0 { | ||||
| 		buf := inverseData[byte(p.elem)] | ||||
| 		buf[buf[0]] ^= p.last | ||||
| 		r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]]) | ||||
| 		return r | ||||
| 	} | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| // Narrow returns the narrow variant of a rune or 0 if the rune is already | ||||
| // narrow or doesn't have a narrow variant. | ||||
| func (p Properties) Narrow() rune { | ||||
| 	if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianFullwidth || k == EastAsianWide || k == EastAsianAmbiguous) { | ||||
| 		buf := inverseData[byte(p.elem)] | ||||
| 		buf[buf[0]] ^= p.last | ||||
| 		r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]]) | ||||
| 		return r | ||||
| 	} | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| // Wide returns the wide variant of a rune or 0 if the rune is already | ||||
| // wide or doesn't have a wide variant. | ||||
| func (p Properties) Wide() rune { | ||||
| 	if k := p.elem.kind(); byte(p.elem) != 0 && (k == EastAsianHalfwidth || k == EastAsianNarrow) { | ||||
| 		buf := inverseData[byte(p.elem)] | ||||
| 		buf[buf[0]] ^= p.last | ||||
| 		r, _ := utf8.DecodeRune(buf[1 : 1+buf[0]]) | ||||
| 		return r | ||||
| 	} | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| // TODO for Properties: | ||||
| // - Add Fullwidth/Halfwidth or Inverted methods for computing variants | ||||
| // mapping. | ||||
| // - Add width information (including information on non-spacing runes). | ||||
|  | ||||
| // Transformer implements the transform.Transformer interface. | ||||
| type Transformer struct { | ||||
| 	t transform.SpanningTransformer | ||||
| } | ||||
|  | ||||
| // Reset implements the transform.Transformer interface. | ||||
| func (t Transformer) Reset() { t.t.Reset() } | ||||
|  | ||||
| // Transform implements the transform.Transformer interface. | ||||
| func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { | ||||
| 	return t.t.Transform(dst, src, atEOF) | ||||
| } | ||||
|  | ||||
| // Span implements the transform.SpanningTransformer interface. | ||||
| func (t Transformer) Span(src []byte, atEOF bool) (n int, err error) { | ||||
| 	return t.t.Span(src, atEOF) | ||||
| } | ||||
|  | ||||
| // Bytes returns a new byte slice with the result of applying t to b. | ||||
| func (t Transformer) Bytes(b []byte) []byte { | ||||
| 	b, _, _ = transform.Bytes(t, b) | ||||
| 	return b | ||||
| } | ||||
|  | ||||
| // String returns a string with the result of applying t to s. | ||||
| func (t Transformer) String(s string) string { | ||||
| 	s, _, _ = transform.String(t, s) | ||||
| 	return s | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	// Fold is a transform that maps all runes to their canonical width. | ||||
| 	// | ||||
| 	// Note that the NFKC and NFKD transforms in golang.org/x/text/unicode/norm | ||||
| 	// provide a more generic folding mechanism. | ||||
| 	Fold Transformer = Transformer{foldTransform{}} | ||||
|  | ||||
| 	// Widen is a transform that maps runes to their wide variant, if | ||||
| 	// available. | ||||
| 	Widen Transformer = Transformer{wideTransform{}} | ||||
|  | ||||
| 	// Narrow is a transform that maps runes to their narrow variant, if | ||||
| 	// available. | ||||
| 	Narrow Transformer = Transformer{narrowTransform{}} | ||||
| ) | ||||
|  | ||||
| // TODO: Consider the following options: | ||||
| // - Treat Ambiguous runes that have a halfwidth counterpart as wide, or some | ||||
| //   generalized variant of this. | ||||
| // - Consider a wide Won character to be the default width (or some generalized | ||||
| //   variant of this). | ||||
| // - Filter the set of characters that gets converted (the preferred approach is | ||||
| //   to allow applying filters to transforms). | ||||
		Reference in New Issue
	
	Block a user
	 6543
					6543