2013-03-06 1 views
4

У меня есть несколько двоичных данных, которые были получены путем сериализации класса буфера протокола google. Как узнать во время выполнения класс, для которого данные были сериализованы.Поиск типа сообщения буфера протокола из сериализованных данных

Например, предположим, что у меня есть класс abc. Я сериализую этот класс abc в двоичные данные. Есть ли способ проверить, что эти двоичные данные были получены путем сериализации класса abc,, а не какого-либо другого класса?

Кроме того, если я проанализирую эти двоичные данные класса abc методом parse class xyz, как бы узнать, был ли анализ сильным.

+0

Если у вас есть контроль над обоими концами соединения, вы можете «обмануть», добавив имя (outermost) класса в качестве префикса для данных буферов протокола Google. Вот что я делаю, см. Здесь http://stackoverflow.com/a/17923846/253938. – RenniePet

+0

Хм .. это сработало бы: D..b грустно, у меня нет контроля над стороной отправителей. –

ответ

3

protobuf не содержит информацию о типе на проводе (если только вы не делаете это самостоятельно вне протобуфа). Как таковой вы не можете строго подтвердите это - что на самом деле хорошо вещь, потому что это означает, что типы взаимозаменяемы и совместимы. До тех пор, пока class abcимеет совместимый договор с другим типом, он будет работать. Под «совместимым» здесь я имею в виду: для любых чисел полей, которые являются общими для обоих, они имеют совместимые типы проводников. Если abc объявляет поле 4 строкой, а другой класс объявляет поле 4 числом с двойной точностью, то при десериализации он будет терпеть неудачу.

Еще один «сигнал» вы можете использовать это упущение required полей: если abc всегда включает в себя поле 3, но вы получите данные, которые опускает поле 3, то это, вероятно, не является abc. Обратите внимание, что protobuf спроектирован так, чтобы быть толерантным к версии, хотя: вы не можете предположить, что дополнительные поля означают, что это не abc, так как может случиться так, что данные используют более позднюю версию контракта или используют расширение поля. Аналогично, отсутствующие необязательные поля могут отсутствовать, потому что либо они просто решили не указывать значение или, что это поле не указано в версии контракта, который они используют.

Повторное тестирование для успешного анализа: это будет конкретный вариант реализации. Я хотел бы представить, что реализация C++ будет иметь либо возвращаемое значение для проверки, либо поле флага для проверки. Я не использую эту апи, поэтому не могу сказать. На некоторых других платформах я ожидал бы, что исключение будет выбрано (java, .net и т. Д.), Если возникла критическая проблема.

+0

Функции разбора возвращают значение bool. Но, к сожалению, они возвращаются _true_ в обоих случаях - если я анализирую с использованием класса 'class abc' или' class xyz' –

+0

@TusharKoul, по сравнению с остальной частью моего ответа: есть ли что-либо между 'abc' и' xyz', которое сделать их * несовместимыми *? Главным здесь было бы полевое число с очень разными значениями в двух случаях. В целом, protobuf принимает философию, что вы уже знаете, какими должны быть ваши данные, и * получите все правильно *. –

+0

Вопрос не о совместимости. Я просто хотел проверить, что данные будут проанализированы для правильного класса. Как вы упомянули в комментарии, если класс был неправильным, и синтаксический анализ возвращал false, я бы знал, что я вызываю синтаксический анализ для неправильного класса. Но я догадываюсь, что вы правы о философии протобуфа, что тип класса должен быть уже известен. –