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