gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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