-
Notifications
You must be signed in to change notification settings - Fork 0
/
binarytreereader.go
105 lines (96 loc) · 1.53 KB
/
binarytreereader.go
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
const (
nodeStart = 0xfe
nodeEnd = 0xff
escapeChar = 0xfd
)
type BinaryTreeReader struct {
BinaryNode
}
func NewBinaryTreeReader(data []byte) *BinaryTreeReader {
return &BinaryTreeReader{
BinaryNode{
buffer: data,
},
}
}
func (b *BinaryTreeReader) GetNode() *BinaryNode {
if !b.advance() {
panic("advance")
}
return b.getNodeData()
}
func (b *BinaryTreeReader) GetNextNode() *BinaryNode {
value := b.ReadU8()
if value != nodeStart {
return nil
}
value = b.ReadU8()
level := 1
for {
value = b.ReadU8()
switch value {
case nodeEnd:
level--
if level == 0 {
value = b.ReadU8()
if value != nodeStart {
return nil
}
b.index--
return b.getNodeData()
}
case nodeStart:
level++
case escapeChar:
b.ReadU8()
}
}
}
func (b *BinaryTreeReader) getNodeData() *BinaryNode {
start := b.index
value := b.ReadU8()
if value != nodeStart {
return nil
}
var node []byte
for {
value = b.ReadU8()
if value == nodeEnd || value == nodeStart {
break
}
if value == escapeChar {
value = b.ReadU8()
}
node = append(node, value)
}
b.index = start
return &BinaryNode{node, 0}
}
func (b *BinaryTreeReader) advance() bool {
start := false
if b.index == 0 {
start = true
b.index = 4
}
if b.ReadU8() != nodeStart {
return false
}
if start {
b.index--
return true
}
value := b.ReadU8()
for {
value = b.ReadU8()
switch value {
case nodeEnd:
return false
case nodeStart:
b.index--
return true
case escapeChar:
b.ReadU8()
}
}
}