/
jsonutil.go
133 lines (97 loc) · 2.77 KB
/
jsonutil.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
// Package jsonutil provides methods for working with JSON data
package jsonutil
// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2024 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //
import (
"bufio"
"compress/gzip"
"encoding/json"
"io"
"os"
)
// ////////////////////////////////////////////////////////////////////////////////// //
// GzipLevel is default Gzip compression level
var GzipLevel = gzip.BestSpeed
// ////////////////////////////////////////////////////////////////////////////////// //
// Read reads and decode JSON file
func Read(file string, v any) error {
return readFile(file, v, false)
}
// ReadGz reads and decode gzipped JSON file
func ReadGz(file string, v any) error {
return readFile(file, v, true)
}
// Write encodes data to JSON and save it to file
func Write(file string, v any, perms ...os.FileMode) error {
return writeFile(file, v, perms, false)
}
// Write encodes data to gzipped JSON and save it to file
func WriteGz(file string, v any, perms ...os.FileMode) error {
return writeFile(file, v, perms, true)
}
// ////////////////////////////////////////////////////////////////////////////////// //
func readFile(file string, v any, compress bool) error {
fd, err := os.Open(file)
if err != nil {
return err
}
defer fd.Close()
return readData(fd, v, compress)
}
func readData(rw io.ReadWriter, v any, compress bool) error {
var err error
var dr io.Reader
r := bufio.NewReader(rw)
if compress {
dr, err = gzip.NewReader(r)
if err != nil {
return err
}
} else {
dr = r
}
return json.NewDecoder(dr).Decode(v)
}
func writeFile(file string, v any, perms []os.FileMode, compressed bool) error {
var perm os.FileMode = 0644
if len(perms) != 0 {
perm = perms[0]
}
fd, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
defer fd.Close()
return writeData(fd, v, compressed)
}
func writeData(rw io.ReadWriter, v any, compressed bool) error {
var err error
var je *json.Encoder
var gw *gzip.Writer
w := bufio.NewWriter(rw)
if compressed {
gw, err = gzip.NewWriterLevel(w, GzipLevel)
if err != nil {
return err
}
je = json.NewEncoder(gw)
} else {
je = json.NewEncoder(w)
}
je.SetIndent("", " ")
err = je.Encode(v)
if err != nil {
return err
}
if compressed {
err = gw.Close()
if err != nil {
return err
}
}
return w.Flush()
}