5. Représentations de types primitifs (Primitive Type Representations)
L'encodage HPACK utilise deux types primitifs : des entiers de longueur variable non signés et des chaînes d'octets.
5.1. Représentation d'entier (Integer Representation)
Les entiers sont utilisés pour représenter des index de noms, des index de champs d'en-tête ou des longueurs de chaînes. Une représentation d'entier peut commencer n'importe où dans un octet. Pour permettre un traitement optimisé, une représentation d'entier se termine toujours à la fin d'un octet.
Un entier est représenté en deux parties : un préfixe qui remplit l'octet actuel et une liste optionnelle d'octets qui sont utilisés si la valeur entière ne tient pas dans le préfixe. Le nombre de bits du préfixe (appelé N) est un paramètre de la représentation d'entier.
Si la valeur entière est suffisamment petite, c'est-à-dire strictement inférieure à 2^N-1, elle est encodée dans le préfixe de N bits.
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| ? | ? | ? | Value |
+---+---+---+-------------------+
Figure 2 : Valeur entière encodée dans le préfixe (N = 5)
Sinon, tous les bits du préfixe sont mis à 1, et la valeur, diminuée de 2^N-1, est encodée en utilisant une liste d'un ou plusieurs octets. Le bit de poids fort de chaque octet est utilisé comme indicateur de continuation : sa valeur est mise à 1 sauf pour le dernier octet de la liste. Les bits restants des octets sont utilisés pour encoder la valeur diminuée.
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| ? | ? | ? | 1 1 1 1 1 |
+---+---+---+-------------------+
| 1 | Value-(2^N-1) LSB |
+---+---------------------------+
...
+---+---------------------------+
| 0 | Value-(2^N-1) MSB |
+---+---------------------------+
Figure 3 : Valeur entière encodée après le préfixe (N = 5)
Le décodage de la valeur entière à partir de la liste d'octets commence par inverser l'ordre des octets dans la liste. Ensuite, pour chaque octet, son bit de poids fort est supprimé. Les bits restants des octets sont concaténés, et la valeur résultante est augmentée de 2^N-1 pour obtenir la valeur entière.
La taille du préfixe, N, est toujours comprise entre 1 et 8 bits. Un entier commençant à la limite d'un octet aura un préfixe de 8 bits.
Pseudo-code pour représenter un entier I :
if I < 2^N - 1, encode I on N bits
else
encode (2^N - 1) on N bits
I = I - (2^N - 1)
while I >= 128
encode (I % 128 + 128) on 8 bits
I = I / 128
encode I on 8 bits
Pseudo-code pour décoder un entier I :
decode I from the next N bits
if I < 2^N - 1, return I
else
M = 0
repeat
B = next octet
I = I + (B & 127) * 2^M
M = M + 7
while B & 128 == 128
return I
Des exemples illustrant l'encodage des entiers sont disponibles dans l'annexe C.1.
Cette représentation d'entier permet des valeurs de taille indéfinie. Il est également possible pour un encodeur d'envoyer un grand nombre de valeurs zéro, ce qui peut gaspiller des octets et pourrait être utilisé pour déborder les valeurs entières. Les encodages d'entiers qui dépassent les limites d'implémentation -- en valeur ou en longueur d'octets -- DOIVENT (MUST) être traités comme des erreurs de décodage. Différentes limites peuvent être définies pour chacune des différentes utilisations des entiers, en fonction des contraintes d'implémentation.
5.2. Représentation de littéral de chaîne (String Literal Representation)
Les noms de champs d'en-tête et les valeurs de champs d'en-tête peuvent être représentés sous forme de littéraux de chaîne (String Literal). Un littéral de chaîne est encodé comme une séquence d'octets, soit en encodant directement les octets du littéral de chaîne, soit en utilisant un code de Huffman (voir [HUFFMAN]).
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| H | String Length (7+) |
+---+---------------------------+
| String Data (Length octets) |
+-------------------------------+
Figure 4 : Représentation de littéral de chaîne
Une représentation de littéral de chaîne contient les champs suivants :
H : Un indicateur d'un bit, H, indiquant si les octets de la chaîne sont encodés en Huffman ou non.
Longueur de chaîne (String Length) : Le nombre d'octets utilisés pour encoder le littéral de chaîne, encodé comme un entier avec un préfixe de 7 bits (voir section 5.1).
Données de chaîne (String Data) : Les données encodées du littéral de chaîne. Si H vaut '0', alors les données encodées sont les octets bruts du littéral de chaîne. Si H vaut '1', alors les données encodées sont l'encodage de Huffman du littéral de chaîne.
Les littéraux de chaîne qui utilisent l'encodage de Huffman sont encodés avec le code de Huffman défini dans l'annexe B.