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 5package cipher 6 7import "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. 14type StreamReader struct { 15 S Stream 16 R io.Reader 17} 18 19func (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. 30type StreamWriter struct { 31 S Stream 32 W io.Writer 33 Err error // unused 34} 35 36func (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. 48func (w StreamWriter) Close() error { 49 if c, ok := w.W.(io.Closer); ok { 50 return c.Close() 51 } 52 return nil 53} 54