github.com/go-xe2/third@v1.0.3/golang.org/x/text/unicode/norm/transform.go (about) 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 "github.com/go-xe2/third/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 n := 0 22 // Cap the maximum number of src bytes to check. 23 b := src 24 eof := atEOF 25 if ns := len(dst); ns < len(b) { 26 err = transform.ErrShortDst 27 eof = false 28 b = b[:ns] 29 } 30 i, ok := formTable[f].quickSpan(inputBytes(b), n, len(b), eof) 31 n += copy(dst[n:], b[n:i]) 32 if !ok { 33 nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF) 34 return nDst + n, nSrc + n, err 35 } 36 if 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 n < rb.nsrc && !atEOF { 83 err = transform.ErrShortSrc 84 } 85 return nDst, nSrc, err 86 } 87 } 88 }