2010-05-12 5 views
6

A l'aide de Google Protocol Buffers, puis-je définir une taille maximale pour tous les messages que je code? Si je sais que ce que je code n'est jamais plus grand que X octets, alors Protobuffs de Google produira toujours un tampon de taille Y, et si je lui donne une plus petite quantité de données, je le tamponnerai à la taille Y?Google Protocol Buffers - Tampon de taille fixe?

Répondre

5

Le format de fil pour les tampons de protocole ne rendrait pas ce trivial; Je ne suis pas conscient de de quelque chose pour le faire, mais une option serait de le sérialiser dans un tampon avec votre propre longueur en-tête et pad avec des données supplémentaires au besoin.

Vous devez ajouter un préfixe de longueur car il n'est pas ajouté par défaut, sinon il lirait la mémoire à la fin de votre tampon. Même les 0 à la traîne ne seraient pas légaux (ils chercheraient un numéro de champ).

Je ne peux pas commenter sur le C++ ou de Jon version C#, mais pour mon C# version (protobuf-net), vous devriez être en mesure de faire quelque chose comme (non testé):

using(var ms = new MemoryStream(fixedLength)) { 
    ms.SetLength(fixedLength); 
    Serializer.SerializeWithLengthPrefix(ms, obj); 
    if(ms.Length > fixedLength) { /* boom */ } 
    byte[] arr = ms.ToArray(); // use this 
} 

Cette devrait désérialiser correctement si également en utilisant DeserializeWithLengthPrefix.


Re les questions (commentaires); SerializeWithLengthPrefix est un protobuf-net -specific méthode; il peut être quelque chose dans la version C++, mais c'est assez simple. La façon de mettre en œuvre cette plus facile à partir de zéro est:

  • suppose que nous allons laisser un en-tête de longueur fixe (4 octets) pour indiquer le volume de données réelles que nous avons
  • sauter 4 octets (ou écrire 00- 00-00-00)
  • maintenant serialize au reste du tampon
  • trouver le nombre d'octets que vous venez d'écrire
  • écrire cette valeur de retour au début du tampon

en sens inverse, évidemment:

  • lire 4 octets et interpréter comme un entier
  • deserialize que beaucoup de données

Il est un peu peu plus complexe protobuf- net, car il offre un peu plus d'options (comment l'int devrait être codé, et si oui ou non pour l'envelopper de sorte que le chose entière peut encore être traité comme un flux de protobuf 100% value - in particulier I suspect Je viens de décrire le comportement si j'ai demandé SerializeWithLengthPrefix d'utiliser le codage à largeur fixe et "champ 0").

+0

Merci beaucoup Marc, toujours utile. Pouvez-vous expliquer plus en détail ce que SerializeWithLengthPrefix fait réellement? Merci encore! – Roey

+0

Encore une chose, je désérialise avec la version C++ de Protocol Buffers .... est-ce que DeserializeWithLengthPrefix existe sous une forme quelconque dans la version C++ ?? – Roey

+0

@Roey - Je vais modifier cette information dans ... –

Questions connexes