Буферы Протокола Google - буфер Фиксированного размера?

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

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

6
задан Roey 12 May 2010 в 06:19
поделиться

1 ответ

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

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

Я не могу прокомментировать версию C++ или 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").

5
ответ дан 17 December 2019 в 04:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: