pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/jsonutil/jsonutil.go (about) 1 // Package jsonutil provides methods for working with JSON data 2 package jsonutil 3 4 // ////////////////////////////////////////////////////////////////////////////////// // 5 // // 6 // Copyright (c) 2022 ESSENTIAL KAOS // 7 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 8 // // 9 // ////////////////////////////////////////////////////////////////////////////////// // 10 11 import ( 12 "bufio" 13 "compress/gzip" 14 "encoding/json" 15 "io" 16 "os" 17 ) 18 19 // ////////////////////////////////////////////////////////////////////////////////// // 20 21 // GzipLevel is default Gzip compression level 22 var GzipLevel = gzip.BestSpeed 23 24 // ////////////////////////////////////////////////////////////////////////////////// // 25 26 // Read reads and decode JSON file 27 func Read(file string, v interface{}) error { 28 return readFile(file, v, false) 29 } 30 31 // ReadGz reads and decode gzipped JSON file 32 func ReadGz(file string, v interface{}) error { 33 return readFile(file, v, true) 34 } 35 36 // Write encodes data to JSON and save it to file 37 func Write(file string, v interface{}, perms ...os.FileMode) error { 38 return writeFile(file, v, perms, false) 39 } 40 41 // Write encodes data to gzipped JSON and save it to file 42 func WriteGz(file string, v interface{}, perms ...os.FileMode) error { 43 return writeFile(file, v, perms, true) 44 } 45 46 // ////////////////////////////////////////////////////////////////////////////////// // 47 48 func readFile(file string, v interface{}, compress bool) error { 49 fd, err := os.Open(file) 50 51 if err != nil { 52 return err 53 } 54 55 defer fd.Close() 56 57 return readData(fd, v, compress) 58 } 59 60 func readData(rw io.ReadWriter, v interface{}, compress bool) error { 61 var err error 62 var dr io.Reader 63 64 r := bufio.NewReader(rw) 65 66 if compress { 67 dr, err = gzip.NewReader(r) 68 69 if err != nil { 70 return err 71 } 72 } else { 73 dr = r 74 } 75 76 return json.NewDecoder(dr).Decode(v) 77 } 78 79 func writeFile(file string, v interface{}, perms []os.FileMode, compressed bool) error { 80 var perm os.FileMode = 0644 81 82 if len(perms) != 0 { 83 perm = perms[0] 84 } 85 86 fd, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 87 88 if err != nil { 89 return err 90 } 91 92 defer fd.Close() 93 94 return writeData(fd, v, compressed) 95 } 96 97 func writeData(rw io.ReadWriter, v interface{}, compressed bool) error { 98 var err error 99 var je *json.Encoder 100 var gw *gzip.Writer 101 102 w := bufio.NewWriter(rw) 103 104 if compressed { 105 gw, err = gzip.NewWriterLevel(w, GzipLevel) 106 107 if err != nil { 108 return err 109 } 110 111 je = json.NewEncoder(gw) 112 } else { 113 je = json.NewEncoder(w) 114 } 115 116 je.SetIndent("", " ") 117 118 err = je.Encode(v) 119 120 if err != nil { 121 return err 122 } 123 124 if compressed { 125 err = gw.Close() 126 127 if err != nil { 128 return err 129 } 130 } 131 132 return w.Flush() 133 }