...

Source file src/pkg/vendor/golang.org/x/text/unicode/norm/readwriter.go

     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	}
   126	

View as plain text