Source file src/pkg/crypto/cipher/io.go
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 type StreamWriter struct {
29 S Stream
30 W io.Writer
31 Err error
32 }
33
34 func (w StreamWriter) Write(src []byte) (n int, err error) {
35 if w.Err != nil {
36 return 0, w.Err
37 }
38 c := make([]byte, len(src))
39 w.S.XORKeyStream(c, src)
40 n, err = w.W.Write(c)
41 if n != len(src) {
42 if err == nil { // should never happen
43 err = io.ErrShortWrite
44 }
45 w.Err = err
46 }
47 return
48 }
49
50 func (w StreamWriter) Close() error {
51 // This saves us from either requiring a WriteCloser or having a
52 // StreamWriterCloser.
53 return w.W.(io.Closer).Close()
54 }