-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsonx.go
More file actions
94 lines (83 loc) · 2.35 KB
/
Copy pathjsonx.go
File metadata and controls
94 lines (83 loc) · 2.35 KB
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
// Package jsonx is a high-performance JSON library with a drop-in
// encoding/json API. It targets beating bytedance/sonic on AMD64 with AVX-512
// by using type-specialized decoders cached by reflect.Type, unsafe field
// writes, SWAR structural scanning, and branchless number parsing.
package jsonx
import (
"io"
)
// Unmarshal parses the JSON-encoded data and stores the result in the value
// pointed to by v. It is API-compatible with encoding/json.
func Unmarshal(data []byte, v interface{}) error {
d := decoderPool.Get().(*decoder)
d.reset(data)
err := d.decodeInto(v)
decoderPool.Put(d)
return err
}
// Marshal returns the JSON encoding of v. It is API-compatible with
// encoding/json.
func Marshal(v interface{}) ([]byte, error) {
e := encoderPool.Get().(*encoder)
e.reset()
err := e.encode(v)
if err != nil {
encoderPool.Put(e)
return nil, err
}
// hand back a copy so the pooled buffer can be reused
out := make([]byte, len(e.buf))
copy(out, e.buf)
encoderPool.Put(e)
return out, nil
}
// MarshalIndent is like Marshal but applies Indent to format the output.
// Each JSON element in the output will begin on a new line beginning with
// prefix followed by one or more copies of indent according to the
// indentation nesting. It is API-compatible with encoding/json.
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
b, err := Marshal(v)
if err != nil {
return nil, err
}
out := make([]byte, 0, len(b)+len(b)/8)
return appendIndented(out, b, prefix, indent), nil
}
// Valid reports whether data is a valid JSON encoding.
func Valid(data []byte) bool {
d := decoderPool.Get().(*decoder)
d.reset(data)
ok := d.validate()
decoderPool.Put(d)
return ok
}
// Decoder mirrors encoding/json.Decoder surface minimally.
type Decoder struct {
r io.Reader
buf []byte
}
func NewDecoder(r io.Reader) *Decoder { return &Decoder{r: r} }
func (d *Decoder) Decode(v interface{}) error {
if d.buf == nil {
b, err := io.ReadAll(d.r)
if err != nil {
return err
}
d.buf = b
}
return Unmarshal(d.buf, v)
}
// Encoder mirrors encoding/json.Encoder minimally.
type Encoder struct {
w io.Writer
}
func NewEncoder(w io.Writer) *Encoder { return &Encoder{w: w} }
func (e *Encoder) Encode(v interface{}) error {
data, err := Marshal(v)
if err != nil {
return err
}
data = append(data, '\n')
_, err = e.w.Write(data)
return err
}