forked from vaughan0/go-ini
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fileio.go
128 lines (121 loc) · 3.08 KB
/
fileio.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
package ini
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"os"
"sort"
"strings"
)
// Loads INI data from a reader and stores the data in the File.
func (f *file) ReadFrom(in io.Reader) (n int64, err error) {
n = 0
scanner := bufio.NewScanner(in)
n, err = parseFile(scanner, f)
return
}
// Loads INI data from a named file and stores the data in the File.
func (f *file) LoadFile(file string) (err error) {
in, err := os.Open(file)
if err != nil {
return
}
defer in.Close()
_, err = f.ReadFrom(in)
return
}
// Write out an INI File representing the current state to a writer.
func (f *file) WriteTo(out io.Writer) (n int64, err error) {
orderedSections := make([]string, len(f.sections))
counter := 0
n = 0
thisWrite := 0
for section, _ := range f.sections {
orderedSections[counter] = section
counter++
}
sort.Strings(orderedSections)
for _, section := range orderedSections {
options := f.sections[section]
thisWrite, err = fmt.Fprintln(out, "["+section+"]")
n += int64(thisWrite)
if (err) != nil {
return
}
orderedStringKeys := make([]string, len(options.stringValues))
counter = 0
for key, _ := range options.stringValues {
orderedStringKeys[counter] = key
counter++
}
sort.Strings(orderedStringKeys)
for _, key := range orderedStringKeys {
thisWrite, err = fmt.Fprintln(out, key, "=", options.stringValues[key])
n += int64(thisWrite)
if (err) != nil {
return
}
}
orderedArrayKeys := make([]string, len(options.arrayValues))
counter = 0
for key, _ := range options.arrayValues {
orderedArrayKeys[counter] = key
counter++
}
sort.Strings(orderedArrayKeys)
for _, key := range orderedArrayKeys {
for _, value := range options.arrayValues[key] {
thisWrite, err = fmt.Fprintln(out, key, "[]=", value)
n += int64(thisWrite)
if (err) != nil {
return
}
}
}
thisWrite, err = fmt.Fprintln(out)
n += int64(thisWrite)
if (err) != nil {
return
}
}
return
}
// Load ini data from the bytestream provided
// This is provided so that data can be loaded by treating File as an io.Writer
func (f *file) Write(p []byte) (n int, err error) {
reader := strings.NewReader(string(p))
var m int64 = 0
m, err = f.ReadFrom(reader)
n = int(m)
if n != len(p) && err == nil {
err = errors.New("Internal error: failed to write")
}
return
}
// Write out ini data to the bytestream provided
// This is provided so that data can be saved by treating File as an io.Reader
// The returned stream is a consistent representation of the ini file when the read started
// Call close to start a new read from a freshly serialized file
func (f *file) Read(p []byte) (n int, err error) {
n = 0
if f.reader == nil {
buf := new(bytes.Buffer)
_, err = f.WriteTo(buf)
if err != nil {
return
}
f.reader = buf
}
n, err = f.reader.Read(p)
return
}
// Close a read stream
// This is semantically a ReaderCloser, in that it does not affect Write
// After a call to Close() a subsequent Read() will start from the beginning (and reflect any new changes)
func (f *file) Close() (err error) {
err = nil
f.reader = nil
return
}