Функции ввода-вывода с разделителями в буферах протокола: эквиваленты C
В сценариях, когда несколько сообщений протокольных буферов считываются или записываются из файлов в обоих C и Java возникает необходимость добавлять к сообщениям префиксы длины. Хотя API Java предоставляет для этой цели специальные функции ввода-вывода с разделителями, их эквивалентные аналоги в C могут быть неочевидны.
Недавнее обновление показывает, что такие эквиваленты C теперь находятся в google/protobuf/util. /delimited_message_util.h как часть версии 3.3.0. Однако до этого обновления существовали альтернативные реализации, которые эффективно удовлетворяли этому требованию.
Одна из таких реализаций, предоставленная бывшим автором библиотек protobuf C и Java, включает оптимизации, предотвращающие потенциальные сбои после 64 МБ ввода. . Эти реализации, как показано ниже, применяют ограничение в 64 МБ для отдельных сообщений, гарантируя бесперебойную потоковую передачу без превышения общего ограничения.
Оптимизированные реализации ввода-вывода с разделителями для C
bool writeDelimitedTo(
const google::protobuf::MessageLite& message,
google::protobuf::io::ZeroCopyOutputStream* rawOutput) {
// Initialize a CodedOutputStream for each message.
google::protobuf::io::CodedOutputStream output(rawOutput);
// Determine the message size and write it as a Varint.
int size = message.ByteSize();
output.WriteVarint32(size);
// Optimize for messages fitting into a single buffer.
uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL) message.SerializeWithCachedSizesToArray(buffer);
else message.SerializeWithCachedSizes(&output);
return true;
}
bool readDelimitedFrom(
google::protobuf::io::ZeroCopyInputStream* rawInput,
google::protobuf::MessageLite* message) {
// Initialize a CodedInputStream for each message.
google::protobuf::io::CodedInputStream input(rawInput);
// Read the message size.
uint32_t size;
if (!input.ReadVarint32(&size)) return false;
// Restrict reading to the determined message size.
google::protobuf::io::CodedInputStream::Limit limit =
input.PushLimit(size);
// Parse the message and verify it fits within the limit.
if (!message->MergeFromCodedStream(&input)) return false;
if (!input.ConsumedEntireMessage()) return false;
// Lift the reading restriction.
input.PopLimit(limit);
return true;
}
Эти оптимизированные реализации эффективно обрабатывают сообщения разного размера и обеспечивают надежное решение для ввода-вывода с разделителями в C .
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3