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.
9 type normWriter struct {
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.
23 // Normalize into w.buf.
28 w.rb.src = inputBytes(data[:m])
30 w.buf = doAppend(&w.rb, w.buf, 0)
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)
41 if _, err = w.w.Write(w.buf[:i]); err != nil {
44 bn := copy(w.buf, w.buf[i:])
51 // Close forces data that remains in the buffer to be written.
52 func (w *normWriter) Close() error {
54 _, err := w.w.Write(w.buf)
62 // Writer returns a new writer that implements Write(b)
63 // by writing f(b) to w. The returned writer may use an
64 // an 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}
72 type normReader struct {
82 // Read implements the standard read interface.
83 func (r *normReader) Read(p []byte) (int, error) {
85 if r.lastBoundary-r.bufStart > 0 {
86 n := copy(p, r.outbuf[r.bufStart:r.lastBoundary])
88 if r.lastBoundary-r.bufStart > 0 {
96 outn := copy(r.outbuf, r.outbuf[r.lastBoundary:])
97 r.outbuf = r.outbuf[0:outn]
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
104 r.outbuf = doAppend(&r.rb, r.outbuf, 0)
107 r.lastBoundary = len(r.outbuf)
109 r.lastBoundary = lastBoundary(&r.rb.f, r.outbuf)
110 if r.lastBoundary == -1 {
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 {
121 buf := make([]byte, chunk)
122 rr := &normReader{rb: reorderBuffer{}, r: r, inbuf: buf}