Funciones de E/S delimitadas en buffers de protocolo: equivalentes de C
En escenarios donde se leen o escriben múltiples mensajes de buffers de protocolo desde archivos en ambos C y Java, resulta necesario adjuntar prefijos de longitud a los mensajes. Si bien la API de Java proporciona funciones de E/S "delimitadas" dedicadas para este propósito, sus equivalentes en C pueden no ser evidentes.
La actualización reciente indica que dichos equivalentes en C ahora residen en google/protobuf/util /delimited_message_util.h como parte de la versión 3.3.0. Sin embargo, antes de esta actualización, había implementaciones alternativas que abordaban este requisito de manera eficiente.
Una de esas implementaciones, proporcionada por un antiguo autor de las bibliotecas protobuf de C y Java, incluye optimizaciones que evitan posibles fallas después de 64 MB de entrada. . Estas implementaciones, como se muestra a continuación, aplican el límite de 64 MB en mensajes individuales, lo que garantiza que la transmisión continúe sin problemas sin exceder el límite general.
Implementaciones de E/S delimitadas optimizadas para 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;
}
Estas implementaciones optimizadas manejan eficazmente mensajes de distintos tamaños y proporcionan una solución confiable para E/S delimitadas en C.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3