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  }