summaryrefslogtreecommitdiff
path: root/src/common/leb128.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/leb128.c')
-rw-r--r--src/common/leb128.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/common/leb128.c b/src/common/leb128.c
index c3f7466..c8d2ace 100644
--- a/src/common/leb128.c
+++ b/src/common/leb128.c
@@ -109,3 +109,210 @@ bool read_leb128(leb128_t *target, const bin_t *data, phys_t *pos, phys_t len)
return (i < 8);
}
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur à consigner. *
+* pbuf = tampon de données à constituer. [OUT] *
+* *
+* Description : Encode un nombre non signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool pack_uleb128(const uleb128_t *value, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ uleb128_t tmp; /* Valeur modifiable */
+ uint8_t byte; /* Octet à transposer */
+
+ tmp = *value;
+
+ do
+ {
+ byte = (tmp & 0x7f);
+ tmp >>= 7;
+
+ if (tmp != 0)
+ byte |= 0x80;
+
+ result = extend_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
+
+ }
+ while (result && tmp != 0);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur à consigner. *
+* pbuf = tampon de données à constituer. [OUT] *
+* *
+* Description : Encode un nombre signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool pack_leb128(const leb128_t *value, packed_buffer_t *pbuf)
+{
+
+ bool result; /* Bilan à retourner */
+ uleb128_t tmp; /* Valeur modifiable */
+ bool more; /* Poursuite des traitements */
+ bool negative; /* Nature de la valeur */
+ uint8_t byte; /* Octet à transposer */
+
+ tmp = *value;
+
+ more = true;
+ negative = (*value < 0);
+
+ while (more)
+ {
+ byte = (tmp & 0x7f);
+ tmp >>= 7;
+
+ /**
+ * Propagation forcée du bit de signe pour les implémentations de
+ * décalage basées sur une opération logique et non arithmétique.
+ */
+
+ if (negative)
+ tmp |= (~0llu << (LEB128_BITS_COUNT - 7));
+
+ /**
+ * Le bit de signe n'est pas le bit de poids fort ici :
+ * On travaille sur 7 bits, donc le masque est 0x40 !
+ */
+
+ if ((tmp == 0 && (byte & 0x40) == 0x00) || (tmp == -1 && (byte & 0x40) == 0x40))
+ more = false;
+
+ else
+ byte |= 0x80;
+
+ result = extend_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur à constituer. [OUT] *
+* pbuf = tampon de données à consulter. *
+* *
+* Description : Décode un nombre non signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool unpack_uleb128(uleb128_t *value, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ unsigned int shift; /* Décalage à appliquer */
+ uint8_t byte; /* Octet à transposer */
+
+ result = true;
+
+ *value = 0;
+
+ shift = 0;
+
+ while (true)
+ {
+ /* Encodage sur trop d'octets ? */
+ if (shift > (7 * sizeof(uleb128_t)))
+ {
+ result = false;
+ break;
+ }
+
+ result = extract_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
+ if (!result) break;
+
+ *value |= ((byte & 0x7f) << shift);
+
+ if ((byte & 0x80) == 0x00)
+ break;
+
+ shift += 7;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur à constituer. [OUT] *
+* pbuf = tampon de données à consulter. *
+* *
+* Description : Décode un nombre signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool unpack_leb128(leb128_t *value, packed_buffer_t *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ unsigned int shift; /* Décalage à appliquer */
+ uint8_t byte; /* Octet à transposer */
+
+ result = true;
+
+ *value = 0;
+
+ shift = 0;
+
+ do
+ {
+ /* Encodage sur trop d'octets ? */
+ if (shift > (7 * sizeof(leb128_t)))
+ {
+ result = false;
+ break;
+ }
+
+ result = extract_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
+ if (!result) break;
+
+ *value |= ((byte & 0x7f) << shift);
+
+ shift += 7;
+
+ }
+ while ((byte & 0x80) == 0x80);
+
+ /**
+ * Le bit de signe n'est pas le bit de poids fort ici :
+ * On travaille sur 7 bits, donc le masque est 0x40 !
+ */
+
+ if (shift < LEB128_BITS_COUNT && (byte & 0x40) == 0x40)
+ *value |= (~0llu << shift);
+
+ return result;
+
+}