mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:12:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			181 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
|  * Copyright 2021 ByteDance Inc.
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| package decoder
 | |
| 
 | |
| import (
 | |
|     `encoding/json`
 | |
|     `errors`
 | |
|     `fmt`
 | |
|     `reflect`
 | |
|     `strconv`
 | |
|     `strings`
 | |
| 
 | |
|     `github.com/bytedance/sonic/internal/native/types`
 | |
|     `github.com/bytedance/sonic/internal/rt`
 | |
| )
 | |
| 
 | |
| type SyntaxError struct {
 | |
|     Pos  int
 | |
|     Src  string
 | |
|     Code types.ParsingError
 | |
|     Msg  string
 | |
| }
 | |
| 
 | |
| func (self SyntaxError) Error() string {
 | |
|     return fmt.Sprintf("%q", self.Description())
 | |
| }
 | |
| 
 | |
| func (self SyntaxError) Description() string {
 | |
|     return "Syntax error " + self.description()
 | |
| }
 | |
| 
 | |
| func (self SyntaxError) description() string {
 | |
|     i := 16
 | |
|     p := self.Pos - i
 | |
|     q := self.Pos + i
 | |
| 
 | |
|     /* check for empty source */
 | |
|     if self.Src == "" {
 | |
|         return fmt.Sprintf("no sources available: %#v", self)
 | |
|     }
 | |
| 
 | |
|     /* prevent slicing before the beginning */
 | |
|     if p < 0 {
 | |
|         p, q, i = 0, q - p, i + p
 | |
|     }
 | |
| 
 | |
|     /* prevent slicing beyond the end */
 | |
|     if n := len(self.Src); q > n {
 | |
|         n = q - n
 | |
|         q = len(self.Src)
 | |
| 
 | |
|         /* move the left bound if possible */
 | |
|         if p > n {
 | |
|             i += n
 | |
|             p -= n
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* left and right length */
 | |
|     x := clamp_zero(i)
 | |
|     y := clamp_zero(q - p - i - 1)
 | |
| 
 | |
|     /* compose the error description */
 | |
|     return fmt.Sprintf(
 | |
|         "at index %d: %s\n\n\t%s\n\t%s^%s\n",
 | |
|         self.Pos,
 | |
|         self.Message(),
 | |
|         self.Src[p:q],
 | |
|         strings.Repeat(".", x),
 | |
|         strings.Repeat(".", y),
 | |
|     )
 | |
| }
 | |
| 
 | |
| func (self SyntaxError) Message() string {
 | |
|     if self.Msg == "" {
 | |
|         return self.Code.Message()
 | |
|     }
 | |
|     return self.Msg
 | |
| }
 | |
| 
 | |
| func clamp_zero(v int) int {
 | |
|     if v < 0 {
 | |
|         return 0
 | |
|     } else {
 | |
|         return v
 | |
|     }
 | |
| }
 | |
| 
 | |
| /** JIT Error Helpers **/
 | |
| 
 | |
| var stackOverflow = &json.UnsupportedValueError {
 | |
|     Str   : "Value nesting too deep",
 | |
|     Value : reflect.ValueOf("..."),
 | |
| }
 | |
| 
 | |
| //go:nosplit
 | |
| func error_wrap(src string, pos int, code types.ParsingError) error {
 | |
|     return SyntaxError {
 | |
|         Pos  : pos,
 | |
|         Src  : src,
 | |
|         Code : code,
 | |
|     }
 | |
| }
 | |
| 
 | |
| //go:nosplit
 | |
| func error_type(vt *rt.GoType) error {
 | |
|     return &json.UnmarshalTypeError{Type: vt.Pack()}
 | |
| }
 | |
| 
 | |
| type MismatchTypeError struct {
 | |
|     Pos  int
 | |
|     Src  string
 | |
|     Type reflect.Type
 | |
| }
 | |
| 
 | |
| func swithchJSONType (src string, pos int) string {
 | |
|     var val string
 | |
|     switch src[pos] {
 | |
|         case 'f': fallthrough
 | |
|         case 't': val = "bool"
 | |
|         case '"': val = "string"
 | |
|         case '{': val = "object"
 | |
|         case '[': val = "array"
 | |
|         case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': val = "number"        
 | |
|     }
 | |
|     return val
 | |
| }
 | |
| 
 | |
| func (self MismatchTypeError) Error() string {
 | |
|     se := SyntaxError {
 | |
|         Pos  : self.Pos,
 | |
|         Src  : self.Src,
 | |
|         Code : types.ERR_MISMATCH,
 | |
|     }
 | |
|     return fmt.Sprintf("Mismatch type %s with value %s %q", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
 | |
| }
 | |
| 
 | |
| func (self MismatchTypeError) Description() string {
 | |
|     se := SyntaxError {
 | |
|         Pos  : self.Pos,
 | |
|         Src  : self.Src,
 | |
|         Code : types.ERR_MISMATCH,
 | |
|     }
 | |
|     return fmt.Sprintf("Mismatch type %s with value %s %s", self.Type.String(), swithchJSONType(self.Src, self.Pos), se.description())
 | |
| }
 | |
| 
 | |
| //go:nosplit
 | |
| func error_mismatch(src string, pos int, vt *rt.GoType) error {
 | |
|     return &MismatchTypeError {
 | |
|         Pos  : pos,
 | |
|         Src  : src,
 | |
|         Type : vt.Pack(),
 | |
|     }
 | |
| }
 | |
| 
 | |
| //go:nosplit
 | |
| func error_field(name string) error {
 | |
|     return errors.New("json: unknown field " + strconv.Quote(name))
 | |
| }
 | |
| 
 | |
| //go:nosplit
 | |
| func error_value(value string, vtype reflect.Type) error {
 | |
|     return &json.UnmarshalTypeError {
 | |
|         Type  : vtype,
 | |
|         Value : value,
 | |
|     }
 | |
| }
 |