github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/compat.go (about) 1 //go:build !amd64 || !go1.16 || go1.22 2 // +build !amd64 !go1.16 go1.22 3 4 /* 5 * Copyright 2021 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package sonic 21 22 import ( 23 "bytes" 24 "encoding/json" 25 "io" 26 "reflect" 27 28 "github.com/goshafaq/sonic/option" 29 ) 30 31 type frozenConfig struct { 32 Config 33 } 34 35 // Froze convert the Config to API 36 func (cfg Config) Froze() API { 37 api := &frozenConfig{Config: cfg} 38 return api 39 } 40 41 func (cfg frozenConfig) marshalOptions(val interface{}, prefix, indent string) ([]byte, error) { 42 w := bytes.NewBuffer([]byte{}) 43 enc := json.NewEncoder(w) 44 enc.SetEscapeHTML(cfg.EscapeHTML) 45 enc.SetIndent(prefix, indent) 46 err := enc.Encode(val) 47 out := w.Bytes() 48 49 // json.Encoder always appends '\n' after encoding, 50 // which is not same with json.Marshal() 51 if len(out) > 0 && out[len(out)-1] == '\n' { 52 out = out[:len(out)-1] 53 } 54 return out, err 55 } 56 57 // Marshal is implemented by sonic 58 func (cfg frozenConfig) Marshal(val interface{}) ([]byte, error) { 59 if !cfg.EscapeHTML { 60 return cfg.marshalOptions(val, "", "") 61 } 62 return json.Marshal(val) 63 } 64 65 // MarshalToString is implemented by sonic 66 func (cfg frozenConfig) MarshalToString(val interface{}) (string, error) { 67 out, err := cfg.Marshal(val) 68 return string(out), err 69 } 70 71 // MarshalIndent is implemented by sonic 72 func (cfg frozenConfig) MarshalIndent(val interface{}, prefix, indent string) ([]byte, error) { 73 if !cfg.EscapeHTML { 74 return cfg.marshalOptions(val, prefix, indent) 75 } 76 return json.MarshalIndent(val, prefix, indent) 77 } 78 79 // UnmarshalFromString is implemented by sonic 80 func (cfg frozenConfig) UnmarshalFromString(buf string, val interface{}) error { 81 r := bytes.NewBufferString(buf) 82 dec := json.NewDecoder(r) 83 if cfg.UseNumber { 84 dec.UseNumber() 85 } 86 if cfg.DisallowUnknownFields { 87 dec.DisallowUnknownFields() 88 } 89 return dec.Decode(val) 90 } 91 92 // Unmarshal is implemented by sonic 93 func (cfg frozenConfig) Unmarshal(buf []byte, val interface{}) error { 94 return cfg.UnmarshalFromString(string(buf), val) 95 } 96 97 // NewEncoder is implemented by sonic 98 func (cfg frozenConfig) NewEncoder(writer io.Writer) Encoder { 99 enc := json.NewEncoder(writer) 100 if !cfg.EscapeHTML { 101 enc.SetEscapeHTML(cfg.EscapeHTML) 102 } 103 return enc 104 } 105 106 // NewDecoder is implemented by sonic 107 func (cfg frozenConfig) NewDecoder(reader io.Reader) Decoder { 108 dec := json.NewDecoder(reader) 109 if cfg.UseNumber { 110 dec.UseNumber() 111 } 112 if cfg.DisallowUnknownFields { 113 dec.DisallowUnknownFields() 114 } 115 return dec 116 } 117 118 // Valid is implemented by sonic 119 func (cfg frozenConfig) Valid(data []byte) bool { 120 return json.Valid(data) 121 } 122 123 // Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in 124 // order to reduce the first-hit latency at **amd64** Arch. 125 // Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is 126 // a compile option to set the depth of recursive compile for the nested struct type. 127 // * This is the none implement for !amd64. 128 // It will be useful for someone who develop with !amd64 arch,like Mac M1. 129 func Pretouch(vt reflect.Type, opts ...option.CompileOption) error { 130 return nil 131 }