1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
package binproto
type urReturn struct {
ut UnitType
data interface{}
}
type Demux struct {
ur UnitReader
events, other chan urReturn
err error
}
func NewDemux(ur UnitReader) (d *Demux) {
d = &Demux{
ur: ur,
events: make(chan urReturn),
other: make(chan urReturn),
err: nil}
go d.demux()
return
}
func (d *Demux) demux() {
inEvent := false
nesting := 0
for {
ut, data, err := d.ur.ReadUnit()
if err != nil {
d.err = err
close(d.events)
close(d.other)
return
}
if inEvent {
switch ut {
case UTList, UTIdKVMap, UTTextKVMap:
nesting++
case UTTerm:
nesting--
}
d.events <- urReturn{ut, data}
if nesting <= 0 {
inEvent = false
}
} else if ut == UTEvent {
d.events <- urReturn{ut, data}
inEvent = true
nesting = 0
} else {
d.other <- urReturn{ut, data}
}
}
}
type PartUnitReader struct {
ch chan urReturn
d *Demux
}
func (d *Demux) Events() *PartUnitReader { return &PartUnitReader{d.events, d} }
func (d *Demux) Other() *PartUnitReader { return &PartUnitReader{d.other, d} }
func (pur *PartUnitReader) ReadUnit() (UnitType, interface{}, error) {
urr, ok := <-pur.ch
if !ok {
return 0, nil, pur.d.err
}
return urr.ut, urr.data, nil
}
|