🎨 提交支持逻辑

This commit is contained in:
pro911 2025-10-29 16:27:07 +08:00
parent 6ad6205e9c
commit a1e7662b26
2 changed files with 301 additions and 0 deletions

View File

@ -347,10 +347,31 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
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 {
if val == "" {
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)
if err == nil {
field.SetInt(intVal)

View File

@ -15,7 +15,287 @@ import (
// Package indicates what library is being used for JSON encoding.
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() {
json.RegisterExtension(&ApipostExtension{})
API = jsoniterApi{}
}