github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/decoder/decoder_compat.go (about)

     1  //go:build !amd64 || !go1.16 || go1.22
     2  // +build !amd64 !go1.16 go1.22
     3  
     4  /*
     5  * Copyright 2023 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 decoder
    21  
    22  import (
    23  	"bytes"
    24  	"encoding/json"
    25  	"io"
    26  	"reflect"
    27  	"unsafe"
    28  
    29  	"github.com/goshafaq/sonic/internal/native/types"
    30  	"github.com/goshafaq/sonic/option"
    31  )
    32  
    33  func init() {
    34  	println("WARNING: sonic only supports Go1.16~1.20 && CPU amd64, but your environment is not suitable")
    35  }
    36  
    37  const (
    38  	_F_use_int64       = 0
    39  	_F_disable_urc     = 2
    40  	_F_disable_unknown = 3
    41  	_F_copy_string     = 4
    42  
    43  	_F_use_number      = types.B_USE_NUMBER
    44  	_F_validate_string = types.B_VALIDATE_STRING
    45  	_F_allow_control   = types.B_ALLOW_CONTROL
    46  )
    47  
    48  type Options uint64
    49  
    50  const (
    51  	OptionUseInt64         Options = 1 << _F_use_int64
    52  	OptionUseNumber        Options = 1 << _F_use_number
    53  	OptionUseUnicodeErrors Options = 1 << _F_disable_urc
    54  	OptionDisableUnknown   Options = 1 << _F_disable_unknown
    55  	OptionCopyString       Options = 1 << _F_copy_string
    56  	OptionValidateString   Options = 1 << _F_validate_string
    57  )
    58  
    59  func (self *Decoder) SetOptions(opts Options) {
    60  	if (opts&OptionUseNumber != 0) && (opts&OptionUseInt64 != 0) {
    61  		panic("can't set OptionUseInt64 and OptionUseNumber both!")
    62  	}
    63  	self.f = uint64(opts)
    64  }
    65  
    66  // Decoder is the decoder context object
    67  type Decoder struct {
    68  	i int
    69  	f uint64
    70  	s string
    71  }
    72  
    73  // NewDecoder creates a new decoder instance.
    74  func NewDecoder(s string) *Decoder {
    75  	return &Decoder{s: s}
    76  }
    77  
    78  // Pos returns the current decoding position.
    79  func (self *Decoder) Pos() int {
    80  	return self.i
    81  }
    82  
    83  func (self *Decoder) Reset(s string) {
    84  	self.s = s
    85  	self.i = 0
    86  	// self.f = 0
    87  }
    88  
    89  // NOTE: api fallback do nothing
    90  func (self *Decoder) CheckTrailings() error {
    91  	pos := self.i
    92  	buf := self.s
    93  	/* skip all the trailing spaces */
    94  	if pos != len(buf) {
    95  		for pos < len(buf) && (types.SPACE_MASK&(1<<buf[pos])) != 0 {
    96  			pos++
    97  		}
    98  	}
    99  
   100  	/* then it must be at EOF */
   101  	if pos == len(buf) {
   102  		return nil
   103  	}
   104  
   105  	/* junk after JSON value */
   106  	return nil
   107  }
   108  
   109  // Decode parses the JSON-encoded data from current position and stores the result
   110  // in the value pointed to by val.
   111  func (self *Decoder) Decode(val interface{}) error {
   112  	r := bytes.NewBufferString(self.s)
   113  	dec := json.NewDecoder(r)
   114  	if (self.f & uint64(OptionUseNumber)) != 0 {
   115  		dec.UseNumber()
   116  	}
   117  	if (self.f & uint64(OptionDisableUnknown)) != 0 {
   118  		dec.DisallowUnknownFields()
   119  	}
   120  	return dec.Decode(val)
   121  }
   122  
   123  // UseInt64 indicates the Decoder to unmarshal an integer into an interface{} as an
   124  // int64 instead of as a float64.
   125  func (self *Decoder) UseInt64() {
   126  	self.f |= 1 << _F_use_int64
   127  	self.f &^= 1 << _F_use_number
   128  }
   129  
   130  // UseNumber indicates the Decoder to unmarshal a number into an interface{} as a
   131  // json.Number instead of as a float64.
   132  func (self *Decoder) UseNumber() {
   133  	self.f &^= 1 << _F_use_int64
   134  	self.f |= 1 << _F_use_number
   135  }
   136  
   137  // UseUnicodeErrors indicates the Decoder to return an error when encounter invalid
   138  // UTF-8 escape sequences.
   139  func (self *Decoder) UseUnicodeErrors() {
   140  	self.f |= 1 << _F_disable_urc
   141  }
   142  
   143  // DisallowUnknownFields indicates the Decoder to return an error when the destination
   144  // is a struct and the input contains object keys which do not match any
   145  // non-ignored, exported fields in the destination.
   146  func (self *Decoder) DisallowUnknownFields() {
   147  	self.f |= 1 << _F_disable_unknown
   148  }
   149  
   150  // CopyString indicates the Decoder to decode string values by copying instead of referring.
   151  func (self *Decoder) CopyString() {
   152  	self.f |= 1 << _F_copy_string
   153  }
   154  
   155  // ValidateString causes the Decoder to validate string values when decoding string value
   156  // in JSON. Validation is that, returning error when unescaped control chars(0x00-0x1f) or
   157  // invalid UTF-8 chars in the string value of JSON.
   158  func (self *Decoder) ValidateString() {
   159  	self.f |= 1 << _F_validate_string
   160  }
   161  
   162  // Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
   163  // order to reduce the first-hit latency.
   164  //
   165  // Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
   166  // a compile option to set the depth of recursive compile for the nested struct type.
   167  func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
   168  	return nil
   169  }
   170  
   171  type StreamDecoder = json.Decoder
   172  
   173  // NewStreamDecoder adapts to encoding/json.NewDecoder API.
   174  //
   175  // NewStreamDecoder returns a new decoder that reads from r.
   176  func NewStreamDecoder(r io.Reader) *StreamDecoder {
   177  	return json.NewDecoder(r)
   178  }
   179  
   180  // SyntaxError represents json syntax error
   181  type SyntaxError json.SyntaxError
   182  
   183  // Description
   184  func (s SyntaxError) Description() string {
   185  	return (*json.SyntaxError)(unsafe.Pointer(&s)).Error()
   186  }
   187  
   188  // Error
   189  func (s SyntaxError) Error() string {
   190  	return (*json.SyntaxError)(unsafe.Pointer(&s)).Error()
   191  }
   192  
   193  // MismatchTypeError represents dismatching between json and object
   194  type MismatchTypeError json.UnmarshalTypeError