Как кодировать / декодировать вложенные сообщения, используя protobuf? - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть структура protobuf, которая представляет вложенные слои / оболочки структур. При кодировании этих данных вся иерархия может обрабатываться в одном наборе.

Однако при декодировании должен декодироваться только первый внешний конверт, и вложенный конверт должен оставаться закодированным для передачи в нисходящем направлении для декодирования следующим архитектурным слоем и т. Д. Каждый уровень знает только о структуре конверта. предназначено для этого.

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

Есть ли лучший способ справиться с этим? И бонусный вопрос, есть ли лучший способ при использовании nanopb?

1 Ответ

0 голосов
/ 06 сентября 2018

Если вы используете proto2 (а не proto3), это, похоже, хорошо подойдет для extensions . Каждое «внешнее» сообщение будет определять диапазон расширения, например (для цитирования из документа):

message Foo {
  // ...
  extensions 100 to 199;
}

Затем в вашей "внутренней" схеме вы можете объявить дополнительные поля для родительского сообщения - либо тривиальные поля, либо целые объекты:

message Bar { /*...*/ }
extend Foo {
  optional Bar bar = 126;
}

Затем «внутренний» код использует любой API «расширений» для выбранной вами платформы; если вы используете реализацию Google, то это ряд методов, таких как HasExtension(), ClearExtension(), GetExtension(), MutableExtension() и AddExtension(), но разные реализации могут иметь разные API.

При таком подходе «внешнее» сообщение никогда не имеет (или не нуждается) в знании внутренних данных; библиотека занимается всем этим.

Самое замечательное в этом подходе состоит в том, что он является побайтным идентичным использованию bytes - поэтому ваши существующие данные должны быть полностью совместимы с тем, если вы использовали:

message Foo {
    optional bytes bar = 126;
}

Обратите внимание, что proto3 не поддерживает расширения . Существует новая концепция Any, которая предлагает в целом аналогичные результаты, но работает совсем по-другому. Он не совместим с байтами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...