podman
1// +build !amd64 !go1.16 go1.22
2
3/*
4* Copyright 2023 ByteDance Inc.
5*
6* Licensed under the Apache License, Version 2.0 (the "License");
7* you may not use this file except in compliance with the License.
8* You may obtain a copy of the License at
9*
10* http://www.apache.org/licenses/LICENSE-2.0
11*
12* Unless required by applicable law or agreed to in writing, software
13* distributed under the License is distributed on an "AS IS" BASIS,
14* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15* See the License for the specific language governing permissions and
16* limitations under the License.
17*/
18
19package encoder20
21import (22`io`23`bytes`24`encoding/json`25`reflect`26
27`github.com/bytedance/sonic/option`28)
29
30func init() {31println("WARNING: sonic only supports Go1.16~1.20 && CPU amd64, but your environment is not suitable")32}
33
34// Options is a set of encoding options.
35type Options uint6436
37const (38bitSortMapKeys = iota39bitEscapeHTML
40bitCompactMarshaler
41bitNoQuoteTextMarshaler
42bitNoNullSliceOrMap
43bitValidateString
44bitNoValidateJSONMarshaler
45
46// used for recursive compile47bitPointerValue = 6348)
49
50const (51// SortMapKeys indicates that the keys of a map needs to be sorted52// before serializing into JSON.53// WARNING: This hurts performance A LOT, USE WITH CARE.54SortMapKeys Options = 1 << bitSortMapKeys55
56// EscapeHTML indicates encoder to escape all HTML characters57// after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape).58// WARNING: This hurts performance A LOT, USE WITH CARE.59EscapeHTML Options = 1 << bitEscapeHTML60
61// CompactMarshaler indicates that the output JSON from json.Marshaler62// is always compact and needs no validation63CompactMarshaler Options = 1 << bitCompactMarshaler64
65// NoQuoteTextMarshaler indicates that the output text from encoding.TextMarshaler66// is always escaped string and needs no quoting67NoQuoteTextMarshaler Options = 1 << bitNoQuoteTextMarshaler68
69// NoNullSliceOrMap indicates all empty Array or Object are encoded as '[]' or '{}',70// instead of 'null'71NoNullSliceOrMap Options = 1 << bitNoNullSliceOrMap72
73// ValidateString indicates that encoder should validate the input string74// before encoding it into JSON.75ValidateString Options = 1 << bitValidateString76
77// NoValidateJSONMarshaler indicates that the encoder should not validate the output string78// after encoding the JSONMarshaler to JSON.79NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler80
81// CompatibleWithStd is used to be compatible with std encoder.82CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler83)
84
85// Encoder represents a specific set of encoder configurations.
86type Encoder struct {87Opts Options
88prefix string89indent string90}
91
92// Encode returns the JSON encoding of v.
93func (self *Encoder) Encode(v interface{}) ([]byte, error) {94if self.indent != "" || self.prefix != "" {95return EncodeIndented(v, self.prefix, self.indent, self.Opts)96}97return Encode(v, self.Opts)98}
99
100// SortKeys enables the SortMapKeys option.
101func (self *Encoder) SortKeys() *Encoder {102self.Opts |= SortMapKeys103return self104}
105
106// SetEscapeHTML specifies if option EscapeHTML opens
107func (self *Encoder) SetEscapeHTML(f bool) {108if f {109self.Opts |= EscapeHTML110} else {111self.Opts &= ^EscapeHTML112}113}
114
115// SetValidateString specifies if option ValidateString opens
116func (self *Encoder) SetValidateString(f bool) {117if f {118self.Opts |= ValidateString119} else {120self.Opts &= ^ValidateString121}122}
123
124// SetNoValidateJSONMarshaler specifies if option NoValidateJSONMarshaler opens
125func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {126if f {127self.Opts |= NoValidateJSONMarshaler128} else {129self.Opts &= ^NoValidateJSONMarshaler130}131}
132
133// SetCompactMarshaler specifies if option CompactMarshaler opens
134func (self *Encoder) SetCompactMarshaler(f bool) {135if f {136self.Opts |= CompactMarshaler137} else {138self.Opts &= ^CompactMarshaler139}140}
141
142// SetNoQuoteTextMarshaler specifies if option NoQuoteTextMarshaler opens
143func (self *Encoder) SetNoQuoteTextMarshaler(f bool) {144if f {145self.Opts |= NoQuoteTextMarshaler146} else {147self.Opts &= ^NoQuoteTextMarshaler148}149}
150
151// SetIndent instructs the encoder to format each subsequent encoded
152// value as if indented by the package-level function EncodeIndent().
153// Calling SetIndent("", "") disables indentation.
154func (enc *Encoder) SetIndent(prefix, indent string) {155enc.prefix = prefix156enc.indent = indent157}
158
159// Quote returns the JSON-quoted version of s.
160func Quote(s string) string {161/* check for empty string */162if s == "" {163return `""`164}165
166out, _ := json.Marshal(s)167return string(out)168}
169
170// Encode returns the JSON encoding of val, encoded with opts.
171func Encode(val interface{}, opts Options) ([]byte, error) {172return json.Marshal(val)173}
174
175// EncodeInto is like Encode but uses a user-supplied buffer instead of allocating
176// a new one.
177func EncodeInto(buf *[]byte, val interface{}, opts Options) error {178if buf == nil {179panic("user-supplied buffer buf is nil")180}181w := bytes.NewBuffer(*buf)182enc := json.NewEncoder(w)183enc.SetEscapeHTML((opts & EscapeHTML) != 0)184err := enc.Encode(val)185*buf = w.Bytes()186return err187}
188
189// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
190// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
191// so that the JSON will be safe to embed inside HTML <script> tags.
192// For historical reasons, web browsers don't honor standard HTML
193// escaping within <script> tags, so an alternative JSON encoding must
194// be used.
195func HTMLEscape(dst []byte, src []byte) []byte {196d := bytes.NewBuffer(dst)197json.HTMLEscape(d, src)198return d.Bytes()199}
200
201// EncodeIndented is like Encode but applies Indent to format the output.
202// Each JSON element in the output will begin on a new line beginning with prefix
203// followed by one or more copies of indent according to the indentation nesting.
204func EncodeIndented(val interface{}, prefix string, indent string, opts Options) ([]byte, error) {205w := bytes.NewBuffer([]byte{})206enc := json.NewEncoder(w)207enc.SetEscapeHTML((opts & EscapeHTML) != 0)208enc.SetIndent(prefix, indent)209err := enc.Encode(val)210out := w.Bytes()211return out, err212}
213
214// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
215// order to reduce the first-hit latency.
216//
217// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
218// a compile option to set the depth of recursive compile for the nested struct type.
219func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {220return nil221}
222
223// Valid validates json and returns first non-blank character position,
224// if it is only one valid json value.
225// Otherwise returns invalid character position using start.
226//
227// Note: it does not check for the invalid UTF-8 characters.
228func Valid(data []byte) (ok bool, start int) {229return json.Valid(data), 0230}
231
232// StreamEncoder uses io.Writer as
233type StreamEncoder = json.Encoder234
235// NewStreamEncoder adapts to encoding/json.NewDecoder API.
236//
237// NewStreamEncoder returns a new encoder that write to w.
238func NewStreamEncoder(w io.Writer) *StreamEncoder {239return json.NewEncoder(w)240}
241
242