-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxmlpathtype.go
135 lines (126 loc) · 2.84 KB
/
xmlpathtype.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package gluaxmlpath
import (
"github.com/yuin/gopher-lua"
xmlpath "gopkg.in/xmlpath.v2"
)
type Node struct {
base *xmlpath.Node
}
type Path struct {
base *xmlpath.Path
}
type Iter struct {
base *xmlpath.Iter
}
const luaNodeTypeName = "xmlpath.node"
const luaPathTypeName = "xmlpath.path"
const luaIterTypeName = "xmlpath.iter"
func registerType(L *lua.LState, module *lua.LTable) {
//reg node
nodemt := L.NewTypeMetatable(luaNodeTypeName)
L.SetField(module, "node", nodemt)
L.SetField(nodemt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
"string": nodeString,
}))
//reg path
pathmt := L.NewTypeMetatable(luaPathTypeName)
L.SetField(module, "path", pathmt)
L.SetField(pathmt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
"iter": iter,
}))
//reg iter
itermt := L.NewTypeMetatable(luaIterTypeName)
L.SetField(module, "iter", itermt)
L.SetField(itermt, "__index", L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
//"next": next,
"node": node,
}))
}
func newNode(L *lua.LState, n *xmlpath.Node) *lua.LUserData {
ud := L.NewUserData()
ud.Value = &Node{
n,
}
L.SetMetatable(ud, L.GetTypeMetatable(luaNodeTypeName))
return ud
}
func checkNode(L *lua.LState) *Node {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*Node); ok {
return v
}
L.ArgError(1, "node expected")
return nil
}
func newPath(L *lua.LState, p *xmlpath.Path) *lua.LUserData {
ud := L.NewUserData()
ud.Value = &Path{
p,
}
L.SetMetatable(ud, L.GetTypeMetatable(luaPathTypeName))
return ud
}
func checkPath(L *lua.LState) *Path {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*Path); ok {
return v
}
L.ArgError(1, "path expected")
return nil
}
func newIter(L *lua.LState, i *xmlpath.Iter) *lua.LUserData {
ud := L.NewUserData()
ud.Value = &Iter{
i,
}
L.SetMetatable(ud, L.GetTypeMetatable(luaIterTypeName))
return ud
}
func checkIter(L *lua.LState) *Iter {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*Iter); ok {
return v
}
L.ArgError(1, "iter expected")
return nil
}
//iter := path.iter(node)
func iter(L *lua.LState) int {
path := checkPath(L)
if L.GetTop() == 2 {
ut := L.CheckUserData(2)
if node, ok := ut.Value.(*Node); ok {
it := path.base.Iter(node.base)
ltab := L.NewTable()
i := 1
for it.Next() {
L.RawSetInt(ltab, i, newNode(L, it.Node()))
i++
}
L.Push(ltab)
//L.Push(newIter(L, it))
return 1
}
}
L.ArgError(1, "node expected")
return 0
}
//support lua standard iterator
//hasNext := iter.next()
// func next(L *lua.LState) int {
// iter := checkIter(L)
// L.Push(lua.LBool(iter.base.Next()))
// return 1
// }
//node := iter.node()
func node(L *lua.LState) int {
iter := checkIter(L)
L.Push(newNode(L, iter.base.Node()))
return 1
}
//string := node.string()
func nodeString(L *lua.LState) int {
node := checkNode(L)
L.Push(lua.LString(node.base.String()))
return 1
}