Rumah >pembangunan bahagian belakang >Golang >Bagaimanakah Saya Boleh Menghuraikan Mesej Protobuf Tidak Diketahui Tanpa Maklumat Jenis?
Unknown Message Proto Demarshalling Without Type Information
Walaupun kaedah proto.Unmarshal() protobuf memerlukan jenis mesej yang diketahui, mesej yang tidak diketahui memberikan cabaran . Walau bagaimanapun, kami boleh mengekstrak maklumat terhad menggunakan pakej protowire.
Pendekatan:
Kenal pasti jenis medan, yang boleh menjadi:
Model Data:
type Field struct { Tag Tag Val Val } type Tag struct { Num int32 Type protowire.Type } type Val struct { Payload interface{} Length int }
Penghurai:
func parseUnknown(b []byte) []Field { // Iteratively consume and parse fields for len(b) > 0 { // Read field tag and length n, t, fieldlen := protowire.ConsumeField(b) if fieldlen < 1 { return nil } field := Field{Tag: Tag{Num: int32(n), Type: t}} // Read and process tag and value content _, _, taglen := protowire.ConsumeTag(b[:fieldlen]) if taglen < 1 { return nil } var v interface{} var vlen int switch t { case protowire.VarintType: v, vlen = protowire.ConsumeVarint(b[taglen:fieldlen]) case protowire.Fixed64Type: v, vlen = protowire.ConsumeFixed64(b[taglen:fieldlen]) case protowire.BytesType: v, vlen = protowire.ConsumeBytes(b[taglen:fieldlen]) sub := parseUnknown(v.([]byte)) if sub != nil { v = sub } case protowire.StartGroupType: v, vlen = protowire.ConsumeGroup(n, b[taglen:fieldlen]) sub := parseUnknown(v.([]byte)) if sub != nil { v = sub } case protowire.Fixed32Type: v, vlen = protowire.ConsumeFixed32(b[taglen:fieldlen]) } if vlen < 1 { return nil } field.Val = Val{Payload: v, Length: vlen - taglen} fields = append(fields, field) b = b[fieldlen:] } return fields }
Contoh (Struktur Mesej):
message Foo { string a = 1; string b = 2; Bar bar = 3; } message Bar { string c = 1; }
Contoh (Output Dihurai):
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}}
Pertimbangan:
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Menghuraikan Mesej Protobuf Tidak Diketahui Tanpa Maklumat Jenis?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!