forked from hprose/hprose-golang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.go
145 lines (130 loc) · 3.81 KB
/
filter.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
136
137
138
139
140
141
142
143
144
145
/**********************************************************\
| |
| hprose |
| |
| Official WebSite: http://www.hprose.com/ |
| http://www.hprose.org/ |
| |
\**********************************************************/
/**********************************************************\
* *
* rpc/filter.go *
* *
* hprose filter interface for Go. *
* *
* LastModified: Sep 28, 2017 *
* Author: Ma Bingyao <andot@hprose.com> *
* *
\**********************************************************/
package rpc
import "sync"
// Filter is hprose filter
type Filter interface {
InputFilter(data []byte, context Context) []byte
OutputFilter(data []byte, context Context) []byte
}
// filterManager is the filter manager
type filterManager struct {
filters []Filter
fmLocker sync.RWMutex
}
// Filter return the first filter
func (fm *filterManager) Filter() Filter {
fm.fmLocker.RLock()
defer fm.fmLocker.RUnlock()
if len(fm.filters) == 0 {
return nil
}
return fm.filters[0]
}
// NumFilter return the filter count
func (fm *filterManager) NumFilter() int {
fm.fmLocker.RLock()
defer fm.fmLocker.RUnlock()
return len(fm.filters)
}
// FilterByIndex return the filter by index
func (fm *filterManager) FilterByIndex(index int) Filter {
fm.fmLocker.RLock()
defer fm.fmLocker.RUnlock()
n := len(fm.filters)
if index < 0 && index >= n {
return nil
}
return fm.filters[index]
}
func (fm *filterManager) addFilter(filter ...Filter) {
if len(filter) > 0 {
fm.filters = append(fm.filters, filter...)
}
}
// SetFilter will replace the current filter settings
func (fm *filterManager) SetFilter(filter ...Filter) {
fm.fmLocker.Lock()
fm.filters = make([]Filter, len(filter))
fm.addFilter(filter...)
fm.fmLocker.Unlock()
}
// AddFilter add the filter to this FilterManager
func (fm *filterManager) AddFilter(filter ...Filter) {
fm.fmLocker.Lock()
fm.addFilter(filter...)
fm.fmLocker.Unlock()
}
// RemoveFilterByIndex remove the filter by the index
func (fm *filterManager) RemoveFilterByIndex(index int) {
fm.fmLocker.Lock()
n := len(fm.filters)
if index < 0 && index >= n {
fm.fmLocker.Unlock()
return
}
if index == n-1 {
fm.filters = fm.filters[:index]
} else {
fm.filters = append(fm.filters[:index], fm.filters[index+1:]...)
}
fm.fmLocker.Unlock()
}
func (fm *filterManager) removeFilter(filter Filter) {
for i := range fm.filters {
if fm.filters[i] == filter {
fm.RemoveFilterByIndex(i)
return
}
}
}
// RemoveFilter remove the filter from this FilterManager
func (fm *filterManager) RemoveFilter(filter ...Filter) {
for i := range filter {
fm.removeFilter(filter[i])
}
}
func (fm *filterManager) inputFilter(data []byte, context Context) (out []byte, err error) {
fm.fmLocker.RLock()
defer func() {
if e := recover(); e != nil {
err = NewPanicError(e)
}
fm.fmLocker.RUnlock()
}()
for i := len(fm.filters) - 1; i >= 0; i-- {
data = fm.filters[i].InputFilter(data, context)
}
out = data
return
}
func (fm *filterManager) outputFilter(data []byte, context Context) (out []byte, err error) {
fm.fmLocker.RLock()
defer func() {
if e := recover(); e != nil {
err = NewPanicError(e)
}
defer fm.fmLocker.RUnlock()
}()
for i := range fm.filters {
data = fm.filters[i].OutputFilter(data, context)
}
out = data
return
}