gtsocial-umbx

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

reflect_json_number.go (2694B)


      1 package jsoniter
      2 
      3 import (
      4 	"encoding/json"
      5 	"github.com/modern-go/reflect2"
      6 	"strconv"
      7 	"unsafe"
      8 )
      9 
     10 type Number string
     11 
     12 // String returns the literal text of the number.
     13 func (n Number) String() string { return string(n) }
     14 
     15 // Float64 returns the number as a float64.
     16 func (n Number) Float64() (float64, error) {
     17 	return strconv.ParseFloat(string(n), 64)
     18 }
     19 
     20 // Int64 returns the number as an int64.
     21 func (n Number) Int64() (int64, error) {
     22 	return strconv.ParseInt(string(n), 10, 64)
     23 }
     24 
     25 func CastJsonNumber(val interface{}) (string, bool) {
     26 	switch typedVal := val.(type) {
     27 	case json.Number:
     28 		return string(typedVal), true
     29 	case Number:
     30 		return string(typedVal), true
     31 	}
     32 	return "", false
     33 }
     34 
     35 var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem()
     36 var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem()
     37 
     38 func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder {
     39 	if typ.AssignableTo(jsonNumberType) {
     40 		return &jsonNumberCodec{}
     41 	}
     42 	if typ.AssignableTo(jsoniterNumberType) {
     43 		return &jsoniterNumberCodec{}
     44 	}
     45 	return nil
     46 }
     47 
     48 func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder {
     49 	if typ.AssignableTo(jsonNumberType) {
     50 		return &jsonNumberCodec{}
     51 	}
     52 	if typ.AssignableTo(jsoniterNumberType) {
     53 		return &jsoniterNumberCodec{}
     54 	}
     55 	return nil
     56 }
     57 
     58 type jsonNumberCodec struct {
     59 }
     60 
     61 func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
     62 	switch iter.WhatIsNext() {
     63 	case StringValue:
     64 		*((*json.Number)(ptr)) = json.Number(iter.ReadString())
     65 	case NilValue:
     66 		iter.skipFourBytes('n', 'u', 'l', 'l')
     67 		*((*json.Number)(ptr)) = ""
     68 	default:
     69 		*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
     70 	}
     71 }
     72 
     73 func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
     74 	number := *((*json.Number)(ptr))
     75 	if len(number) == 0 {
     76 		stream.writeByte('0')
     77 	} else {
     78 		stream.WriteRaw(string(number))
     79 	}
     80 }
     81 
     82 func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
     83 	return len(*((*json.Number)(ptr))) == 0
     84 }
     85 
     86 type jsoniterNumberCodec struct {
     87 }
     88 
     89 func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
     90 	switch iter.WhatIsNext() {
     91 	case StringValue:
     92 		*((*Number)(ptr)) = Number(iter.ReadString())
     93 	case NilValue:
     94 		iter.skipFourBytes('n', 'u', 'l', 'l')
     95 		*((*Number)(ptr)) = ""
     96 	default:
     97 		*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
     98 	}
     99 }
    100 
    101 func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
    102 	number := *((*Number)(ptr))
    103 	if len(number) == 0 {
    104 		stream.writeByte('0')
    105 	} else {
    106 		stream.WriteRaw(string(number))
    107 	}
    108 }
    109 
    110 func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
    111 	return len(*((*Number)(ptr))) == 0
    112 }