github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/crypto/cipher/io.go (about)

     1  // Copyright 2010 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 cipher
     6  
     7  import "io"
     8  
     9  // The Stream* objects are so simple that all their members are public. Users
    10  // can create them themselves.
    11  
    12  // StreamReader wraps a Stream into an io.Reader. It calls XORKeyStream
    13  // to process each slice of data which passes through.
    14  type StreamReader struct {
    15  	S Stream
    16  	R io.Reader
    17  }
    18  
    19  func (r StreamReader) Read(dst []byte) (n int, err error) {
    20  	n, err = r.R.Read(dst)
    21  	r.S.XORKeyStream(dst[:n], dst[:n])
    22  	return
    23  }
    24  
    25  // StreamWriter wraps a Stream into an io.Writer. It calls XORKeyStream
    26  // to process each slice of data which passes through. If any Write call
    27  // returns short then the StreamWriter is out of sync and must be discarded.
    28  // A StreamWriter has no internal buffering; Close does not need
    29  // to be called to flush write data.
    30  type StreamWriter struct {
    31  	S   Stream
    32  	W   io.Writer
    33  	Err error // unused
    34  }
    35  
    36  func (w StreamWriter) Write(src []byte) (n int, err error) {
    37  	c := make([]byte, len(src))
    38  	w.S.XORKeyStream(c, src)
    39  	n, err = w.W.Write(c)
    40  	if n != len(src) {
    41  		if err == nil { // should never happen
    42  			err = io.ErrShortWrite
    43  		}
    44  	}
    45  	return
    46  }
    47  
    48  // Close closes the underlying Writer and returns its Close return value, if the Writer
    49  // is also an io.Closer. Otherwise it returns nil.
    50  func (w StreamWriter) Close() error {
    51  	if c, ok := w.W.(io.Closer); ok {
    52  		return c.Close()
    53  	}
    54  	return nil
    55  }