You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.5 KiB
Go
108 lines
2.5 KiB
Go
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"
|
|
}
|
|
|