OSDN Git Service

e3d733cb02192e24c194c9e18a8a9ecb9b390825
[pf3gnuchains/gcc-fork.git] / libgo / go / crypto / openpgp / packet / reader.go
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         error_ "crypto/openpgp/error"
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.(error_.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 }