标准包encoding/binary
可用于操作原始 C 结构。您可以扩展 Read 和 Write 函数以支持自定义类型:
func Read(r io.Reader, order binary.ByteOrder, data interface{}) error {
switch data := data.(type) {
case *foo:
return readFoo(r, order, data)
// (...)
default:
return binary.Read(r, order, data)
}
}
func Write(w io.Writer, order binary.ByteOrder, data interface{}) error {
switch data := data.(type) {
case foo:
return writeFoo(r, order, data)
// (...)
default:
return binary.Write(r, order, data)
}
}
使用包含所有联合字段的结构并使用应用程序上下文来决定将哪个值编码到 C 联合中。
type foo struct {
is_i bool
i int32
f float32
}
// Read a foo from r into data
func readFoo(r io.Reader, order binary.ByteOrder, data *foo) error {
b := make([]byte, 4)
if _, err := io.ReadFull(r, b); err != nil {
return err
}
*data = foo{
i: int32(order.PutUint32(b)),
f: float32(order.PutUint32(b)),
}
return nil
}
// Write a foo from data into w
func writeFoo(w io.Writer, order binary.ByteOrder, data foo) error {
b := make([]byte, 4)
if data.is_i {
order.PutUint32(b, uint32(data.i))
} else {
order.PutUint32(b, uint32(data.f))
}
_, err := w.Write(b)
return err
}
(或者,使用 getter 和 setter: http: //pastebin.com/H1QW5AFb)
使用按位运算来编组位域
type bar struct {
x bool
y uint
z uint
}
// Read a bar from r into data
func readBar(r io.Reader, order binary.ByteOrder, data *foo) error {
b := make([]byte, 1)
if _, err := io.ReadFull(r, b); err != nil {
return err
}
// Read from bitfield
*data = bar{
x: bool(b[0] >> 7), // bool x:1;
y: uint((b[0] & 0x70) >> 3), // unsigned int y:3;
z: uint(b[0] & 0x0f), // unsigned int z:4;
}
return nil
}
// Write a bar from data into w
func writeBar(w io.Writer, order binary.ByteOrder, data bar) error {
b := make([]byte, 1)
var x uint8
if data.x {
x = 1
}
// Create bitfield
b[0] = (x & 0x01 << 7) & // bool x:1;
(uint8(data.y) & 0x03 << 4) & // unsigned int y:3;
(uint8(data.z) & 0x04) // unsigned int z:4;
_, err := w.Write(b)
return err
}
baz 的序列化形式取决于编译器对 complex 的内部定义。使用时encoding.binary
,字段有 1 字节对齐,因此 quux 可以直接编组。