Ejercicio: Análisis de Protobuf
En este ejercicio, vas a compilar un analizador para la codificación binaria de protobuf. No hay nada de lo que preocuparse, es más sencillo de lo que parece. En este ejemplo se muestra un patrón de análisis muy habitual que consiste en transferir fracciones de datos. Los datos subyacentes nunca se copian.
Para poder llevar a cabo un análisis completo de un mensaje de protobuf, es necesario conocer los tipos de campos, indexados por el número de campo. Se suelen proporcionar en un archivo proto
. En este ejercicio, codificaremos esa información en declaraciones match
en funciones a las que se llama para cada campo.
Usaremos el proto que sigue:
message PhoneNumber {
optional string number = 1;
optional string type = 2;
}
message Person {
optional string name = 1;
optional int32 id = 2;
repeated PhoneNumber phones = 3;
}
Un mensaje proto se codifica como una serie de campos, uno detrás del otro. Cada uno se implementa como una “etiqueta” seguida del valor. La etiqueta contiene un número de campo (por ejemplo, 2
para el campo id
de un mensaje de Person
) y un tipo de wire que define cómo se debe definir la carga útil a partir del flujo de bytes.
Los números enteros, incluida la etiqueta, se representan con una codificación de longitud variable denominada VARINT. A continuación puedes consultar la definición de parse_varint
. El código dado también define retrollamadas para gestionar los campos Person
y PhoneNumber
, así como analizar un mensaje en una serie de llamadas a dichas retrollamadas.
Ahora solo tienes que implementar la función parse_field
y el trait ProtoMessage
para Person
y PhoneNumber
.
Speaker Notes
This slide and its sub-slides should take about 30 minutes.
- En este ejercicio hay varios casos en los cuales la lección del protobuf puede fallar, e.g. si intentas leer un
i32
cuando hay menos de 4 bytes restantes en el buffer de datos. Normalmente usaríamos el enumResult
, pero para simplificar el ejercicio inducimos pánico si ocurre un error. En el día 4 cubriremos el manejo de errores en Rust en mas detall