package codec import ( "bytes" "encoding/binary" "reflect" "github.com/noahlann/nnet/pkg/codec" ) // BinaryCodec 二进制编解码器 type BinaryCodec struct { byteOrder binary.ByteOrder } // NewBinaryCodec 创建二进制编解码器 func NewBinaryCodec() codec.Codec { return &BinaryCodec{ byteOrder: binary.BigEndian, } } // NewBinaryCodecWithByteOrder 使用指定的字节序创建二进制编解码器 func NewBinaryCodecWithByteOrder(byteOrder binary.ByteOrder) codec.Codec { return &BinaryCodec{ byteOrder: byteOrder, } } // Encode 编码 func (c *BinaryCodec) Encode(v interface{}) ([]byte, error) { buf := new(bytes.Buffer) rv := reflect.ValueOf(v) if rv.Kind() == reflect.Ptr { rv = rv.Elem() } switch rv.Kind() { case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if err := binary.Write(buf, c.byteOrder, rv.Interface()); err != nil { return nil, err } case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if err := binary.Write(buf, c.byteOrder, rv.Interface()); err != nil { return nil, err } case reflect.Slice: if rv.Type().Elem().Kind() == reflect.Uint8 { // byte slice return rv.Bytes(), nil } // 其他类型的slice需要特殊处理 return nil, codec.NewError("unsupported slice type") case reflect.Array: if rv.Type().Elem().Kind() == reflect.Uint8 { // byte array result := make([]byte, rv.Len()) reflect.Copy(reflect.ValueOf(result), rv) return result, nil } return nil, codec.NewError("unsupported array type") default: return nil, codec.NewError("unsupported type: " + rv.Kind().String()) } return buf.Bytes(), nil } // Decode 解码 func (c *BinaryCodec) Decode(data []byte, v interface{}) error { rv := reflect.ValueOf(v) if rv.Kind() != reflect.Ptr { return codec.NewError("decode target must be a pointer") } rv = rv.Elem() buf := bytes.NewReader(data) switch rv.Kind() { case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: if err := binary.Read(buf, c.byteOrder, v); err != nil { return err } case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if err := binary.Read(buf, c.byteOrder, v); err != nil { return err } case reflect.Slice: if rv.Type().Elem().Kind() == reflect.Uint8 { // byte slice rv.SetBytes(data) return nil } return codec.NewError("unsupported slice type") default: return codec.NewError("unsupported type: " + rv.Kind().String()) } return nil } // Name 获取编解码器名称 func (c *BinaryCodec) Name() string { return "binary" }