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 := []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