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