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