...

Source file src/github.com/json-iterator/go/reflect_json_number.go

Documentation: github.com/json-iterator/go

     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  }
   113  

View as plain text