...

Source file src/pkg/vendor/golang.org/x/text/unicode/norm/transform.go

     1	// Copyright 2013 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 norm
     6	
     7	import (
     8		"unicode/utf8"
     9	
    10		"golang.org/x/text/transform"
    11	)
    12	
    13	// Reset implements the Reset method of the transform.Transformer interface.
    14	func (Form) Reset() {}
    15	
    16	// Transform implements the Transform method of the transform.Transformer
    17	// interface. It may need to write segments of up to MaxSegmentSize at once.
    18	// Users should either catch ErrShortDst and allow dst to grow or have dst be at
    19	// least of size MaxTransformChunkSize to be guaranteed of progress.
    20	func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
    21		// Cap the maximum number of src bytes to check.
    22		b := src
    23		eof := atEOF
    24		if ns := len(dst); ns < len(b) {
    25			err = transform.ErrShortDst
    26			eof = false
    27			b = b[:ns]
    28		}
    29		i, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), eof)
    30		n := copy(dst, b[:i])
    31		if !ok {
    32			nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF)
    33			return nDst + n, nSrc + n, err
    34		}
    35	
    36		if err == nil && n < len(src) && !atEOF {
    37			err = transform.ErrShortSrc
    38		}
    39		return n, n, err
    40	}
    41	
    42	func flushTransform(rb *reorderBuffer) bool {
    43		// Write out (must fully fit in dst, or else it is an ErrShortDst).
    44		if len(rb.out) < rb.nrune*utf8.UTFMax {
    45			return false
    46		}
    47		rb.out = rb.out[rb.flushCopy(rb.out):]
    48		return true
    49	}
    50	
    51	var errs = []error{nil, transform.ErrShortDst, transform.ErrShortSrc}
    52	
    53	// transform implements the transform.Transformer interface. It is only called
    54	// when quickSpan does not pass for a given string.
    55	func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
    56		// TODO: get rid of reorderBuffer. See CL 23460044.
    57		rb := reorderBuffer{}
    58		rb.init(f, src)
    59		for {
    60			// Load segment into reorder buffer.
    61			rb.setFlusher(dst[nDst:], flushTransform)
    62			end := decomposeSegment(&rb, nSrc, atEOF)
    63			if end < 0 {
    64				return nDst, nSrc, errs[-end]
    65			}
    66			nDst = len(dst) - len(rb.out)
    67			nSrc = end
    68	
    69			// Next quickSpan.
    70			end = rb.nsrc
    71			eof := atEOF
    72			if n := nSrc + len(dst) - nDst; n < end {
    73				err = transform.ErrShortDst
    74				end = n
    75				eof = false
    76			}
    77			end, ok := rb.f.quickSpan(rb.src, nSrc, end, eof)
    78			n := copy(dst[nDst:], rb.src.bytes[nSrc:end])
    79			nSrc += n
    80			nDst += n
    81			if ok {
    82				if err == nil && n < rb.nsrc && !atEOF {
    83					err = transform.ErrShortSrc
    84				}
    85				return nDst, nSrc, err
    86			}
    87		}
    88	}
    89	

View as plain text