gitee.com/h79/goutils@v1.22.10/common/json/json.go (about) 1 package json 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "gitee.com/h79/goutils/common/file" 7 "gitee.com/h79/goutils/common/result" 8 "os" 9 "strings" 10 "unicode" 11 "unicode/utf16" 12 "unicode/utf8" 13 ) 14 15 type DumpOption func(enc *json.Encoder) 16 17 func EscapeHTML(escape bool) DumpOption { 18 return func(enc *json.Encoder) { 19 enc.SetEscapeHTML(escape) 20 } 21 } 22 23 // Indent sets the indentation level (passed as string of spaces) for DumpBytes/DumpString 24 func Indent(prefix, indent string) DumpOption { 25 return func(enc *json.Encoder) { 26 enc.SetIndent(prefix, indent) 27 } 28 } 29 30 // DumpBytes convert Go data object to JSON []byte 31 func DumpBytes(obj interface{}, options ...DumpOption) ([]byte, error) { 32 var b bytes.Buffer 33 enc := json.NewEncoder(&b) 34 enc.SetEscapeHTML(false) 35 36 for _, opt := range options { 37 opt(enc) 38 } 39 err := enc.Encode(obj) 40 return b.Bytes(), err 41 } 42 43 // DumpString encode Go data object to JSON string 44 func DumpString(obj interface{}, options ...DumpOption) (string, error) { 45 if res, err := DumpBytes(obj, options...); err != nil { 46 return "", err 47 } else { 48 return string(res), nil 49 } 50 } 51 52 // MustDumpBytes encode Go data object to JSON []byte (panic in case of error) 53 func MustDumpBytes(obj interface{}, options ...DumpOption) []byte { 54 if res, err := DumpBytes(obj, options...); err != nil { 55 panic(err) 56 } else { 57 return res 58 } 59 } 60 61 // MustDumpString encode Go data object to JSON string (panic in case of error) 62 func MustDumpString(obj interface{}, options ...DumpOption) string { 63 if res, err := DumpString(obj, options...); err != nil { 64 panic(err) 65 } else { 66 return res 67 } 68 } 69 70 // ToString 序列化参数 71 func ToString(o interface{}) string { 72 // 序列化一次 73 raw, _ := json.Marshal(o) 74 75 // 反序列化为map 76 m := make(map[string]interface{}) 77 reader := bytes.NewReader(raw) 78 decode := json.NewDecoder(reader) 79 decode.UseNumber() 80 _ = decode.Decode(&m) 81 82 // 重新做一次序列化,并禁用Html Escape 83 buffer := bytes.NewBufferString("") 84 encoder := json.NewEncoder(buffer) 85 encoder.SetEscapeHTML(false) 86 _ = encoder.Encode(m) 87 88 // Trim掉末尾的换行符 89 return strings.TrimSpace(buffer.String()) 90 } 91 92 func Write(name string, data interface{}, perm os.FileMode) error { 93 return file.WriteFileName(name, perm, func(w *os.File) error { 94 enc := json.NewEncoder(w) 95 if err := enc.Encode(data); err != nil { 96 return result.Errorf(result.ErrJson, "Encode %s json failed,err: %v", name, err).Log() 97 } 98 return nil 99 }) 100 } 101 102 func Read(name string, data interface{}) error { 103 _, err := file.ReadFileName(name, func(r *os.File) error { 104 dec := json.NewDecoder(r) 105 if err := dec.Decode(data); err != nil { 106 return result.Errorf(result.ErrJson, "Decode %s json failed,err: %v", name, err).Log() 107 } 108 return nil 109 }) 110 return err 111 } 112 113 func UnQuoteBytes(s []byte) (t []byte, ok bool) { 114 if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { 115 return s, true 116 } 117 s = s[1 : len(s)-1] 118 119 // Check for unusual characters. If there are none, 120 // then no unquoting is needed, so return a slice of the 121 // original bytes. 122 r := 0 123 for r < len(s) { 124 c := s[r] 125 if c == '\\' || c == '"' || c < ' ' { 126 break 127 } 128 if c < utf8.RuneSelf { 129 r++ 130 continue 131 } 132 rr, size := utf8.DecodeRune(s[r:]) 133 if rr == utf8.RuneError && size == 1 { 134 break 135 } 136 r += size 137 } 138 if r == len(s) { 139 return s, true 140 } 141 142 b := make([]byte, len(s)+2*utf8.UTFMax) 143 w := copy(b, s[0:r]) 144 for r < len(s) { 145 // Out of room? Can only happen if s is full of 146 // malformed UTF-8 and we're replacing each 147 // byte with RuneError. 148 if w >= len(b)-2*utf8.UTFMax { 149 nb := make([]byte, (len(b)+utf8.UTFMax)*2) 150 copy(nb, b[0:w]) 151 b = nb 152 } 153 switch c := s[r]; { 154 case c == '\\': 155 r++ 156 if r >= len(s) { 157 return 158 } 159 switch s[r] { 160 default: 161 return 162 case '"', '\\', '/', '\'': 163 b[w] = s[r] 164 r++ 165 w++ 166 case 'b': 167 b[w] = '\b' 168 r++ 169 w++ 170 case 'f': 171 b[w] = '\f' 172 r++ 173 w++ 174 case 'n': 175 b[w] = '\n' 176 r++ 177 w++ 178 case 'r': 179 b[w] = '\r' 180 r++ 181 w++ 182 case 't': 183 b[w] = '\t' 184 r++ 185 w++ 186 case 'u': 187 r-- 188 rr := getU4(s[r:]) 189 if rr < 0 { 190 return 191 } 192 r += 6 193 if utf16.IsSurrogate(rr) { 194 rr1 := getU4(s[r:]) 195 if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { 196 // A valid pair; consume. 197 r += 6 198 w += utf8.EncodeRune(b[w:], dec) 199 break 200 } 201 // Invalid surrogate; fall back to replacement rune. 202 rr = unicode.ReplacementChar 203 } 204 w += utf8.EncodeRune(b[w:], rr) 205 } 206 207 // Quote, control characters are invalid. 208 case c == '"', c < ' ': 209 return 210 211 // ASCII 212 case c < utf8.RuneSelf: 213 b[w] = c 214 r++ 215 w++ 216 217 // Coerce to well-formed UTF-8. 218 default: 219 rr, size := utf8.DecodeRune(s[r:]) 220 r += size 221 w += utf8.EncodeRune(b[w:], rr) 222 } 223 } 224 return b[0:w], true 225 } 226 227 // getU4 decodes \uXXXX from the beginning of s, returning the hex value, 228 // or it returns -1. 229 func getU4(s []byte) rune { 230 if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { 231 return -1 232 } 233 var r rune 234 for _, c := range s[2:6] { 235 switch { 236 case '0' <= c && c <= '9': 237 c = c - '0' 238 case 'a' <= c && c <= 'f': 239 c = c - 'a' + 10 240 case 'A' <= c && c <= 'F': 241 c = c - 'A' + 10 242 default: 243 return -1 244 } 245 r = r*16 + rune(c) 246 } 247 return r 248 } 249 250 type coder struct { 251 } 252 253 func (j *coder) Unmarshal(content []byte, v interface{}) error { 254 return json.Unmarshal(content, v) 255 } 256 257 func (j *coder) Marshal(v interface{}) ([]byte, error) { 258 return json.Marshal(v) 259 } 260 261 var DefaultCoder = &coder{}