blob: 18c4c254039d4750c8b96b623aad31f14d77a1ae (
plain) (
blame)
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
|
package ini
import (
"fmt"
"strings"
"sync"
)
// Section represents a section in an INI file. The section has a name, which is
// enclosed in square brackets in the file. The section also has an array of
// key/value pairs.
type Section struct {
name string
props map[string]string
mtx sync.RWMutex
}
func newSection(name string) *Section {
sec := &Section{}
sec.name = name
sec.props = make(map[string]string)
return sec
}
// addLines addes an array of strings containing name/value pairs
// of the format `key=value`.
//func addLines(lines []string) {
// TODO
//}
// GetName returns the name of the section.
func (sec *Section) GetName() (name string) {
sec.mtx.RLock()
name = sec.name
sec.mtx.RUnlock()
return
}
// GetProp returns the value associated with the given key, or
// `ok=false` if key does not exist.
func (sec *Section) GetProp(key string) (val string, ok bool) {
sec.mtx.RLock()
val, ok = sec.props[key]
sec.mtx.RUnlock()
return
}
// SetProp sets the value associated with the given key.
func (sec *Section) setProp(key string, val string) {
sec.mtx.Lock()
sec.props[key] = val
sec.mtx.Unlock()
}
// hasKeys returns true if there are one or more properties in
// this section.
func (sec *Section) hasKeys() (b bool) {
sec.mtx.RLock()
b = len(sec.props) > 0
sec.mtx.RUnlock()
return
}
// getKeys returns an array containing all keys in this section.
func (sec *Section) getKeys() []string {
sec.mtx.RLock()
defer sec.mtx.RUnlock()
arr := make([]string, len(sec.props))
idx := 0
for k := range sec.props {
arr[idx] = k
idx++
}
return arr
}
// combine the given section with this one.
func (sec *Section) combine(sec2 *Section) {
sec.mtx.Lock()
sec2.mtx.RLock()
defer sec.mtx.Unlock()
defer sec2.mtx.RUnlock()
for k, v := range sec2.props {
sec.props[k] = v
}
}
// String returns a string representation of this section.
func (sec *Section) String() string {
return fmt.Sprintf("[%s]\n%s", sec.GetName(), sec.StringPropsOnly())
}
// StringPropsOnly returns a string representation of this section
// without the section header.
func (sec *Section) StringPropsOnly() string {
sec.mtx.RLock()
defer sec.mtx.RUnlock()
sb := &strings.Builder{}
for k, v := range sec.props {
sb.WriteString(k)
sb.WriteString("=")
sb.WriteString(v)
sb.WriteString("\n")
}
return sb.String()
}
|