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字节存长度 }