|  | // Copyright 2010 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package cipher | 
|  |  | 
|  | import "io" | 
|  |  | 
|  | // The Stream* objects are so simple that all their members are public. Users | 
|  | // can create them themselves. | 
|  |  | 
|  | // StreamReader wraps a Stream into an io.Reader. It calls XORKeyStream | 
|  | // to process each slice of data which passes through. | 
|  | type StreamReader struct { | 
|  | S Stream | 
|  | R io.Reader | 
|  | } | 
|  |  | 
|  | func (r StreamReader) Read(dst []byte) (n int, err error) { | 
|  | n, err = r.R.Read(dst) | 
|  | r.S.XORKeyStream(dst[:n], dst[:n]) | 
|  | return | 
|  | } | 
|  |  | 
|  | // StreamWriter wraps a Stream into an io.Writer. It calls XORKeyStream | 
|  | // to process each slice of data which passes through. If any Write call | 
|  | // returns short then the StreamWriter is out of sync and must be discarded. | 
|  | // A StreamWriter has no internal buffering; Close does not need | 
|  | // to be called to flush write data. | 
|  | type StreamWriter struct { | 
|  | S   Stream | 
|  | W   io.Writer | 
|  | Err error // unused | 
|  | } | 
|  |  | 
|  | func (w StreamWriter) Write(src []byte) (n int, err error) { | 
|  | c := make([]byte, len(src)) | 
|  | w.S.XORKeyStream(c, src) | 
|  | n, err = w.W.Write(c) | 
|  | if n != len(src) && err == nil { // should never happen | 
|  | err = io.ErrShortWrite | 
|  | } | 
|  | return | 
|  | } | 
|  |  | 
|  | // Close closes the underlying Writer and returns its Close return value, if the Writer | 
|  | // is also an io.Closer. Otherwise it returns nil. | 
|  | func (w StreamWriter) Close() error { | 
|  | if c, ok := w.W.(io.Closer); ok { | 
|  | return c.Close() | 
|  | } | 
|  | return nil | 
|  | } |