Google Protocol Buffers - фиксированный размер буфера? - PullRequest
6 голосов
/ 12 мая 2010

Используя буферы протокола Google, могу ли я установить максимальный размер для всех кодируемых сообщений?

Если я знаю, что то, что я кодирую, никогда не превышает X байт, то Google Protobuffs всегда создает буфер размераY, и если я дам ему меньшее количество данных, добавьте его в размер Y?

1 Ответ

5 голосов
/ 12 мая 2010

Формат проводов для буферов протокола не будет таким тривиальным; Я не знаю о том, что можно сделать, но одним из вариантов было бы сериализовать его в буфер с вашим собственным заголовком длины и дополнением при необходимости дополнительными данными.

Вам нужно добавить префикс длины, потому что он не добавлен по умолчанию, иначе это будет чтение мусора в конце вашего буфера. Даже конечные 0 не будут законными (это будет искать номер поля).

Я не могу комментировать версию C ++ или Jon's C #, но для моей версии C # (protobuf-net) вы должны иметь возможность сделать что-то вроде (не проверено):

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

Это должно десериализовать нормально, если также используется DeserializeWithLengthPrefix.


По вопросам (комментариям); SerializeWithLengthPrefix является protobuf-net -специфичным методом; может быть чем-то в версии C ++, но это довольно просто. Самый простой способ реализовать это с нуля :

  • предположим, что мы оставим заголовок фиксированной длины (4 байта), чтобы указать, сколько реальных данных у нас есть
  • пропустить 4 байта (или записать 00-00-00-00)
  • теперь сериализовать в оставшуюся часть буфера
  • найдите сколько байтов вы только что написали
  • записать это значение обратно в начало буфера

наоборот, очевидно:

  • читать 4 байта и интерпретировать как int
  • десериализовать столько, сколько данные

В protobuf-net это немного немного сложнее, поскольку он предлагает еще несколько опций (как должен кодироваться int, и нужно ли оборачивать это так, чтобы весь ) вещь все еще может рассматриваться как поток protobuf со 100% значением - в частности, я подозреваю Я только что описал поведение, если я попросил SerializeWithLengthPrefix использовать кодирование с фиксированной шириной и "поле 0" ).

...