-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
98 lines (85 loc) · 2.13 KB
/
config.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
package beego
import (
"bufio"
"bytes"
"io"
"os"
"strconv"
"strings"
"sync"
"unicode"
)
var (
bComment = []byte{'#'}
bEmpty = []byte{}
bEqual = []byte{'='}
bDQuote = []byte{'"'}
)
type Config struct {
filename string
comment map[int][]string
data map[string]string
offset map[string]int64
sync.RWMutex
}
func LoadConfig(name string) (*Config, error) {
file, err := os.Open(name)
if err != nil {
return nil, err
}
cfg := &Config{
file.Name(),
make(map[int][]string),
make(map[string]string),
make(map[string]int64),
sync.RWMutex{},
}
cfg.Lock()
defer cfg.Unlock()
defer file.Close()
var comment bytes.Buffer
buf := bufio.NewReader(file)
for nComment, off := 0, int64(1); ; {
line, _, err := buf.ReadLine()
if err == io.EOF {
break
}
if bytes.Equal(line, bEmpty) {
continue
}
off += int64(len(line))
if bytes.HasPrefix(line, bComment) {
line = bytes.TrimLeft(line, "#")
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
comment.Write(line)
comment.WriteByte('\n')
continue
}
if comment.Len() != 0 {
cfg.comment[nComment] = []string{comment.String()}
comment.Reset()
nComment++
}
val := bytes.SplitN(line, bEqual, 2)
if bytes.HasPrefix(val[1], bDQuote) {
val[1] = bytes.Trim(val[1], `"`)
}
key := strings.TrimSpace(string(val[0]))
cfg.comment[nComment-1] = append(cfg.comment[nComment-1], key)
cfg.data[key] = strings.TrimSpace(string(val[1]))
cfg.offset[key] = off
}
return cfg, nil
}
func (c *Config) Bool(key string) (bool, error) {
return strconv.ParseBool(c.data[key])
}
func (c *Config) Int(key string) (int, error) {
return strconv.Atoi(c.data[key])
}
func (c *Config) Float(key string) (float64, error) {
return strconv.ParseFloat(c.data[key], 64)
}
func (c *Config) String(key string) string {
return c.data[key]
}