-
Notifications
You must be signed in to change notification settings - Fork 6
/
ini.go
201 lines (185 loc) · 4.44 KB
/
ini.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package config
import (
"strconv"
"strings"
)
// iniConfigPaser ini类型文件配置解析
func iniConfigPaser(data []byte) (Config, error) {
var config = newIniConfig()
var currentSection = config.GlobalSection().(*IniSection)
var dataLength = len(data)
if dataLength >= 3 && data[0] == 239 && data[1] == 187 && data[2] == 191 {
//去除BOM头
data = data[3:]
dataLength -= 3
}
for i := 0; i < dataLength; i++ {
var char = data[i]
//忽略空白字符
if char == ' ' || char == '\n' || char == '\r' {
continue
}
switch char {
case '#', ';':
{
//处理以#和;开头的注释文本
for j := i + 1; j < dataLength; j++ {
if data[j] == '\n' {
i = j
break
}
if j == dataLength-1 {
i = j + 1
}
}
}
case '[':
{
//处理[]段
var found = false
for j := i + 1; j < dataLength; j++ {
if !found && data[j] == ']' {
var sectionName = string(data[i+1 : j])
var section = newIniSection(sectionName)
config.sections[sectionName] = section
currentSection = section
found = true
}
if data[j] == '\n' || j == dataLength-1 {
if !found {
return nil, ErrorNotMatch.Format("]").Error()
}
i = j
break
}
}
}
default:
{
//处理key=value形式的内容
var keyFound = false
var keyEndPos = 0
var key = ""
var value = ""
for j := i + 1; j < dataLength; j++ {
if !keyFound && data[j] == '=' {
key = string(data[i:j])
keyEndPos = j
keyFound = true
}
if data[j] == '\n' || j == dataLength-1 {
if keyFound {
if j == dataLength-1 {
j++
}
value = string(data[keyEndPos+1 : j])
//忽略两头的空白字符
key = strings.TrimSpace(key)
value = strings.TrimSpace(value)
currentSection.add(key, value)
} else {
return nil, ErrorNotMatch.Format("=").Error()
}
i = j
break
}
}
}
}
}
return config, nil
}
// Ini配置
type IniConfig struct {
globalSection *IniSection //全局段
sections map[string]*IniSection //命名段
}
// newIniConfig 创建ini配置
func newIniConfig() *IniConfig {
return &IniConfig{
newIniSection(""),
make(map[string]*IniSection),
}
}
// GlobalSection 获取全局配置段
func (this *IniConfig) GlobalSection() Section {
return this.globalSection
}
// Section 根据name获取指定名称的配置段
func (this *IniConfig) Section(name string) (Section, bool) {
var section, ok = this.sections[name]
return section, ok
}
// Sections 返回全部节
func (this *IniConfig) Sections() []Section {
var arr = make([]Section, 0, len(this.sections))
for _, c := range this.sections {
arr = append(arr, c)
}
return arr
}
// Ini配置段
type IniSection struct {
name string //段名称
kvs map[string]string //键值map
}
// newIniSection 创建ini配置段
func newIniSection(name string) *IniSection {
var section = &IniSection{
name,
make(map[string]string),
}
return section
}
// Name 配置段名称
func (this *IniSection) Name() string {
return this.name
}
// add 添加键值对,对于同名key,后添加的有效
func (this *IniSection) add(key, value string) {
this.kvs[key] = value
}
// String 获取字符串
func (this *IniSection) String(key string) (string, error) {
var value, ok = this.kvs[key]
if ok {
return value, nil
}
return "", ErrorInvalidKey.Format(key).Error()
}
// Int 获取整数
func (this *IniSection) Int(key string) (int, error) {
var value, ok = this.kvs[key]
if ok {
var result, err = strconv.ParseInt(value, 0, 64)
if err == nil {
return int(result), nil
}
return 0, ErrorInvalidTypeConvertion.Format(value, "int64").Error()
}
return 0, ErrorInvalidKey.Format(key).Error()
}
// Bool 获取布尔值
func (this *IniSection) Bool(key string) (bool, error) {
var value, ok = this.kvs[key]
if ok {
var result, err = strconv.ParseBool(value)
if err == nil {
return result, nil
}
return false, ErrorInvalidTypeConvertion.Format(value, "bool").Error()
}
return false, ErrorInvalidKey.Format(key).Error()
}
// Float 获取浮点值
func (this *IniSection) Float(key string) (float64, error) {
var value, ok = this.kvs[key]
if ok {
var result, err = strconv.ParseFloat(value, 64)
if err == nil {
return result, nil
}
return 0.0, ErrorInvalidTypeConvertion.Format(value, "float64").Error()
}
return 0.0, ErrorInvalidKey.Format(key).Error()
}