Skip to content

Instantly share code, notes, and snippets.

@longbuilder
Last active October 14, 2019 18:50
Show Gist options
  • Save longbuilder/9a59e8d77f5836f11720 to your computer and use it in GitHub Desktop.
Save longbuilder/9a59e8d77f5836f11720 to your computer and use it in GitHub Desktop.
golang struct packed to network buffer
// struct filed only support uint* and string
// for string, there should be a value to represent the length of string
// packed
func WriteStructToBuffer(buffer *bytes.Buffer, data interface{}) error {
v := reflect.Indirect(reflect.ValueOf(data))
if v.Kind() != reflect.Struct {
return errors.New("invaild type Not a struct")
}
for i := 0; i < v.NumField(); i++ {
switch v.Field(i).Type().Kind() {
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
err := binary.Write(buffer, binary.BigEndian, v.Field(i).Interface())
if err != nil {
return err
}
break;
case reflect.String:
s := v.Field(i).String()
b := []byte(s)
err := binary.Write(buffer, binary.BigEndian, uint16(len(b)))
if err != nil {
return err
}
_, err = buffer.Write(b)
if err != nil {
return err
}
break;
default:
return errors.New("invail type Unspport reflect type")
}
}
return nil
}
//unpacked
func ReadStructFromBuffer(buffer *bytes.Buffer, data interface{}) error {
k := reflect.TypeOf(data).Kind()
if k != reflect.Ptr {
return errors.New("the second parameter must be a pointer")
}
v := reflect.ValueOf(data).Elem()
if v.Kind() != reflect.Struct {
return errors.New("invaild type Not a struct")
}
for i := 0; i < v.NumField(); i++ {
switch v.Field(i).Type().Kind() {
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
err := binary.Read(buffer, binary.BigEndian, v.Field(i).Addr().Interface())
if err != nil {
return err
}
break;
case reflect.String:
var strlen uint16
err := binary.Read(buffer, binary.BigEndian, &strlen)
if err != nil {
return err
}
v.Field(i).SetString(string(buffer.Next(int(strlen))))
break;
default:
return errors.New("invail type Unspport reflect type")
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment