Есть ли эквиваленты C++ для разграниченных функций ввода-вывода Буферов Протокола в Java?

Я пытаюсь читать / пишут несколько Буферных сообщений Протокола из файлов, и в C++ и в Java. Google предлагает писать префиксы длины перед сообщениями, но нет никакого способа сделать это по умолчанию (что я видел).

Однако API Java в версии 2.1.0 получил ряд "Разграниченных" функций ввода-вывода, которые, по-видимому, делают то задание:

parseDelimitedFrom
mergeDelimitedFrom
writeDelimitedTo

Есть ли эквиваленты C++? И в противном случае каков проводной формат для префиксов размера Java присоединения API, таким образом, я могу проанализировать те сообщения в C++?


Обновление:

Они теперь существуют в google/protobuf/util/delimited_message_util.h с v3.3.0.

64
задан tzaman 20 December 2018 в 22:32
поделиться

3 ответа

Я решил ту же проблему, используя CodedOutputStream/ArrayOutputStream для записи сообщения (с размером) и CodedInputStream/ArrayInputStream для чтения сообщения (с размером).

Например, следующий псевдокод записывает размер сообщения, за которым следует сообщение:

const unsigned bufLength = 256;
unsigned char buffer[bufLength];
Message protoMessage;

google::protobuf::io::ArrayOutputStream arrayOutput(buffer, bufLength);
google::protobuf::io::CodedOutputStream codedOutput(&arrayOutput);

codedOutput.WriteLittleEndian32(protoMessage.ByteSize());
protoMessage.SerializeToCodedStream(&codedOutput);

При записи вы также должны проверить, что ваш буфер достаточно велик, чтобы вместить сообщение (включая размер). А при чтении вы должны проверить, что ваш буфер содержит целое сообщение (включая размер).

Определенно было бы удобно, если бы в C++ API добавили методы удобства, аналогичные тем, которые предоставляет Java API.

12
ответ дан 24 November 2019 в 15:51
поделиться

Итак, я не смог найти функции верхнего уровня C++, реализующие то, что мне нужно, но некоторые поиски в справке Java API привели к следующему, внутри интерфейса MessageLite:

void writeDelimitedTo(OutputStream output)
/*  Like writeTo(OutputStream), but writes the size of 
    the message as a varint before writing the data.   */

Итак, префикс размера в Java - это (Protocol Buffers) varint!

Вооруженный этой информацией, я пошел копаться в C++ API и нашел заголовок CodedStream, в котором есть следующее:

bool CodedInputStream::ReadVarint32(uint32 * value)
void CodedOutputStream::WriteVarint32(uint32 value)

Используя это, я должен быть в состоянии создать свои собственные C++ функции, которые выполняют эту работу.

Они действительно должны добавить это в основной Message API; это недостающая функциональность, учитывая, что Java имеет это, как и отличный порт Марка Грейвелла protobuf-net C# (через SerializeWithLengthPrefix и DeserializeWithLengthPrefix).

17
ответ дан 24 November 2019 в 15:51
поделиться

Вы можете использовать getline для чтения строки из потока, используя указанный разделитель:

istream& getline ( istream& is, string& str, char delim );

(определено в заголовке)

-6
ответ дан 24 November 2019 в 15:51
поделиться
Другие вопросы по тегам:

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