2018-11-10 16:33:27 +00:00
|
|
|
package cnf
|
|
|
|
|
|
|
|
import (
|
2018-11-11 14:34:00 +00:00
|
|
|
lib "github.com/go-ini/ini"
|
2018-11-10 16:33:27 +00:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2018-11-11 14:34:00 +00:00
|
|
|
type ini struct {
|
2018-11-10 16:33:27 +00:00
|
|
|
sections []string
|
2018-11-11 14:34:00 +00:00
|
|
|
data *lib.File
|
2018-11-10 16:33:27 +00:00
|
|
|
parsed bool
|
|
|
|
}
|
|
|
|
|
2018-11-11 00:05:14 +00:00
|
|
|
// ReadFrom implements io.ReaderFrom
|
2018-11-11 14:34:00 +00:00
|
|
|
func (d *ini) ReadFrom(_reader io.Reader) (int64, error) {
|
2018-11-10 16:33:27 +00:00
|
|
|
|
2018-11-15 16:26:11 +00:00
|
|
|
// disallow "key: value"
|
|
|
|
// when trying to find out the format from content
|
|
|
|
// and avoids conflicts with YAML
|
|
|
|
opts := lib.LoadOptions{
|
|
|
|
KeyValueDelimiters: "=",
|
|
|
|
}
|
|
|
|
|
|
|
|
file, err := lib.LoadSources(opts, ioutil.NopCloser(_reader))
|
2018-11-10 16:33:27 +00:00
|
|
|
// 1. get json decoder
|
|
|
|
if err != nil {
|
2018-11-11 00:05:14 +00:00
|
|
|
return 0, err
|
2018-11-10 16:33:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
d.data = file
|
|
|
|
d.sections = file.SectionStrings()
|
|
|
|
d.parsed = true
|
2018-11-11 00:05:14 +00:00
|
|
|
return 0, nil
|
2018-11-10 16:33:27 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-11-11 00:05:14 +00:00
|
|
|
// WriteTo implements io.WriterTo
|
2018-11-11 14:34:00 +00:00
|
|
|
func (d *ini) WriteTo(_writer io.Writer) (int64, error) {
|
2018-11-11 00:05:14 +00:00
|
|
|
return d.data.WriteTo(_writer)
|
2018-11-10 16:33:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get returns the value of a dot-separated path, and if it exists
|
|
|
|
// the maximum depth is 2 : Section.Field
|
2018-11-11 14:34:00 +00:00
|
|
|
func (d *ini) Get(_path string) (string, bool) {
|
2018-11-10 16:33:27 +00:00
|
|
|
|
|
|
|
// 1. split path
|
|
|
|
path := strings.Split(_path, ".")
|
|
|
|
|
|
|
|
// 2. fail if too long
|
|
|
|
if len(path) > 2 {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. direct field (no section)
|
|
|
|
if len(path) == 1 {
|
|
|
|
// unknown field
|
|
|
|
if !d.data.Section("").Haskey(path[0]) {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
// found
|
|
|
|
return d.data.Section("").Key(path[0]).String(), true
|
|
|
|
}
|
|
|
|
|
|
|
|
// 4. fail on missing section
|
|
|
|
found := false
|
|
|
|
for _, sec := range d.sections {
|
|
|
|
if sec == path[0] {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
// 5. Fail on unknown field
|
|
|
|
if !d.data.Section(path[0]).HasKey(path[1]) {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
// 6. return value
|
|
|
|
return d.data.Section(path[0]).Key(path[1]).String(), true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the value of a dot-separated path, and creates it if not found
|
2018-11-11 14:34:00 +00:00
|
|
|
func (d *ini) Set(_path, _value string) bool {
|
2018-11-10 16:33:27 +00:00
|
|
|
|
|
|
|
// 1. split path
|
|
|
|
path := strings.Split(_path, ".")
|
|
|
|
|
|
|
|
// 2. fail if too long
|
|
|
|
if len(path) > 2 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// 3. direct field (no section)
|
|
|
|
section, field := "", path[0]
|
|
|
|
if len(path) > 1 {
|
|
|
|
section, field = path[0], path[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
// 4. Set field value
|
|
|
|
d.data.Section(section).Key(field).SetValue(_value)
|
|
|
|
return true
|
|
|
|
|
|
|
|
}
|