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