forked from github/multus-cni
gomodule is still in progress to migrate for now, hence multus team decide to keep vendor directory to support build without gomodule.
113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
package jsoniter
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/modern-go/reflect2"
|
|
"strconv"
|
|
"unsafe"
|
|
)
|
|
|
|
type Number string
|
|
|
|
// String returns the literal text of the number.
|
|
func (n Number) String() string { return string(n) }
|
|
|
|
// Float64 returns the number as a float64.
|
|
func (n Number) Float64() (float64, error) {
|
|
return strconv.ParseFloat(string(n), 64)
|
|
}
|
|
|
|
// Int64 returns the number as an int64.
|
|
func (n Number) Int64() (int64, error) {
|
|
return strconv.ParseInt(string(n), 10, 64)
|
|
}
|
|
|
|
func CastJsonNumber(val interface{}) (string, bool) {
|
|
switch typedVal := val.(type) {
|
|
case json.Number:
|
|
return string(typedVal), true
|
|
case Number:
|
|
return string(typedVal), true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem()
|
|
var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem()
|
|
|
|
func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder {
|
|
if typ.AssignableTo(jsonNumberType) {
|
|
return &jsonNumberCodec{}
|
|
}
|
|
if typ.AssignableTo(jsoniterNumberType) {
|
|
return &jsoniterNumberCodec{}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder {
|
|
if typ.AssignableTo(jsonNumberType) {
|
|
return &jsonNumberCodec{}
|
|
}
|
|
if typ.AssignableTo(jsoniterNumberType) {
|
|
return &jsoniterNumberCodec{}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type jsonNumberCodec struct {
|
|
}
|
|
|
|
func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
switch iter.WhatIsNext() {
|
|
case StringValue:
|
|
*((*json.Number)(ptr)) = json.Number(iter.ReadString())
|
|
case NilValue:
|
|
iter.skipFourBytes('n', 'u', 'l', 'l')
|
|
*((*json.Number)(ptr)) = ""
|
|
default:
|
|
*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
|
|
}
|
|
}
|
|
|
|
func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
number := *((*json.Number)(ptr))
|
|
if len(number) == 0 {
|
|
stream.writeByte('0')
|
|
} else {
|
|
stream.WriteRaw(string(number))
|
|
}
|
|
}
|
|
|
|
func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|
return len(*((*json.Number)(ptr))) == 0
|
|
}
|
|
|
|
type jsoniterNumberCodec struct {
|
|
}
|
|
|
|
func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
switch iter.WhatIsNext() {
|
|
case StringValue:
|
|
*((*Number)(ptr)) = Number(iter.ReadString())
|
|
case NilValue:
|
|
iter.skipFourBytes('n', 'u', 'l', 'l')
|
|
*((*Number)(ptr)) = ""
|
|
default:
|
|
*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
|
|
}
|
|
}
|
|
|
|
func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
number := *((*Number)(ptr))
|
|
if len(number) == 0 {
|
|
stream.writeByte('0')
|
|
} else {
|
|
stream.WriteRaw(string(number))
|
|
}
|
|
}
|
|
|
|
func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|
return len(*((*Number)(ptr))) == 0
|
|
}
|