Home | History | Annotate | Download | only in cipher
      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 // A StreamWriter has no internal buffering; 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