Ajout du pendant ReadBuffer pour lire bit par bit
This commit is contained in:
parent
aa63afb9d8
commit
77ac3d3d4c
66
inc/buffer.h
66
inc/buffer.h
|
@ -4,46 +4,68 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* Informations sur un tampon de 8 caractères.
|
||||
* Utiliser `createBuffer` pour initialiser un tampon
|
||||
* Tampon permettant d'abstraire l'écriture dans un fichier bit par
|
||||
* bit au lieu d'octet par octet. Les bits sont vidés dans le fichier
|
||||
* dès qu'un octet est complet
|
||||
*/
|
||||
typedef struct Buffer Buffer;
|
||||
struct Buffer {
|
||||
// Compte le nombre d'octets écrits dans le fichier
|
||||
size_t flushed_bytes;
|
||||
|
||||
// Contient les données du tampon, c'est-à-dire
|
||||
typedef struct WriteBuffer WriteBuffer;
|
||||
struct WriteBuffer {
|
||||
// Contient les données du tampon d'écriture, c'est-à-dire
|
||||
// les données en attente de vidage dans le fichier
|
||||
char data;
|
||||
|
||||
// Nombre de bits utilisés dans le tampon. Si ce
|
||||
// nombre vaut 8, le tampon est plein
|
||||
size_t used_bits;
|
||||
// Nombre de bits utilisés dans `data`. Si ce nombre vaut 8,
|
||||
// le tampon d'écriture est plein
|
||||
size_t pending_bits;
|
||||
|
||||
// Fichier dans lequel le tampon est vidé à l'appel
|
||||
// Fichier dans lequel le tampon d'éciture est vidé à l'appel
|
||||
// de `flushBuffer` ou au débordement
|
||||
FILE* linked_file;
|
||||
FILE* dest_file;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise un tampon vide lié au fichier donné
|
||||
* Initialise un tampon d'écriture vide, avec le fichier donné comme
|
||||
* destination
|
||||
*/
|
||||
Buffer createBuffer(FILE*);
|
||||
WriteBuffer createWriteBuffer(FILE*);
|
||||
|
||||
/**
|
||||
* Pousse le bit donné dans le tampon passé.
|
||||
* Si le tampon déborde, le vide dans le fichier lié
|
||||
* Écrit le bit donné dans le tampon d'écriture
|
||||
*/
|
||||
void pushToBuffer(char bit, Buffer*);
|
||||
void putBuffer(char bit, WriteBuffer*);
|
||||
|
||||
/**
|
||||
* Récupère le nombre de fois qu'on a écrit un octet dans le fichier lié
|
||||
* Force le vidage du tampon dans son fichier et sa réinitialisation
|
||||
* (les bits non-remplis seront remplacés par des 0)
|
||||
*/
|
||||
size_t getFlushedBytes(Buffer*);
|
||||
void flushBuffer(WriteBuffer*);
|
||||
|
||||
/**
|
||||
* Vide le tampon dans son fichier et le réinitialise
|
||||
* Tampon permettant d'abstraire le lecture depuis un fichier bit par
|
||||
* bit au lieu d'octet par octet. Un octet est lu depuis le fichier
|
||||
* dès que tous les bits du précédent ont été lus
|
||||
*/
|
||||
void flushBuffer(Buffer*);
|
||||
typedef struct ReadBuffer ReadBuffer;
|
||||
struct ReadBuffer {
|
||||
// Contient les données du tampon de lecture, c'est-à-dire
|
||||
// le dernier octet lu depuis le fichier
|
||||
char data;
|
||||
|
||||
// Numéro du prochain bit de `data` qui sera lu par `getBuffer`
|
||||
size_t next_bit;
|
||||
|
||||
// Fichier depuis lequel le tampon de lecture est rempli
|
||||
FILE* source_file;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise un tampon de lecture avec le fichier donné comme source
|
||||
*/
|
||||
ReadBuffer createReadBuffer(FILE*);
|
||||
|
||||
/**
|
||||
* Lit le prochain bit depuis le tampon de lecture
|
||||
*/
|
||||
char getBuffer(ReadBuffer*);
|
||||
|
||||
#endif
|
||||
|
|
75
src/buffer.c
75
src/buffer.c
|
@ -3,36 +3,19 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
Buffer createBuffer(FILE* file) {
|
||||
Buffer buffer = {
|
||||
.flushed_bytes = 0,
|
||||
WriteBuffer createWriteBuffer(FILE* file) {
|
||||
WriteBuffer buffer = {
|
||||
.data = 0,
|
||||
.used_bits = 0,
|
||||
.linked_file = file
|
||||
.pending_bits = 0,
|
||||
.dest_file = file
|
||||
};
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
size_t getFlushedBytes(Buffer* buffer) {
|
||||
return buffer->flushed_bytes;
|
||||
}
|
||||
|
||||
void flushBuffer(Buffer* buffer) {
|
||||
// FIXME: gérer les erreurs d'écriture
|
||||
|
||||
// Alignement des données à gauche de l'octet
|
||||
buffer->data <<= 8 - buffer->used_bits;
|
||||
fputc(buffer->data, buffer->linked_file);
|
||||
|
||||
buffer->data = 0;
|
||||
buffer->used_bits = 0;
|
||||
buffer->flushed_bytes += 1;
|
||||
}
|
||||
|
||||
void pushToBuffer(char bit, Buffer* buffer) {
|
||||
void putBuffer(char bit, WriteBuffer* buffer) {
|
||||
// Si le tampon déborde, écriture dans le fichier
|
||||
if (buffer->used_bits == 8) {
|
||||
if (buffer->pending_bits == 8) {
|
||||
flushBuffer(buffer);
|
||||
}
|
||||
|
||||
|
@ -40,5 +23,49 @@ void pushToBuffer(char bit, Buffer* buffer) {
|
|||
// le tampon de sortie
|
||||
buffer->data <<= 1;
|
||||
buffer->data |= bit;
|
||||
buffer->used_bits += 1;
|
||||
buffer->pending_bits += 1;
|
||||
}
|
||||
|
||||
void flushBuffer(WriteBuffer* buffer) {
|
||||
// FIXME: gérer les erreurs d'écriture
|
||||
|
||||
// Alignement des données à gauche de l'octet
|
||||
buffer->data <<= 8 - buffer->pending_bits;
|
||||
fputc(buffer->data, buffer->dest_file);
|
||||
|
||||
buffer->data = 0;
|
||||
buffer->pending_bits = 0;
|
||||
}
|
||||
|
||||
ReadBuffer createReadBuffer(FILE* file) {
|
||||
ReadBuffer buffer = {
|
||||
.data = fgetc(file),
|
||||
.next_bit = 7,
|
||||
.source_file = file
|
||||
};
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char getBuffer(ReadBuffer* buffer) {
|
||||
if (buffer->data == EOF) {
|
||||
return EOF;
|
||||
}
|
||||
|
||||
// Lecture du n-ième bit dans le dernier octet lu
|
||||
char result = (
|
||||
buffer->data &
|
||||
(1 << buffer->next_bit)
|
||||
) != 0;
|
||||
|
||||
if (buffer->next_bit > 0) {
|
||||
// Il reste des bits à lire, décalage du compteur
|
||||
buffer->next_bit--;
|
||||
} else {
|
||||
// Besoin de lire le prochain octet depuis le fichier
|
||||
buffer->data = fgetc(buffer->source_file);
|
||||
buffer->next_bit = 7;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue