Unmarshalling von Protobuf-Nachrichten in einer Schnittstelle{} zur Erleichterung der Typumwandlung ist nicht möglich, da die Funktion proto.Unmarshal ein Argument vom Typ erwartet proto.Message, eine Schnittstelle, die konkrete Protobuf-Typen implementieren.
In Fällen, in denen dem Byte-Slice zumindest einige Kontextinformationen (z. B. eine Zeichenfolge oder eine Zahl) beiliegen, können Sie diese Informationen verwenden, um sie dem erwarteten Protobuf-Typ zuzuordnen und ihn zu instanziieren, bevor Sie ihn an Proto übergeben .Unmarshal:
func decodeWithMetadata(data []byte, identifier string) error { var message proto.Message switch identifier { case "foo": message = &mypb.Foo{} case "bar": message = &mypb.Bar{} } if err := proto.Unmarshal(data, message); err != nil { return err } log.Printf("%v\n", data) return nil }
Allerdings, wenn Die Byte-Nutzlast ist völlig unbekannt. Betrachten Sie das Protowire-Paket, das das Extrahieren begrenzter Informationen aus Wire-formatierten Protobuf-Nachrichten ermöglicht. Beachten Sie, dass die Drahtdarstellung von Protobuf-Nachrichten mehrdeutig ist, was zu einer schwachen Semantik führt.
Der folgende Code analysiert unbekannte Protobuf-Nachrichten:
type Field struct { Tag Tag Val Val } type Tag struct { Num int32 Type protowire.Type } type Val struct { Payload interface{} Length int } func parseUnknown(b []byte) []Field { // ... implementation to parse unknown protobuf messages as described in the provided answer ... }
Angesichts eines Protobuf-Schemas wie:
message Foo { string a = 1; string b = 2; Bar bar = 3; } message Bar { string c = 1; }
Der folgende Code zeigt, wie der Parser verwendet wird:
// Parse the protobuf message as byte slice b := []byte{0x0a, 0x01, 0x41, 0x12, 0x01, 0x42, 0x1a, 0x03, 0x43} fields := parseUnknown(b) for _, field := range fields { fmt.Printf("%#v\n", field) }
Ausgabe:
main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x41}, Length:1}} main.Field{Tag:main.Tag{Num:2, Type:2}, Val:main.Val{Payload:[]uint8{0x42}, Length:1}} main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}} main.Field{Tag:main.Tag{Num:3, Type:2}, Val:main.Val{Payload:[]main.Field{main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}}}, Length:3}}
Das obige ist der detaillierte Inhalt vonWie entmarshaliere ich unbekannte Protobuf-Nachrichten in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!