mirror of
https://github.com/gin-gonic/gin.git
synced 2025-12-13 13:12:17 +08:00
🎨 提交支持逻辑
This commit is contained in:
parent
6ad6205e9c
commit
a1e7662b26
@ -347,10 +347,31 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containsAF(s string) bool {
|
||||||
|
for _, char := range s {
|
||||||
|
if char >= 'a' && char <= 'f' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func setIntField(val string, bitSize int, field reflect.Value) error {
|
func setIntField(val string, bitSize int, field reflect.Value) error {
|
||||||
if val == "" {
|
if val == "" {
|
||||||
val = "0"
|
val = "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO 校验数据是否是16进制雪花id如果是则将期转为int64 start
|
||||||
|
if bitSize == 64 && (len(val) < 17 || containsAF(val)) {
|
||||||
|
//hack for hex,must 16位
|
||||||
|
intVal, err := strconv.ParseInt(val, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
field.SetInt(intVal)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//TODO end
|
||||||
|
|
||||||
intVal, err := strconv.ParseInt(val, 10, bitSize)
|
intVal, err := strconv.ParseInt(val, 10, bitSize)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
field.SetInt(intVal)
|
field.SetInt(intVal)
|
||||||
|
|||||||
@ -15,7 +15,287 @@ import (
|
|||||||
// Package indicates what library is being used for JSON encoding.
|
// Package indicates what library is being used for JSON encoding.
|
||||||
const Package = "github.com/json-iterator/go"
|
const Package = "github.com/json-iterator/go"
|
||||||
|
|
||||||
|
func containsAF(s string) bool {
|
||||||
|
for _, char := range s {
|
||||||
|
if char >= 'a' && char <= 'f' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HexStringEncoder 自定义编码器将 int64 类型编码为十六进制字符串或者把16进制转为int64
|
||||||
|
type HexStringEncoder struct {
|
||||||
|
IsInt64Pointer bool //源数据为 *int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode 实现 jsoniter.ValEncoder 接口
|
||||||
|
func (e *HexStringEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||||
|
if ptr == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert *int64 value to a 16-byte hexadecimal string
|
||||||
|
if e.IsInt64Pointer {
|
||||||
|
pp := (**int64)(ptr)
|
||||||
|
if *pp == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream.WriteString(fmt.Sprintf("%x", **pp))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert int64 value to a 16-byte hexadecimal string
|
||||||
|
value := *(*int64)(ptr)
|
||||||
|
if value == 0 {
|
||||||
|
stream.WriteString("0") //0值特殊处理
|
||||||
|
} else {
|
||||||
|
stream.WriteString(fmt.Sprintf("%x", value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *HexStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return ptr == nil || *(*int64)(ptr) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *HexStringEncoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||||
|
valueType := iter.WhatIsNext()
|
||||||
|
if valueType == jsoniter.StringValue {
|
||||||
|
str := iter.ReadString()
|
||||||
|
var i int64
|
||||||
|
var err error
|
||||||
|
if len(str) < 17 || containsAF(str) {
|
||||||
|
i, err = strconv.ParseInt(str, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i, err = strconv.ParseInt(str, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*((*int64)(ptr)) = i
|
||||||
|
} else if valueType == jsoniter.NumberValue {
|
||||||
|
*((*int64)(ptr)) = iter.ReadInt64()
|
||||||
|
} else {
|
||||||
|
*((*int64)(ptr)) = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EmptyObjectEncoder 实现一个编码器,当字段值为nil时,写入空对象{}
|
||||||
|
type EmptyObjectEncoder struct {
|
||||||
|
encoder jsoniter.ValEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *EmptyObjectEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||||
|
// If the pointer points to nil, write an empty object.
|
||||||
|
if *(*uintptr)(ptr) == 0 {
|
||||||
|
stream.WriteRaw("{}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Fallback to default encoding.
|
||||||
|
encoder.encoder.Encode(ptr, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *EmptyObjectEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return encoder.encoder.IsEmpty(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmptyArrayEncoder struct {
|
||||||
|
encoder jsoniter.ValEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *EmptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||||
|
// If the pointer points to nil, write an empty object.
|
||||||
|
if *(*uintptr)(ptr) == 0 {
|
||||||
|
stream.WriteRaw("[]")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Fallback to default encoding.
|
||||||
|
encoder.encoder.Encode(ptr, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *EmptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return encoder.encoder.IsEmpty(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 空数组64位数组
|
||||||
|
type EmptyArrayInt64Encoder struct {
|
||||||
|
encoder jsoniter.ValEncoder
|
||||||
|
decoder jsoniter.ValDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *EmptyArrayInt64Encoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
|
||||||
|
// If the pointer points to nil, write an empty object.
|
||||||
|
if *(*uintptr)(ptr) == 0 {
|
||||||
|
stream.WriteRaw("[]")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//循环数组
|
||||||
|
slice := (*[]int64)(ptr)
|
||||||
|
strSlice := make([]string, len(*slice))
|
||||||
|
for i, v := range *slice {
|
||||||
|
if v == 0 {
|
||||||
|
strSlice[i] = "0"
|
||||||
|
} else {
|
||||||
|
strSlice[i] = fmt.Sprintf("%x", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := jsonInstance.Marshal(strSlice)
|
||||||
|
if err != nil {
|
||||||
|
encoder.encoder.Encode(ptr, stream)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
stream.WriteRaw(string(jsonData))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *EmptyArrayInt64Encoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||||
|
//str := iter.ReadString()
|
||||||
|
valueList := []int64{}
|
||||||
|
for iter.ReadArray() {
|
||||||
|
val := iter.Read()
|
||||||
|
if iter.Error != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if str, ok := val.(string); ok {
|
||||||
|
//含有a-f或者正好16位使用16进制解析
|
||||||
|
if len(str) < 17 || containsAF(str) {
|
||||||
|
intVal, err := strconv.ParseInt(str, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
valueList = append(valueList, intVal)
|
||||||
|
} else {
|
||||||
|
intVal, err := strconv.ParseInt(str, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
valueList = append(valueList, intVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将ptr解析为*[]int64类型的指针
|
||||||
|
ptrToSlice := (*[]int64)(ptr)
|
||||||
|
// 使用reflect包将ptr的内容替换为slice
|
||||||
|
reflect.ValueOf(ptrToSlice).Elem().Set(reflect.ValueOf(valueList))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *EmptyArrayInt64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return encoder.encoder.IsEmpty(ptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToStringEncoder struct{}
|
||||||
|
|
||||||
|
func (codec *ToStringEncoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||||
|
valueType := iter.WhatIsNext()
|
||||||
|
if valueType == jsoniter.StringValue {
|
||||||
|
str := iter.ReadString()
|
||||||
|
*((*string)(ptr)) = str
|
||||||
|
} else {
|
||||||
|
valueAsString := iter.ReadAny().ToString()
|
||||||
|
*((*string)(ptr)) = valueAsString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToBoolEncoder struct {
|
||||||
|
decoder jsoniter.ValDecoder
|
||||||
|
DefaultVal bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (codec *ToBoolEncoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||||
|
valueType := iter.WhatIsNext()
|
||||||
|
if valueType == jsoniter.BoolValue {
|
||||||
|
codec.decoder.Decode(ptr, iter)
|
||||||
|
} else if valueType == jsoniter.NumberValue {
|
||||||
|
i := iter.ReadInt()
|
||||||
|
var myBool bool
|
||||||
|
if i > 0 {
|
||||||
|
myBool = true
|
||||||
|
} else {
|
||||||
|
myBool = false
|
||||||
|
}
|
||||||
|
*((*bool)(ptr)) = myBool
|
||||||
|
} else if valueType == jsoniter.StringValue {
|
||||||
|
str := strings.ToLower(iter.ReadString())
|
||||||
|
var myBool bool
|
||||||
|
if str == "true" || str == "1" {
|
||||||
|
myBool = true
|
||||||
|
} else if str == "false" || str == "0" || str == "-1" {
|
||||||
|
myBool = false
|
||||||
|
} else {
|
||||||
|
myBool = codec.DefaultVal
|
||||||
|
}
|
||||||
|
*((*bool)(ptr)) = myBool
|
||||||
|
} else {
|
||||||
|
str := strings.ToLower(iter.ReadAny().ToString())
|
||||||
|
var myBool bool
|
||||||
|
if str == "true" || str == "1" {
|
||||||
|
myBool = true
|
||||||
|
} else if str == "false" || str == "0" || str == "-1" {
|
||||||
|
myBool = false
|
||||||
|
} else {
|
||||||
|
myBool = codec.DefaultVal
|
||||||
|
}
|
||||||
|
*((*bool)(ptr)) = myBool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HexStringExtension 检查 struct 字段tags,为相应的 int64 字段应用 HexStringEncoder
|
||||||
|
type ApipostExtension struct {
|
||||||
|
jsoniter.DummyExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateStructDescriptor 修改 struct 字段的编码/解码器
|
||||||
|
func (extension *ApipostExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
|
||||||
|
for _, binding := range structDescriptor.Fields {
|
||||||
|
// 检查字段类型和 tag
|
||||||
|
if binding.Field.Type().Kind() == reflect.Int64 {
|
||||||
|
//处理64位转换
|
||||||
|
if strings.Contains(binding.Field.Tag().Get("json"), "hexstring") {
|
||||||
|
binding.Encoder = &HexStringEncoder{}
|
||||||
|
binding.Decoder = &HexStringEncoder{}
|
||||||
|
}
|
||||||
|
} else if binding.Field.Type().Kind() == reflect.Ptr || binding.Field.Type().Kind() == reflect.Interface {
|
||||||
|
if strings.Contains(binding.Field.Tag().Get("json"), "hexstring") && binding.Field.Type().Type1().Elem().Kind() == reflect.Int64 { //处理*int64位转换
|
||||||
|
binding.Encoder = &HexStringEncoder{IsInt64Pointer: true}
|
||||||
|
} else if strings.Contains(binding.Field.Tag().Get("json"), "emptyobject") { //处理空对象
|
||||||
|
binding.Encoder = &EmptyObjectEncoder{binding.Encoder}
|
||||||
|
}
|
||||||
|
} else if binding.Field.Type().Kind() == reflect.Slice || binding.Field.Type().Kind() == reflect.Array {
|
||||||
|
//处理空数组
|
||||||
|
if binding.Field.Type().Type1().Elem().String() == "int64" {
|
||||||
|
//强制转64数组
|
||||||
|
int64SliceEncode := &EmptyArrayInt64Encoder{binding.Encoder, binding.Decoder}
|
||||||
|
binding.Encoder = int64SliceEncode
|
||||||
|
binding.Decoder = int64SliceEncode
|
||||||
|
} else if strings.Contains(binding.Field.Tag().Get("json"), "emptyarray") {
|
||||||
|
binding.Encoder = &EmptyArrayEncoder{binding.Encoder}
|
||||||
|
}
|
||||||
|
} else if binding.Field.Type().Kind() == reflect.String {
|
||||||
|
if strings.Contains(binding.Field.Tag().Get("json"), "tostring") {
|
||||||
|
binding.Decoder = &ToStringEncoder{}
|
||||||
|
}
|
||||||
|
} else if binding.Field.Type().Kind() == reflect.Bool {
|
||||||
|
tagStr := binding.Field.Tag().Get("json")
|
||||||
|
if strings.Contains(tagStr, "tofalse") {
|
||||||
|
binding.Decoder = &ToBoolEncoder{binding.Decoder, false}
|
||||||
|
} else if strings.Contains(tagStr, "totrue") {
|
||||||
|
binding.Decoder = &ToBoolEncoder{binding.Decoder, true}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
json.RegisterExtension(&ApipostExtension{})
|
||||||
API = jsoniterApi{}
|
API = jsoniterApi{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user