reader.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Copyright 2011 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. package packet
  5. import (
  6. "code.google.com/p/go.crypto/openpgp/errors"
  7. "io"
  8. )
  9. // Reader reads packets from an io.Reader and allows packets to be 'unread' so
  10. // that they result from the next call to Next.
  11. type Reader struct {
  12. q []Packet
  13. readers []io.Reader
  14. }
  15. // Next returns the most recently unread Packet, or reads another packet from
  16. // the top-most io.Reader. Unknown packet types are skipped.
  17. func (r *Reader) Next() (p Packet, err error) {
  18. if len(r.q) > 0 {
  19. p = r.q[len(r.q)-1]
  20. r.q = r.q[:len(r.q)-1]
  21. return
  22. }
  23. for len(r.readers) > 0 {
  24. p, err = Read(r.readers[len(r.readers)-1])
  25. if err == nil {
  26. return
  27. }
  28. if err == io.EOF {
  29. r.readers = r.readers[:len(r.readers)-1]
  30. continue
  31. }
  32. if _, ok := err.(errors.UnknownPacketTypeError); !ok {
  33. return nil, err
  34. }
  35. }
  36. return nil, io.EOF
  37. }
  38. // Push causes the Reader to start reading from a new io.Reader. When an EOF
  39. // error is seen from the new io.Reader, it is popped and the Reader continues
  40. // to read from the next most recent io.Reader.
  41. func (r *Reader) Push(reader io.Reader) {
  42. r.readers = append(r.readers, reader)
  43. }
  44. // Unread causes the given Packet to be returned from the next call to Next.
  45. func (r *Reader) Unread(p Packet) {
  46. r.q = append(r.q, p)
  47. }
  48. func NewReader(r io.Reader) *Reader {
  49. return &Reader{
  50. q: nil,
  51. readers: []io.Reader{r},
  52. }
  53. }