github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/compat.go (about) 1 // +build !amd64 !go1.16 go1.23 2 3 /* 4 * Copyright 2021 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 19 package sonic 20 21 import ( 22 `bytes` 23 `encoding/json` 24 `io` 25 `reflect` 26 27 `github.com/bytedance/sonic/option` 28 ) 29 30 type frozenConfig struct { 31 Config 32 } 33 34 // Froze convert the Config to API 35 func (cfg Config) Froze() API { 36 api := &frozenConfig{Config: cfg} 37 return api 38 } 39 40 func (cfg frozenConfig) marshalOptions(val interface{}, prefix, indent string) ([]byte, error) { 41 w := bytes.NewBuffer([]byte{}) 42 enc := json.NewEncoder(w) 43 enc.SetEscapeHTML(cfg.EscapeHTML) 44 enc.SetIndent(prefix, indent) 45 err := enc.Encode(val) 46 out := w.Bytes() 47 48 // json.Encoder always appends '\n' after encoding, 49 // which is not same with json.Marshal() 50 if len(out) > 0 && out[len(out)-1] == '\n' { 51 out = out[:len(out)-1] 52 } 53 return out, err 54 } 55 56 // Marshal is implemented by sonic 57 func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) { 58 if !cfg.EscapeHTML { 59 return cfg.marshalOptions(val, "", "") 60 } 61 return json.Marshal(val) 62 } 63 64 // MarshalToString is implemented by sonic 65 func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) { 66 out, err := cfg.Marshal(val) 67 return string(out), err 68 } 69 70 // MarshalIndent is implemented by sonic 71 func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) { 72 if !cfg.EscapeHTML { 73 return cfg.marshalOptions(val, prefix, indent) 74 } 75 return json.MarshalIndent(val, prefix, indent) 76 } 77 78 // UnmarshalFromString is implemented by sonic 79 func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error { 80 r := bytes.NewBufferString(buf) 81 dec := json.NewDecoder(r) 82 if cfg.UseNumber { 83 dec.UseNumber() 84 } 85 if cfg.DisallowUnknownFields { 86 dec.DisallowUnknownFields() 87 } 88 return dec.Decode(val) 89 } 90 91 // Unmarshal is implemented by sonic 92 func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error { 93 return cfg.UnmarshalFromString(string(buf), val) 94 } 95 96 // NewEncoder is implemented by sonic 97 func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder { 98 enc := json.NewEncoder(writer) 99 if !cfg.EscapeHTML { 100 enc.SetEscapeHTML(cfg.EscapeHTML) 101 } 102 return enc 103 } 104 105 // NewDecoder is implemented by sonic 106 func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder { 107 dec := json.NewDecoder(reader) 108 if cfg.UseNumber { 109 dec.UseNumber() 110 } 111 if cfg.DisallowUnknownFields { 112 dec.DisallowUnknownFields() 113 } 114 return dec 115 } 116 117 // Valid is implemented by sonic 118 func (cfg frozenConfig) Valid(data []byte) bool { 119 return json.Valid(data) 120 } 121 122 // Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in 123 // order to reduce the first-hit latency at **amd64** Arch. 124 // Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is 125 // a compile option to set the depth of recursive compile for the nested struct type. 126 // * This is the none implement for !amd64. 127 // It will be useful for someone who develop with !amd64 arch,like Mac M1. 128 func Pretouch(vt reflect.Type, opts ...option.CompileOption) error { 129 return nil 130 } 131