diff options
Diffstat (limited to 'src/common/bits.c')
-rw-r--r-- | src/common/bits.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/common/bits.c b/src/common/bits.c index f730c66..26f570f 100644 --- a/src/common/bits.c +++ b/src/common/bits.c @@ -31,6 +31,7 @@ #include "asm.h" +#include "leb128.h" @@ -1291,3 +1292,133 @@ void output_bit_field(const bitfield_t *field) } #endif + + +/****************************************************************************** +* * +* Paramètres : fd = flux ouvert en lecture. * +* length = éventuelle indication de la taille du champ ? * +* def_state = éventuelle indication de l'état par défaut ? * +* endian = ordre des bits dans la source. * +* * +* Description : Restaure un champ de bits depuis un flux ouvert. * +* * +* Retour : Adresse du champs de bits mis en place, NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bitfield_t *load_bit_field(int fd, const size_t *length, const bool *def_state, SourceEndian endian) +{ + bitfield_t *result; /* Structure à retourner */ + size_t final_length; /* Nombre de bits représentés */ + uleb128_t leb128_value; /* Valeur LEB128 chargée */ + bool status; /* Bilan d'une lecture */ + bool final_default_state; /* Etat d'initialisation */ + uint8_t u8_value; /* Valeur sur 8 bits chargée */ + size_t i; /* Boucle de parcours */ + + result = NULL; + + if (length != NULL) + final_length = *length; + else + { + status = load_uleb128(&leb128_value, fd); + if (!status) goto exit; + + final_length = leb128_value; + + } + + if (def_state != NULL) + final_default_state = *def_state; + + else + { + status = load_u8(fd, &u8_value); + if (!status) goto exit; + + final_default_state = !!u8_value; + + } + + result = _create_bit_field(final_length); + + result->default_state = final_default_state; + + for (i = 0; i < result->used_words; i++) + { + status = load_uleb128(&leb128_value, fd); + + if (status) + result->bits[i] = leb128_value; + + else + { + delete_bit_field(result); + result = NULL; + break; + } + + } + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à consulter. * +* fd = flux ouvert en écriture. * +* skip_len = saute la sauvegarde de la taille du champ ? * +* skip_def = saute la sauvegarde de l'état par défaut ? * +* endian = ordre des bits dans la source. * +* * +* Description : Sauvegarde un champ de bits dans un flux ouvert. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool store_bit_field(const bitfield_t *field, int fd, bool skip_len, bool skip_def, SourceEndian endian) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + + if (skip_len) + result = true; + else + { + result = store_uleb128((const uleb128_t []) { field->length }, fd); + if (!result) goto exit; + } + + if (skip_def) + result = true; + else + { + result = store_u8(fd, field->default_state); + if (!result) goto exit; + } + + for (i = 0; i < field->used_words; i++) + { + result = store_uleb128((const uleb128_t []) { field->bits[i] }, fd); + + if (!result) + break; + + } + + exit: + + return result; + +} |