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  }