Maison > développement back-end > Golang > Comment désorganiser les messages Protobuf inconnus dans Go ?

Comment désorganiser les messages Protobuf inconnus dans Go ?

Linda Hamilton
Libérer: 2024-12-03 02:15:10
original
792 Les gens l'ont consulté

How to Unmarshal Unknown Protobuf Messages in Go?

Désassembler les messages Protobuf inconnus dans Go

Désassembler les messages protobuf dans une interface{} pour faciliter la conversion de type n'est pas réalisable car la fonction proto.Unmarshal attend un argument de type proto.Message, une interface implémentée par des types protobuf concrets.

Approche alternative avec métadonnées connues

Dans les cas où au moins certaines informations contextuelles (par exemple, une chaîne ou un nombre) accompagnent la tranche d'octets, vous pouvez utiliser ces informations pour mapper le type de protobuf attendu et l'instancier avant de le transmettre à proto .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
}
Copier après la connexion

Analyse de charges utiles complètement inconnues

Cependant, si la charge utile de l'octet est entièrement inconnue, considérez le package protowire, qui permet d'extraire des informations limitées à partir de messages protobuf au format filaire. Gardez à l'esprit que la représentation filaire des messages protobuf est ambiguë, ce qui conduit à une sémantique faible.

Implémentation de l'analyseur

Le code suivant analyse les messages protobuf inconnus :

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 ...
}
Copier après la connexion

Exemple Utilisation

Étant donné un schéma protobuf comme :

message Foo {
  string a = 1;
  string b = 2;
  Bar bar = 3;
}

message Bar {
  string c = 1;
}
Copier après la connexion

Le code suivant montre comment utiliser l'analyseur :

// 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)
}
Copier après la connexion

Sortie :

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}}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal