gtsocial-umbx

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

number.go (2974B)


      1 package decoder
      2 
      3 import (
      4 	"encoding/json"
      5 	"strconv"
      6 	"unsafe"
      7 
      8 	"github.com/goccy/go-json/internal/errors"
      9 )
     10 
     11 type numberDecoder struct {
     12 	stringDecoder *stringDecoder
     13 	op            func(unsafe.Pointer, json.Number)
     14 	structName    string
     15 	fieldName     string
     16 }
     17 
     18 func newNumberDecoder(structName, fieldName string, op func(unsafe.Pointer, json.Number)) *numberDecoder {
     19 	return &numberDecoder{
     20 		stringDecoder: newStringDecoder(structName, fieldName),
     21 		op:            op,
     22 		structName:    structName,
     23 		fieldName:     fieldName,
     24 	}
     25 }
     26 
     27 func (d *numberDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
     28 	bytes, err := d.decodeStreamByte(s)
     29 	if err != nil {
     30 		return err
     31 	}
     32 	if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil {
     33 		return errors.ErrSyntax(err.Error(), s.totalOffset())
     34 	}
     35 	d.op(p, json.Number(string(bytes)))
     36 	s.reset()
     37 	return nil
     38 }
     39 
     40 func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
     41 	bytes, c, err := d.decodeByte(ctx.Buf, cursor)
     42 	if err != nil {
     43 		return 0, err
     44 	}
     45 	if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil {
     46 		return 0, errors.ErrSyntax(err.Error(), c)
     47 	}
     48 	cursor = c
     49 	s := *(*string)(unsafe.Pointer(&bytes))
     50 	d.op(p, json.Number(s))
     51 	return cursor, nil
     52 }
     53 
     54 func (d *numberDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
     55 	bytes, c, err := d.decodeByte(ctx.Buf, cursor)
     56 	if err != nil {
     57 		return nil, 0, err
     58 	}
     59 	if bytes == nil {
     60 		return [][]byte{nullbytes}, c, nil
     61 	}
     62 	return [][]byte{bytes}, c, nil
     63 }
     64 
     65 func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
     66 	start := s.cursor
     67 	for {
     68 		switch s.char() {
     69 		case ' ', '\n', '\t', '\r':
     70 			s.cursor++
     71 			continue
     72 		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
     73 			return floatBytes(s), nil
     74 		case 'n':
     75 			if err := nullBytes(s); err != nil {
     76 				return nil, err
     77 			}
     78 			return nil, nil
     79 		case '"':
     80 			return d.stringDecoder.decodeStreamByte(s)
     81 		case nul:
     82 			if s.read() {
     83 				continue
     84 			}
     85 			goto ERROR
     86 		default:
     87 			goto ERROR
     88 		}
     89 	}
     90 ERROR:
     91 	if s.cursor == start {
     92 		return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
     93 	}
     94 	return nil, errors.ErrUnexpectedEndOfJSON("json.Number", s.totalOffset())
     95 }
     96 
     97 func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
     98 	for {
     99 		switch buf[cursor] {
    100 		case ' ', '\n', '\t', '\r':
    101 			cursor++
    102 			continue
    103 		case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
    104 			start := cursor
    105 			cursor++
    106 			for floatTable[buf[cursor]] {
    107 				cursor++
    108 			}
    109 			num := buf[start:cursor]
    110 			return num, cursor, nil
    111 		case 'n':
    112 			if err := validateNull(buf, cursor); err != nil {
    113 				return nil, 0, err
    114 			}
    115 			cursor += 4
    116 			return nil, cursor, nil
    117 		case '"':
    118 			return d.stringDecoder.decodeByte(buf, cursor)
    119 		default:
    120 			return nil, 0, errors.ErrUnexpectedEndOfJSON("json.Number", cursor)
    121 		}
    122 	}
    123 }