-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathstate.go
108 lines (94 loc) · 2.37 KB
/
state.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
106
107
108
package goP2
import "fmt"
// State 是基本的状态操作接口
type State interface {
Pos() int
SeekTo(int) bool
Next() (interface{}, error)
Trap(message string, args ...interface{}) error
Begin() int
Commit(int)
Rollback(int)
}
// BasicState 实现最基本的 State 操作
type BasicState struct {
buffer []interface{}
index int
begin int
}
// NewBasicState 构造一个新的 BasicState
func NewBasicState(data []interface{}) BasicState {
buffer := make([]interface{}, len(data))
copy(buffer, data)
return BasicState{
buffer,
0,
-1,
}
}
// BasicStateFromText 构造一个新的 BasicState
func BasicStateFromText(str string) BasicState {
data := []rune(str)
buffer := make([]interface{}, 0, len(data))
for _, r := range data {
buffer = append(buffer, r)
}
return BasicState{
buffer,
0,
-1,
}
}
// Pos 返回 state 的当前位置
func (state *BasicState) Pos() int {
return state.index
}
//SeekTo 将指针移动到指定位置
func (state *BasicState) SeekTo(pos int) bool {
if 0 <= pos && pos < len(state.buffer) {
state.index = pos
return true
}
return false
}
// Next 实现迭代逻辑
func (state *BasicState) Next() (interface{}, error) {
if state.index == len(state.buffer) {
return nil, state.Trap("eof")
}
re := state.buffer[state.index]
state.index++
return re, nil
}
// Trap 是构造错误信息的辅助函数,它传递错误的位置,并提供字符串格式化功能
func (state *BasicState) Trap(message string, args ...interface{}) error {
return Error{state.index, fmt.Sprintf(message, args...)}
}
// Begin 开始一个事务并返回事务号,State 的 Begin 总是记录比较靠后的位置。
func (state *BasicState) Begin() int {
if state.begin == -1 {
state.begin = state.Pos()
}
return state.Pos()
}
// Commit 提交一个事务,将其从注册状态中删除,将事务位置保存为比较靠前的位置
func (state *BasicState) Commit(tran int) {
if state.begin == tran {
state.begin = -1
}
}
// Rollback 取消一个事务,将 pos 移动到 该位置,将事务位置保存为比较靠前的位置
func (state *BasicState) Rollback(tran int) {
state.SeekTo(tran)
if state.begin == tran {
state.begin = -1
}
}
// Error 实现基本的错误信息结构
type Error struct {
Pos int
Message string
}
func (e Error) Error() string {
return fmt.Sprintf("stop at %d : %v", e.Pos, e.Message)
}