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 [StreamWriter.Write] 27 // call returns short then the StreamWriter is out of sync and must be discarded. 28 // A StreamWriter has no internal buffering; [StreamWriter.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) && err == nil { // should never happen 41 err = io.ErrShortWrite 42 } 43 return 44 } 45 46 // Close closes the underlying Writer and returns its Close return value, if the Writer 47 // is also an io.Closer. Otherwise it returns nil. 48 func (w StreamWriter) Close() error { 49 if c, ok := w.W.(io.Closer); ok { 50 return c.Close() 51 } 52 return nil 53 } 54