...
1
2
3
18
19 package encoder
20
21 import (
22 `io`
23 `bytes`
24 `encoding/json`
25 `reflect`
26
27 `github.com/bytedance/sonic/option`
28 )
29
30 func init() {
31 println("WARNING: sonic only supports Go1.16~1.22 && CPU amd64, but your environment is not suitable")
32 }
33
34
35 type Options uint64
36
37 const (
38 bitSortMapKeys = iota
39 bitEscapeHTML
40 bitCompactMarshaler
41 bitNoQuoteTextMarshaler
42 bitNoNullSliceOrMap
43 bitValidateString
44 bitNoValidateJSONMarshaler
45 bitNoEncoderNewline
46
47
48 bitPointerValue = 63
49 )
50
51 const (
52
53
54
55 SortMapKeys Options = 1 << bitSortMapKeys
56
57
58
59
60 EscapeHTML Options = 1 << bitEscapeHTML
61
62
63
64 CompactMarshaler Options = 1 << bitCompactMarshaler
65
66
67
68 NoQuoteTextMarshaler Options = 1 << bitNoQuoteTextMarshaler
69
70
71
72 NoNullSliceOrMap Options = 1 << bitNoNullSliceOrMap
73
74
75
76 ValidateString Options = 1 << bitValidateString
77
78
79
80 NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler
81
82
83 NoEncoderNewline Options = 1 << bitNoEncoderNewline
84
85
86 CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
87 )
88
89
90 type Encoder struct {
91 Opts Options
92 prefix string
93 indent string
94 }
95
96
97 func (self *Encoder) Encode(v interface{}) ([]byte, error) {
98 if self.indent != "" || self.prefix != "" {
99 return EncodeIndented(v, self.prefix, self.indent, self.Opts)
100 }
101 return Encode(v, self.Opts)
102 }
103
104
105 func (self *Encoder) SortKeys() *Encoder {
106 self.Opts |= SortMapKeys
107 return self
108 }
109
110
111 func (self *Encoder) SetEscapeHTML(f bool) {
112 if f {
113 self.Opts |= EscapeHTML
114 } else {
115 self.Opts &= ^EscapeHTML
116 }
117 }
118
119
120 func (self *Encoder) SetValidateString(f bool) {
121 if f {
122 self.Opts |= ValidateString
123 } else {
124 self.Opts &= ^ValidateString
125 }
126 }
127
128
129 func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
130 if f {
131 self.Opts |= NoValidateJSONMarshaler
132 } else {
133 self.Opts &= ^NoValidateJSONMarshaler
134 }
135 }
136
137
138 func (self *Encoder) SetNoEncoderNewline(f bool) {
139 if f {
140 self.Opts |= NoEncoderNewline
141 } else {
142 self.Opts &= ^NoEncoderNewline
143 }
144 }
145
146
147 func (self *Encoder) SetCompactMarshaler(f bool) {
148 if f {
149 self.Opts |= CompactMarshaler
150 } else {
151 self.Opts &= ^CompactMarshaler
152 }
153 }
154
155
156 func (self *Encoder) SetNoQuoteTextMarshaler(f bool) {
157 if f {
158 self.Opts |= NoQuoteTextMarshaler
159 } else {
160 self.Opts &= ^NoQuoteTextMarshaler
161 }
162 }
163
164
165
166
167 func (enc *Encoder) SetIndent(prefix, indent string) {
168 enc.prefix = prefix
169 enc.indent = indent
170 }
171
172
173 func Quote(s string) string {
174
175 if s == "" {
176 return `""`
177 }
178
179 out, _ := json.Marshal(s)
180 return string(out)
181 }
182
183
184 func Encode(val interface{}, opts Options) ([]byte, error) {
185 return json.Marshal(val)
186 }
187
188
189
190 func EncodeInto(buf *[]byte, val interface{}, opts Options) error {
191 if buf == nil {
192 panic("user-supplied buffer buf is nil")
193 }
194 w := bytes.NewBuffer(*buf)
195 enc := json.NewEncoder(w)
196 enc.SetEscapeHTML((opts & EscapeHTML) != 0)
197 err := enc.Encode(val)
198 *buf = w.Bytes()
199 return err
200 }
201
202
203
204
205
206
207
208 func HTMLEscape(dst []byte, src []byte) []byte {
209 d := bytes.NewBuffer(dst)
210 json.HTMLEscape(d, src)
211 return d.Bytes()
212 }
213
214
215
216
217 func EncodeIndented(val interface{}, prefix string, indent string, opts Options) ([]byte, error) {
218 w := bytes.NewBuffer([]byte{})
219 enc := json.NewEncoder(w)
220 enc.SetEscapeHTML((opts & EscapeHTML) != 0)
221 enc.SetIndent(prefix, indent)
222 err := enc.Encode(val)
223 out := w.Bytes()
224 return out, err
225 }
226
227
228
229
230
231
232 func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
233 return nil
234 }
235
236
237
238
239
240
241 func Valid(data []byte) (ok bool, start int) {
242 return json.Valid(data), 0
243 }
244
245
246 type StreamEncoder = json.Encoder
247
248
249
250
251 func NewStreamEncoder(w io.Writer) *StreamEncoder {
252 return json.NewEncoder(w)
253 }
254
255
View as plain text