1
2
3
4
5 package norm
6
7 import (
8 "unicode/utf8"
9
10 "golang.org/x/text/transform"
11 )
12
13
14 func (Form) Reset() {}
15
16
17
18
19
20 func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
21
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
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
54
55 func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
56
57 rb := reorderBuffer{}
58 rb.init(f, src)
59 for {
60
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
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