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