-
Notifications
You must be signed in to change notification settings - Fork 1
/
properties.go
165 lines (146 loc) · 3.93 KB
/
properties.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
package properties
import (
"bufio"
"bytes"
"fmt"
"io"
"os"
"strings"
"sync"
)
// 创建一个空属性列表。
// Create an empty property list.
func NewProperties() *Properties {
return &Properties{
object: make(map[string]string),
}
}
type Properties struct {
m sync.Mutex
object map[string]string
}
// 用指定的键在此属性列表中搜索属性。
//
// Searches for the property with the specified key in this property list.
func (p *Properties) Property(key string) (value string, isExist bool) {
if value, ok := p.object[key]; !ok {
return "", false
} else {
return value, true
}
}
// 用指定的键在此属性列表中搜索属性,把","连接的多个属性转换为切片返回。
//
// Search for attributes in this attribute list using the specified key to return multiple attributes connected by "," converted to slices.
func (p *Properties) PropertySlice(key string) (values []string, isExist bool) {
strs, isExist := p.Property(key)
if !isExist {
return nil, false
}
return strings.Split(strs, ","), true
}
// 为指定的键设置多个属性,把多个属性值转换成“,”连接的属性字符串。
//
// Set multiple attributes for the specified key, converting multiple attribute values into a "," concatenated attribute string.
func (p *Properties) SetPropertySlice(key string, values ...string) {
value := strings.Join(values, ",")
p.SetProperty(key, value)
}
// 更新指定的键和属性,如果键不存在就新建。
//
// Update the specified key and properties. If the key does not exist, create a new one.
func (p *Properties) SetProperty(key, value string) {
p.m.Lock()
p.object[key] = value
p.m.Unlock()
}
// 从输入流读取属性列表。
//
// Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format.
func (p *Properties) Load(r io.Reader) error {
br := bufio.NewReader(r)
for {
line, _, err := br.ReadLine()
if err != nil {
if err == io.EOF {
break
} else {
return err
}
}
p.parseLine(line)
}
return nil
}
// 从文件中读取属性列表。
//
// Reads a property list from a file
func (p *Properties) LoadFromFile(filePath string) error {
f, err := os.Open(filePath)
defer f.Close()
if err != nil {
return fmt.Errorf("os.Open failed: %v", err)
}
return p.Load(f)
}
// 将属性列表写入输出流。
//
// Writes this property list (key and element pairs) in this Properties table to the output stream in a format suitable for loading into a Properties table using the Load() method.
func (p *Properties) Store(w io.Writer) error {
var buf bytes.Buffer
for k, v := range p.object {
p.line(k, v, &buf)
}
_, err := w.Write(buf.Bytes())
if err != nil {
return fmt.Errorf("w.Write failed: %v", err)
}
return nil
}
// 将属性列表写入文件。
//
// Writes a list of property to a file.
func (p *Properties) StoreToFile(filePath string) error {
f, err := os.Create(filePath)
defer f.Close()
if err != nil {
return fmt.Errorf("os.Open failed: %v", err)
}
return p.Store(f)
}
func (p *Properties) line(key, value string, buf *bytes.Buffer) {
buf.WriteString(key)
buf.WriteString(" = ")
buf.WriteString(value)
buf.WriteByte('\n')
}
func (p *Properties) parseLine(line []byte) {
lineStr := strings.TrimSpace(string(line))
if isCommentline(lineStr) {
return
}
splitStrs := strings.Split(lineStr, "=")
key := strings.TrimSpace(splitStrs[0])
value := strings.TrimSpace(splitStrs[1])
p.SetProperty(key, value)
}
// 返回属性列表中所有键的枚举。
//
// Returns an enumeration of all keys in the property list.
func (p *Properties) PropertyNames() []string {
var names []string
for k := range p.object {
names = append(names, k)
}
return names
}
// 过滤注释的行
func isCommentline(line string) bool {
if len(line) == 0 {
return true
}
if strings.HasPrefix(line, "#") || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "/*") {
return true
}
return false
}