github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/golang.org/x/text/unicode/norm/readwriter.go (about) 1 // Copyright 2011 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 "io" 8 9 type normWriter struct { 10 rb reorderBuffer 11 w io.Writer 12 buf []byte 13 } 14 15 // Write implements the standard write interface. If the last characters are 16 // not at a normalization boundary, the bytes will be buffered for the next 17 // write. The remaining bytes will be written on close. 18 func (w *normWriter) Write(data []byte) (n int, err error) { 19 // Process data in pieces to keep w.buf size bounded. 20 const chunk = 4000 21 22 for len(data) > 0 { 23 // Normalize into w.buf. 24 m := len(data) 25 if m > chunk { 26 m = chunk 27 } 28 w.rb.src = inputBytes(data[:m]) 29 w.rb.nsrc = m 30 w.buf = doAppend(&w.rb, w.buf, 0) 31 data = data[m:] 32 n += m 33 34 // Write out complete prefix, save remainder. 35 // Note that lastBoundary looks back at most 31 runes. 36 i := lastBoundary(&w.rb.f, w.buf) 37 if i == -1 { 38 i = 0 39 } 40 if i > 0 { 41 if _, err = w.w.Write(w.buf[:i]); err != nil { 42 break 43 } 44 bn := copy(w.buf, w.buf[i:]) 45 w.buf = w.buf[:bn] 46 } 47 } 48 return n, err 49 } 50 51 // Close forces data that remains in the buffer to be written. 52 func (w *normWriter) Close() error { 53 if len(w.buf) > 0 { 54 _, err := w.w.Write(w.buf) 55 if err != nil { 56 return err 57 } 58 } 59 return nil 60 } 61 62 // Writer returns a new writer that implements Write(b) 63 // by writing f(b) to w. The returned writer may use an 64 // internal buffer to maintain state across Write calls. 65 // Calling its Close method writes any buffered data to w. 66 func (f Form) Writer(w io.Writer) io.WriteCloser { 67 wr := &normWriter{rb: reorderBuffer{}, w: w} 68 wr.rb.init(f, nil) 69 return wr 70 } 71 72 type normReader struct { 73 rb reorderBuffer 74 r io.Reader 75 inbuf []byte 76 outbuf []byte 77 bufStart int 78 lastBoundary int 79 err error 80 } 81 82 // Read implements the standard read interface. 83 func (r *normReader) Read(p []byte) (int, error) { 84 for { 85 if r.lastBoundary-r.bufStart > 0 { 86 n := copy(p, r.outbuf[r.bufStart:r.lastBoundary]) 87 r.bufStart += n 88 if r.lastBoundary-r.bufStart > 0 { 89 return n, nil 90 } 91 return n, r.err 92 } 93 if r.err != nil { 94 return 0, r.err 95 } 96 outn := copy(r.outbuf, r.outbuf[r.lastBoundary:]) 97 r.outbuf = r.outbuf[0:outn] 98 r.bufStart = 0 99 100 n, err := r.r.Read(r.inbuf) 101 r.rb.src = inputBytes(r.inbuf[0:n]) 102 r.rb.nsrc, r.err = n, err 103 if n > 0 { 104 r.outbuf = doAppend(&r.rb, r.outbuf, 0) 105 } 106 if err == io.EOF { 107 r.lastBoundary = len(r.outbuf) 108 } else { 109 r.lastBoundary = lastBoundary(&r.rb.f, r.outbuf) 110 if r.lastBoundary == -1 { 111 r.lastBoundary = 0 112 } 113 } 114 } 115 } 116 117 // Reader returns a new reader that implements Read 118 // by reading data from r and returning f(data). 119 func (f Form) Reader(r io.Reader) io.Reader { 120 const chunk = 4000 121 buf := make([]byte, chunk) 122 rr := &normReader{rb: reorderBuffer{}, r: r, inbuf: buf} 123 rr.rb.init(f, buf) 124 return rr 125 }