reflect_json_number.go raw

   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