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>
|
#include <stdio.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Informations sur un tampon de 8 caractères.
|
* Tampon permettant d'abstraire l'écriture dans un fichier bit par
|
||||||
* Utiliser `createBuffer` pour initialiser un tampon
|
* 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;
|
typedef struct WriteBuffer WriteBuffer;
|
||||||
struct Buffer {
|
struct WriteBuffer {
|
||||||
// Compte le nombre d'octets écrits dans le fichier
|
// Contient les données du tampon d'écriture, c'est-à-dire
|
||||||
size_t flushed_bytes;
|
|
||||||
|
|
||||||
// Contient les données du tampon, c'est-à-dire
|
|
||||||
// les données en attente de vidage dans le fichier
|
// les données en attente de vidage dans le fichier
|
||||||
char data;
|
char data;
|
||||||
|
|
||||||
// Nombre de bits utilisés dans le tampon. Si ce
|
// Nombre de bits utilisés dans `data`. Si ce nombre vaut 8,
|
||||||
// nombre vaut 8, le tampon est plein
|
// le tampon d'écriture est plein
|
||||||
size_t used_bits;
|
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
|
// 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é.
|
* Écrit le bit donné dans le tampon d'écriture
|
||||||
* Si le tampon déborde, le vide dans le fichier lié
|
|
||||||
*/
|
*/
|
||||||
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
|
#endif
|
||||||
|
|
75
src/buffer.c
75
src/buffer.c
|
@ -3,36 +3,19 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
Buffer createBuffer(FILE* file) {
|
WriteBuffer createWriteBuffer(FILE* file) {
|
||||||
Buffer buffer = {
|
WriteBuffer buffer = {
|
||||||
.flushed_bytes = 0,
|
|
||||||
.data = 0,
|
.data = 0,
|
||||||
.used_bits = 0,
|
.pending_bits = 0,
|
||||||
.linked_file = file
|
.dest_file = file
|
||||||
};
|
};
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getFlushedBytes(Buffer* buffer) {
|
void putBuffer(char bit, WriteBuffer* 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) {
|
|
||||||
// Si le tampon déborde, écriture dans le fichier
|
// Si le tampon déborde, écriture dans le fichier
|
||||||
if (buffer->used_bits == 8) {
|
if (buffer->pending_bits == 8) {
|
||||||
flushBuffer(buffer);
|
flushBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,5 +23,49 @@ void pushToBuffer(char bit, Buffer* buffer) {
|
||||||
// le tampon de sortie
|
// le tampon de sortie
|
||||||
buffer->data <<= 1;
|
buffer->data <<= 1;
|
||||||
buffer->data |= bit;
|
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