refactor(blazing): 重构项目并优化数据结构
- 更新 LoginUserInfo 结构体,将 uint64 类型改为 uint32 - 调整 ServerInfo 结构体,将 IP 字段从 []byte 改为 string - 移除未使用的 ArraySerialize 结构体 - 更新 ByteArray 类,修改相关方法名 - 删除未使用的 serialize 相关代码 - 优化模块导入,移除冗余依赖
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
package serialize
|
||||
|
||||
type ArraySerialize struct {
|
||||
OrderId int64 `v:"order-exist"`
|
||||
ProductName string
|
||||
Amount int64
|
||||
// ...
|
||||
}
|
||||
var paddedContent byte=0//长度不足时填充的内容, 默认填充0
|
||||
|
||||
380
common/serialize/Serialize.go
Normal file
380
common/serialize/Serialize.go
Normal file
@@ -0,0 +1,380 @@
|
||||
package serialize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/tnnmigga/enum"
|
||||
)
|
||||
|
||||
// DefaultPacketSerializer 默认序列化实现,使用大端序写入数据
|
||||
func DefaultPacketSerializer[T any]() PacketSerializer[T] {
|
||||
return func(data T) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := binary.Write(&buf, binary.BigEndian, data); err != nil {
|
||||
return nil, errors.New("binary.Write failed: " + err.Error())
|
||||
}
|
||||
// 使用大端序写入数据
|
||||
// 1. 使用reflect获取结构体类型
|
||||
// typ := reflect.TypeOf(data)
|
||||
// fmt.Println("结构体类型名称:", typ.Name())
|
||||
// fmt.Println("字段数量:", typ.NumField())
|
||||
|
||||
// for i := 0; i < typ.NumField(); i++ {
|
||||
// field := typ.Field(i)
|
||||
// fmt.Printf("字段名: %s, 类型: %s",
|
||||
// field.Name, field.Type)
|
||||
// fmt.Println("字段值:", reflect.ValueOf(data).Field(i).Interface())
|
||||
|
||||
// // writedata := reflect.ValueOf(data).Field(i).Interface()
|
||||
// fmt.Println(field.Type.Kind())
|
||||
|
||||
// // serializebase[T](field, &buf, writedata)
|
||||
|
||||
// }
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultPacketDeserializer 默认反序列化实现,使用大端序读取数据
|
||||
func DefaultPacketDeserializer[T any]() PacketDeserializer[T] {
|
||||
return func(data []byte) (T, error) {
|
||||
var result T
|
||||
reader := bytes.NewReader(data)
|
||||
// 使用大端序读取数据
|
||||
if err := binary.Read(reader, binary.BigEndian, &result); err != nil {
|
||||
var zero T
|
||||
return zero, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewDefaultPacketHandler 创建默认的数据包处理句柄
|
||||
func NewDefaultPacketHandler[T any]() *PacketHandler[T] {
|
||||
return &PacketHandler[T]{
|
||||
Serialize: DefaultPacketSerializer[T](),
|
||||
Deserialize: DefaultPacketDeserializer[T](),
|
||||
}
|
||||
}
|
||||
|
||||
type SerializeMode int
|
||||
|
||||
var lengthtype = enum.New[struct {
|
||||
LENGTH_FIRST SerializeMode
|
||||
FIXED_LENGTH SerializeMode
|
||||
}]()
|
||||
|
||||
// PacketSerializer 定义序列化函数类型,将数据转换为字节切片
|
||||
type PacketSerializer[T any] func(data T) ([]byte, error)
|
||||
|
||||
// PacketDeserializer 定义反序列化函数类型,将字节切片转换为数据
|
||||
type PacketDeserializer[T any] func(data []byte) (T, error)
|
||||
|
||||
// PacketHandler 封装序列化和反序列化处理函数
|
||||
type PacketHandler[T any] struct {
|
||||
Serialize PacketSerializer[T] // 序列化函数
|
||||
Deserialize PacketDeserializer[T] // 反序列化函数
|
||||
}
|
||||
|
||||
// 定长序列化器
|
||||
type FixedVarSerializer struct {
|
||||
byteOrder binary.ByteOrder
|
||||
}
|
||||
|
||||
// 新建序列化器
|
||||
func NewFixedVarSerializer(order binary.ByteOrder) *FixedVarSerializer {
|
||||
if order == nil {
|
||||
order = binary.BigEndian
|
||||
}
|
||||
return &FixedVarSerializer{byteOrder: order}
|
||||
}
|
||||
|
||||
// 序列化任意结构体
|
||||
func (s *FixedVarSerializer) Serialize(obj interface{}) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := s.serializeValue(reflect.ValueOf(obj), &buf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("序列化失败: %w", err)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// 递归序列化值
|
||||
func (s *FixedVarSerializer) serializeValue(val reflect.Value, buf *bytes.Buffer) error {
|
||||
kind := val.Kind()
|
||||
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
return s.serializeStruct(val, buf)
|
||||
case reflect.Slice, reflect.Array:
|
||||
return s.serializeSlice(val, buf)
|
||||
default:
|
||||
if err := binary.Write(buf, s.byteOrder, val.Interface()); err != nil {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// 序列化结构体
|
||||
func (s *FixedVarSerializer) serializeStruct(val reflect.Value, buf *bytes.Buffer) error {
|
||||
typ := val.Type()
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
fieldVal := val.Field(i)
|
||||
|
||||
if !field.IsExported() {
|
||||
continue
|
||||
}
|
||||
|
||||
// 解析标签(格式:mode,params 如 fixed:16 或 varlen)
|
||||
tag := field.Tag.Get("serialize")
|
||||
if tag == "" {
|
||||
// 未指定标签:按原生类型序列化
|
||||
err := s.serializeValue(fieldVal, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 解析模式和参数
|
||||
mode, params, err := parseTag(tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 根据模式序列化
|
||||
switch mode {
|
||||
case lengthtype.FIXED_LENGTH:
|
||||
err = s.serializeFixedField(fieldVal, params, buf)
|
||||
case lengthtype.LENGTH_FIRST:
|
||||
err = s.serializeVarWithLenField(fieldVal, params, buf)
|
||||
default:
|
||||
return fmt.Errorf("无效的序列化模式: %s", tag)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 解析标签(格式:fixed:N 或 varlen 或 varlen:N)
|
||||
func parseTag(tag string) (SerializeMode, string, error) {
|
||||
parts := splitTag(tag)
|
||||
if len(parts) == 0 {
|
||||
return 0, "", fmt.Errorf("空标签")
|
||||
}
|
||||
|
||||
modeStr := parts[0]
|
||||
params := ""
|
||||
if len(parts) > 1 {
|
||||
params = parts[1]
|
||||
}
|
||||
|
||||
switch modeStr {
|
||||
case "fixed":
|
||||
if params == "" {
|
||||
return 0, "", fmt.Errorf("fixed模式需指定长度")
|
||||
}
|
||||
return lengthtype.FIXED_LENGTH, params, nil
|
||||
case "varlen":
|
||||
// varlen模式:可指定长度字段字节数(如varlen:2表示用2字节存长度)
|
||||
if params == "" {
|
||||
params = "4" // 默认用4字节存长度
|
||||
}
|
||||
return lengthtype.LENGTH_FIRST, params, nil
|
||||
default:
|
||||
return 0, "", fmt.Errorf("未知模式: %s", modeStr)
|
||||
}
|
||||
}
|
||||
|
||||
// 定长模式序列化字段
|
||||
func (s *FixedVarSerializer) serializeFixedField(val reflect.Value, lengthStr string, buf *bytes.Buffer) error {
|
||||
length, err := strconv.Atoi(lengthStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("无效的定长参数: %s", lengthStr)
|
||||
}
|
||||
return s.serializeFixedLengthValue(val, length, buf)
|
||||
}
|
||||
|
||||
// 不定长+长度模式序列化字段
|
||||
func (s *FixedVarSerializer) serializeVarWithLenField(val reflect.Value, lenBytesStr string, buf *bytes.Buffer) error {
|
||||
lenBytes, err := strconv.Atoi(lenBytesStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("无效的长度字节数: %s", lenBytesStr)
|
||||
}
|
||||
if lenBytes < 1 || lenBytes > 8 {
|
||||
return fmt.Errorf("长度字节数需在1-8之间")
|
||||
}
|
||||
|
||||
// 先序列化内容到临时缓冲区
|
||||
var contentBuf bytes.Buffer
|
||||
err = s.serializeValue(val, &contentBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content := contentBuf.Bytes()
|
||||
|
||||
// 写入长度(用指定字节数)
|
||||
|
||||
lenBuf := make([]byte, lenBytes)
|
||||
switch lenBytesStr {
|
||||
case "4":
|
||||
s.byteOrder.PutUint32(lenBuf, uint32(len(content)))
|
||||
case "2":
|
||||
s.byteOrder.PutUint16(lenBuf, uint16(len(content)))
|
||||
}
|
||||
//s.byteOrder.PutUint32(lenBuf, uint32(len(content)))
|
||||
buf.Write(lenBuf[:lenBytes])
|
||||
|
||||
// 写入内容
|
||||
buf.Write(content)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 序列化定长值
|
||||
func (s *FixedVarSerializer) serializeFixedLengthValue(val reflect.Value, length int, buf *bytes.Buffer) error {
|
||||
kind := val.Kind()
|
||||
|
||||
if kind == reflect.String {
|
||||
str := val.String()
|
||||
if len(str) > length {
|
||||
str = str[:length]
|
||||
}
|
||||
buf.WriteString(str)
|
||||
buf.Write(make([]byte, length-len(str)))
|
||||
return nil
|
||||
}
|
||||
|
||||
var tmpBuf bytes.Buffer
|
||||
fmt.Println(val)
|
||||
err := s.serializeValue(val, &tmpBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpData := tmpBuf.Bytes()
|
||||
|
||||
if len(tmpData) > length {
|
||||
buf.Write(tmpData[:length])
|
||||
} else {
|
||||
buf.Write(tmpData)
|
||||
buf.Write(make([]byte, length-len(tmpData)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 序列化slice
|
||||
func (s *FixedVarSerializer) serializeSlice(val reflect.Value, buf *bytes.Buffer) error {
|
||||
tempslice := gconv.SliceAny(val)
|
||||
fmt.Println(val)
|
||||
//binary.Write(buf, s.byteOrder, val.Bytes())
|
||||
for i := 0; i < len(tempslice); i++ {
|
||||
err := s.serializeValue(val.Index(i), buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// for i := 0; i < len(tempslice); i++ {
|
||||
// kind := val.Type().Elem().Field(i)
|
||||
|
||||
// tag := kind.Tag.Get("serialize")
|
||||
|
||||
// // 检查元素是否有标签
|
||||
// if tag != "" {
|
||||
// // 元素有标签:按定长模式处理
|
||||
// mode, params, err := parseTag(tag)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// if mode == lengthtype.FIXED_LENGTH {
|
||||
// // 定长slice:解析maxItems和itemLen
|
||||
// parts := splitTag(params)
|
||||
// if len(parts) != 2 {
|
||||
// return fmt.Errorf("定长slice标签需格式为 fixed:N,M")
|
||||
// }
|
||||
// maxItems, _ := strconv.Atoi(parts[0])
|
||||
// itemLen, _ := strconv.Atoi(parts[1])
|
||||
// return s.serializeFixedSlice(val, maxItems, itemLen, buf)
|
||||
// }
|
||||
// }
|
||||
|
||||
// 无标签或不定长模式:按原生slice处理(先写长度,再写元素)
|
||||
|
||||
// count := val.Len()
|
||||
// binary.Write(buf, s.byteOrder, int32(len(tempslice)))
|
||||
// for i := 0; i < count; i++ {
|
||||
// err := s.serializeValue(val.Index(i), buf)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
return nil
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 序列化定长slice
|
||||
func (s *FixedVarSerializer) serializeFixedSlice(val reflect.Value, maxItems, itemLen int, buf *bytes.Buffer) error {
|
||||
count := val.Len()
|
||||
if count > maxItems {
|
||||
count = maxItems
|
||||
}
|
||||
|
||||
buf.WriteByte(byte(count))
|
||||
|
||||
for i := 0; i < maxItems; i++ {
|
||||
if i < count {
|
||||
item := val.Index(i)
|
||||
tmpBuf := &bytes.Buffer{}
|
||||
err := s.serializeValue(item, tmpBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpData := tmpBuf.Bytes()
|
||||
|
||||
if len(tmpData) > itemLen {
|
||||
buf.Write(tmpData[:itemLen])
|
||||
} else {
|
||||
buf.Write(tmpData)
|
||||
buf.Write(make([]byte, itemLen-len(tmpData)))
|
||||
}
|
||||
} else {
|
||||
buf.Write(make([]byte, itemLen))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 辅助函数:分割标签参数
|
||||
func splitTag(tag string) []string {
|
||||
if tag == "" {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(tag, ":")
|
||||
}
|
||||
|
||||
// 示例结构体(混合模式)
|
||||
type Address struct {
|
||||
City string `serialize:"fixed:20"` // 定长模式:20字节
|
||||
Country string `serialize:"varlen"` // 不定长模式:先写4字节长度,再写内容
|
||||
}
|
||||
|
||||
type Person struct {
|
||||
Name string `serialize:"fixed:16"` // 定长姓名
|
||||
Age uint8 // 原生类型
|
||||
Address Address // 嵌套结构体
|
||||
Hobbies []string `serialize:"fixed:5,20"` // 定长slice:5个元素,每个20字节
|
||||
Friends []Person `serialize:"varlen"` // 不定长slice:先写长度,再写内容
|
||||
Metadata []float64 `serialize:"varlen:2"` // 不定长slice:用2字节存长度
|
||||
}
|
||||
42
common/serialize/Serialize_test.go
Normal file
42
common/serialize/Serialize_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package serialize
|
||||
|
||||
import (
|
||||
"blazing/common/core/info"
|
||||
"blazing/common/core/info/pet"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDefaultPacketSerializer(t *testing.T) {
|
||||
serializer := NewFixedVarSerializer(nil)
|
||||
|
||||
tt := info.NewServerInfo()
|
||||
tt.OnlineID = 99
|
||||
tt.IP = "127.0.0.1"
|
||||
// tt1 := serialize.NewDefaultPacketHandler[info.ServerInfo]()
|
||||
// tg, _ := tt1.Serialize(*tt)
|
||||
// 序列化
|
||||
data, err := serializer.Serialize(*tt)
|
||||
if err != nil {
|
||||
fmt.Println("错误:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("序列化数据(长度: %d字节):\n%x\n", len(data), data)
|
||||
}
|
||||
func TestDefaultPacketSerializerPet(t *testing.T) {
|
||||
serializer := NewFixedVarSerializer(nil)
|
||||
|
||||
tt := pet.NewPetInfo()
|
||||
|
||||
// tt1 := serialize.NewDefaultPacketHandler[info.ServerInfo]()
|
||||
// tg, _ := tt1.Serialize(*tt)
|
||||
// 序列化
|
||||
data, err := serializer.Serialize(*tt)
|
||||
if err != nil {
|
||||
fmt.Println("错误:", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("序列化数据(长度: %d字节):\n%x\n", len(data), data)
|
||||
}
|
||||
@@ -29,16 +29,16 @@ var bufferpool = &sync.Pool{
|
||||
// CreateByteArray 创建一个新的ByteArray实例,使用指定的字节数组
|
||||
func CreateByteArray(bytes ...[]byte) *ByteArray {
|
||||
var ba *ByteArray
|
||||
if len(bytes) == 0 {//如果是0,则为新创建
|
||||
if len(bytes) == 0 { //如果是0,则为新创建
|
||||
ba = bufferpool.Get().(*ByteArray)
|
||||
}else{//读序列
|
||||
ba =&ByteArray{endian: defaultEndian}
|
||||
} else { //读序列
|
||||
ba = &ByteArray{endian: defaultEndian}
|
||||
}
|
||||
|
||||
|
||||
for _, num := range bytes {
|
||||
ba.buf=append(ba.buf, num...)
|
||||
}
|
||||
|
||||
ba.buf = append(ba.buf, num...)
|
||||
}
|
||||
|
||||
ba.ResetPos()
|
||||
return ba
|
||||
}
|
||||
@@ -140,7 +140,7 @@ func (ba *ByteArray) Reset() {
|
||||
|
||||
// Bytes 返回完整的字节数组
|
||||
func (ba *ByteArray) Bytes() []byte {
|
||||
defer releaseByteArray(ba)//这里是写数组,写完后退出时释放线程池
|
||||
defer releaseByteArray(ba) //这里是写数组,写完后退出时释放线程池
|
||||
return ba.buf
|
||||
}
|
||||
|
||||
@@ -201,8 +201,8 @@ func (ba *ByteArray) WriteInt64(value int64) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// WriteUInt64 写入uint64,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteUInt64(value uint64) error {
|
||||
// Writeuint32 写入uint32,根据当前字节序处理
|
||||
func (ba *ByteArray) Writeuint32(value uint32) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
@@ -413,16 +413,16 @@ func (ba *ByteArray) ReadUInt32() (uint32, error) {
|
||||
|
||||
// ReadInt64 读取int64,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadInt64() (int64, error) {
|
||||
var v uint64
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(v), nil
|
||||
}
|
||||
|
||||
// ReadUInt64 读取uint64,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadUInt64() (uint64, error) {
|
||||
var v uint64
|
||||
// Readuint32 读取uint32,根据当前字节序处理
|
||||
func (ba *ByteArray) Readuint32() (uint32, error) {
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
package serialize
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
OrderId int64 `v:"order-exist"`
|
||||
ProductName string `v:"order-exist"`
|
||||
Amount int64
|
||||
// ...
|
||||
}
|
||||
|
||||
func RuleOrderExist(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
fmt.Println(in)
|
||||
return nil
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package serialize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
func Test_main(t *testing.T) {
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
req = &Request{
|
||||
OrderId: 65535,
|
||||
ProductName: "HikingShoe",
|
||||
Amount: 10000,
|
||||
}
|
||||
)
|
||||
err := g.Validator().RuleFunc("order-exist", RuleOrderExist).Data(req).Run(ctx)
|
||||
fmt.Println(err)
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
package serialize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
"github.com/tnnmigga/enum"
|
||||
)
|
||||
|
||||
var lengthtype = enum.New[struct {
|
||||
LENGTH_FIRST int
|
||||
FIXED_LENGTH int
|
||||
}]()
|
||||
|
||||
// PacketSerializer 定义序列化函数类型,将数据转换为字节切片
|
||||
type PacketSerializer[T any] func(data T) ([]byte, error)
|
||||
|
||||
// PacketDeserializer 定义反序列化函数类型,将字节切片转换为数据
|
||||
type PacketDeserializer[T any] func(data []byte) (T, error)
|
||||
|
||||
// PacketHandler 封装序列化和反序列化处理函数
|
||||
type PacketHandler[T any] struct {
|
||||
Serialize PacketSerializer[T] // 序列化函数
|
||||
Deserialize PacketDeserializer[T] // 反序列化函数
|
||||
}
|
||||
|
||||
|
||||
|
||||
func serializebase[T any](field reflect.StructField, buf *bytes.Buffer, writedata any) error {
|
||||
|
||||
|
||||
if field.Type.Kind() == reflect.Slice { //|| field.Type.Kind() == reflect.Array}
|
||||
|
||||
datatype := make(chan int, 1)
|
||||
FIXED_LENGTH := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
if in.Field == field.Name { //判断相同
|
||||
datatype <- lengthtype.FIXED_LENGTH
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
LENGTH_FIRST := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
datatype <- lengthtype.FIXED_LENGTH
|
||||
// fmt.Println(in)
|
||||
return nil
|
||||
}
|
||||
length := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
tem := <-datatype
|
||||
close(datatype)
|
||||
writelen := 0
|
||||
if parts := strings.Split(in.Rule, ":"); len(parts) > 1 {
|
||||
writelen = gconv.Int(strings.TrimSpace(parts[1]))
|
||||
|
||||
}
|
||||
switch tem {
|
||||
case lengthtype.FIXED_LENGTH: //in.value
|
||||
tempslice := gconv.SliceAny(writedata)
|
||||
temp := make([]byte, writelen-len(tempslice))
|
||||
|
||||
for i := 0; i < len(tempslice); i++ {
|
||||
tempdata := tempslice[i]
|
||||
fmt.Println(i)
|
||||
serializebase[T]( field, buf, tempdata) //todo递归序列化
|
||||
// copy(temp, date1)
|
||||
// if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
|
||||
// return nil
|
||||
// }
|
||||
}
|
||||
|
||||
if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
|
||||
return nil
|
||||
}
|
||||
case lengthtype.LENGTH_FIRST:
|
||||
// temp := make([]byte, writelen)
|
||||
// date1 := []byte(writedata.(string))
|
||||
// copy(temp, date1)
|
||||
// if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
|
||||
// return nil
|
||||
// }
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
rules := make(map[string]gvalid.RuleFunc, 3)
|
||||
rules["LENGTH_FIRST"] = LENGTH_FIRST
|
||||
rules["FIXED_LENGTH"] = FIXED_LENGTH
|
||||
rules["length"] = length
|
||||
g.Validator().RuleFuncMap(rules).Data(writedata).Run(gctx.New())
|
||||
// serializeslice[T](field, buf, writedata)
|
||||
} else {
|
||||
if err := binary.Write(buf, binary.BigEndian, writedata); err != nil {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultPacketSerializer 默认序列化实现,使用大端序写入数据
|
||||
func DefaultPacketSerializer[T any]() PacketSerializer[T] {
|
||||
return func(data T) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
// 使用大端序写入数据
|
||||
// 1. 使用reflect获取结构体类型
|
||||
typ := reflect.TypeOf(data)
|
||||
fmt.Println("结构体类型名称:", typ.Name())
|
||||
fmt.Println("字段数量:", typ.NumField())
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
fmt.Printf("字段名: %s, 类型: %s",
|
||||
field.Name, field.Type)
|
||||
fmt.Println("字段值:", reflect.ValueOf(data).Field(i).Interface())
|
||||
|
||||
writedata := reflect.ValueOf(data).Field(i).Interface()
|
||||
fmt.Println(field.Type.Kind())
|
||||
|
||||
serializebase[T]( field, &buf, writedata)
|
||||
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultPacketDeserializer 默认反序列化实现,使用大端序读取数据
|
||||
func DefaultPacketDeserializer[T any]() PacketDeserializer[T] {
|
||||
return func(data []byte) (T, error) {
|
||||
var result T
|
||||
reader := bytes.NewReader(data)
|
||||
// 使用大端序读取数据
|
||||
if err := binary.Read(reader, binary.BigEndian, &result); err != nil {
|
||||
var zero T
|
||||
return zero, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewDefaultPacketHandler 创建默认的数据包处理句柄
|
||||
func NewDefaultPacketHandler[T any]() *PacketHandler[T] {
|
||||
return &PacketHandler[T]{
|
||||
Serialize: DefaultPacketSerializer[T](),
|
||||
Deserialize: DefaultPacketDeserializer[T](),
|
||||
}
|
||||
}
|
||||
|
||||
// 示例:使用自定义类型演示序列化与反序列化
|
||||
type ExampleData struct {
|
||||
ID int32
|
||||
Name string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// 自定义序列化函数(处理结构体类型)
|
||||
func CustomSerializer() PacketSerializer[ExampleData] {
|
||||
return func(data ExampleData) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
// 先序列化基本类型字段
|
||||
if err := binary.Write(&buf, binary.BigEndian, data.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 序列化字符串长度和内容
|
||||
lenName := int32(len(data.Name))
|
||||
if err := binary.Write(&buf, binary.BigEndian, lenName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := buf.Write([]byte(data.Name)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 序列化字节数组长度和内容
|
||||
lenData := int32(len(data.Data))
|
||||
if err := binary.Write(&buf, binary.BigEndian, lenData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := buf.Write(data.Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义反序列化函数(处理结构体类型)
|
||||
func CustomDeserializer() PacketDeserializer[ExampleData] {
|
||||
return func(data []byte) (ExampleData, error) {
|
||||
var result ExampleData
|
||||
reader := bytes.NewReader(data)
|
||||
|
||||
// 读取基本类型字段
|
||||
if err := binary.Read(reader, binary.BigEndian, &result.ID); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// 读取字符串长度和内容
|
||||
var lenName int32
|
||||
if err := binary.Read(reader, binary.BigEndian, &lenName); err != nil {
|
||||
return result, err
|
||||
}
|
||||
if lenName > int32(reader.Len()) {
|
||||
return result, errors.New("invalid name length")
|
||||
}
|
||||
nameBuf := make([]byte, lenName)
|
||||
if _, err := reader.Read(nameBuf); err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Name = string(nameBuf)
|
||||
|
||||
// 读取字节数组长度和内容
|
||||
var lenData int32
|
||||
if err := binary.Read(reader, binary.BigEndian, &lenData); err != nil {
|
||||
return result, err
|
||||
}
|
||||
if lenData > int32(reader.Len()) {
|
||||
return result, errors.New("invalid data length")
|
||||
}
|
||||
result.Data = make([]byte, lenData)
|
||||
if _, err := reader.Read(result.Data); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user