I already found encoding/binary package to deal with it, but it depended on reflect package so it didn't work with uncapitalized(that is, unexported) struct fields. However I spent a week to find that problem out, I still have a question: if struct fields should not be exported, how do I dump them easily into binary data?
EDIT: Here's the example. If you capitalize the name of fields of Data
struct, that works properly. But Data
struct was intended to be an abstract type, so I don't want to export these fields.
package main import ( "fmt" "encoding/binary" "bytes" ) type Data struct { id int32 name [16]byte } func main() { d := Data{Id: 1} copy(d.Name[:], []byte("tree")) buffer := new(bytes.Buffer) binary.Write(buffer, binary.LittleEndian, d) // d was written properly fmt.Println(buffer.Bytes()) // try to read... buffer = bytes.NewBuffer(buffer.Bytes()) var e = new(Data) err := binary.Read(buffer, binary.LittleEndian, e) fmt.Println(e, err) }
Your best option would probably be to use the gob package and let your struct implement the GobDecoder and GobEncoder interfaces in order to serialize and deserialize private fields.
This would be safe, platform independent, and efficient. And you have to add those GobEncode and GobDecode functions only on structs with unexported fields, which means you don't clutter the rest of your code.
func (d *Data) GobEncode() ([]byte, error) { w := new(bytes.Buffer) encoder := gob.NewEncoder(w) err := encoder.Encode(d.id) if err!=nil { return nil, err } err = encoder.Encode(d.name) if err!=nil { return nil, err } return w.Bytes(), nil } func (d *Data) GobDecode(buf []byte) error { r := bytes.NewBuffer(buf) decoder := gob.NewDecoder(r) err := decoder.Decode(&d.id) if err!=nil { return err } return decoder.Decode(&d.name) } func main() { d := Data{id: 7} copy(d.name[:], []byte("tree")) buffer := new(bytes.Buffer) // writing enc := gob.NewEncoder(buffer) err := enc.Encode(d) if err != nil { log.Fatal("encode error:", err) } // reading buffer = bytes.NewBuffer(buffer.Bytes()) e := new(Data) dec := gob.NewDecoder(buffer) err = dec.Decode(e) fmt.Println(e, err) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With