/
utils.go
151 lines (123 loc) · 2.98 KB
/
utils.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
146
147
148
149
150
151
package cidre
import (
"crypto/hmac"
"crypto/sha1"
"errors"
"fmt"
"reflect"
"strings"
)
/* DynamicObjectFactory {{{ */
type dynamicObjectFactory map[string]reflect.Type
var dynamicObjectFactoryCh = make(chan bool, 1)
// DynamicObjectFactory provides functions to create an object by string name.
//
// package mypackage
//
// type MyObject struct {}
// DynamicObjectFactory.Register(MyObject{})
// DynamicObjectFactory.New("mypackage.MyObject")
var DynamicObjectFactory = make(dynamicObjectFactory)
func (self dynamicObjectFactory) Register(infs ...interface{}) {
dynamicObjectFactoryCh <- true
defer func() { <-dynamicObjectFactoryCh }()
for _, inf := range infs {
typ := reflect.TypeOf(inf)
self[typ.String()] = typ
}
}
func (self dynamicObjectFactory) New(name string) interface{} {
dynamicObjectFactoryCh <- true
defer func() { <-dynamicObjectFactoryCh }()
typ, ok := self[name]
if !ok {
panic("DynamicObjectFactory: type name " + name + " not found.")
}
return reflect.New(typ).Interface()
}
// }}}
/* {{{ */
// Dict is a Python's dict like object.
type Dict map[string]interface{}
func NewDict() Dict {
return make(Dict)
}
func (self Dict) Update(other map[string]interface{}) {
for key, value := range other {
self[key] = value
}
}
func (self Dict) Copy(other map[string]interface{}) {
Dict(other).Update(self)
}
func (self Dict) Pop(key string) interface{} {
v := self.Get(key)
self.Del(key)
return v
}
func (self Dict) Get(key string) interface{} {
return self[key]
}
func (self Dict) GetOr(key string, value interface{}) interface{} {
if self.Has(key) {
return self.Get(key)
} else {
return value
}
}
func (self Dict) Has(key string) bool {
_, ok := self[key]
return ok
}
func (self Dict) GetString(key string) string {
if v, ok := self[key]; ok {
return v.(string)
} else {
return ""
}
}
func (self Dict) GetInt(key string) int {
if v, ok := self[key]; ok {
return v.(int)
} else {
return 0
}
}
func (self Dict) GetBool(key string) bool {
if v, ok := self[key]; ok {
return v.(bool)
} else {
return false
}
}
func (self Dict) Set(key string, value interface{}) Dict {
self[key] = value
return self
}
func (self Dict) Del(key string) Dict {
delete(self, key)
return self
}
//}}}
// String utils {{{
// Returns a string that is the concatenation of the strings in efficient way.
func BuildString(ca int, ss ...string) string {
buf := make([]byte, 0, ca)
for _, s := range ss {
buf = append(buf, s...)
}
return string(buf)
}
// Returns a string with a HMAC signature.
func SignString(value, key string) string {
return fmt.Sprintf("%x----%s", hmac.New(sha1.New, []byte(key)).Sum([]byte(value)), value)
}
// Returns a string if HMAC signature is valid.
func ValidateSignedString(value, key string) (string, error) {
parts := strings.SplitN(value, "----", 2)
if parts[0] == fmt.Sprintf("%x", hmac.New(sha1.New, []byte(key)).Sum([]byte(parts[1]))) {
return parts[1], nil
}
return "", errors.New("data is tampered")
}
// }}}