1
/************************************************/
2
/* Module de gestion de buffers dynamiques v1.0 */
3
/************************************************/
8
#include "gestion_memoire.h"
9
#include "listes_chainees.h"
10
#include "buffer_dynamiques.h"
12
/* Cette structure code un buffer dynamique.
13
Il faut laisser cette structure et Premier_buffer_dynamique dans
14
gestion_memoire.c : c'est une structure privee. */
15
typedef struct gbd_Buffer_dynamique
18
long nbre_elements_initial;
19
long nbre_elements_total;
20
long nbre_elements_occupes;
21
void *pointeur_buffer;
26
} gbd_buffer_dynamique;
28
static void gbd_desallouer_buffer();
29
static int gbd_chercher_buffer_dynamique();
30
static void *gbd_modifier_buffer_dynamique();
31
static long puissance_2_sup();
33
/* Pointeur sur le premier buffer dynamique de la liste chainee. */
34
/* Ce pointeur est egal a NULL au debut, car la liste est vide. */
36
static ldc_liste_chainee liste_buffer_dynamiques=NULL;
38
/* Cette procedure ajoute un buffer dynamique dans la liste chainee. */
39
/* Cette procedure peut etre appelee par la macro creer_buffer_dynamique */
40
/* (cf gestion_memoire.h) */
41
void *gbd_creer_buffer_dynamique(taille,nbre_initial,allouer,reallouer,liberer,desallouer)
49
gbd_buffer_dynamique *nouvelle_structure;
50
long nbre_initial_p2 = puissance_2_sup(nbre_initial);
52
if (liste_buffer_dynamiques == NULL)
53
liste_buffer_dynamiques=ldc_creer(gbd_chercher_buffer_dynamique,gbd_desallouer_buffer,liberer,allouer);
55
nouvelle_structure = (*allouer)(sizeof(gbd_buffer_dynamique));
56
nouvelle_structure -> pointeur_buffer = allouer(taille*nbre_initial_p2);
57
nouvelle_structure -> taille_elements = taille;
58
nouvelle_structure -> nbre_elements_initial = nbre_initial_p2;
59
nouvelle_structure -> nbre_elements_total = nbre_initial_p2;
60
nouvelle_structure -> nbre_elements_occupes = 0;
61
nouvelle_structure -> liberer = liberer;
62
nouvelle_structure -> allouer = allouer;
63
nouvelle_structure -> reallouer = reallouer;
64
nouvelle_structure -> desallouer = desallouer;
66
ldc_ajouter_objet(liste_buffer_dynamiques,nouvelle_structure);
68
return nouvelle_structure -> pointeur_buffer;
71
/* Cette procedure detruit un buffer dynamique dans la liste chainee. */
72
int gbd_detruire_buffer_dynamique(pointeur_buffer)
73
void *pointeur_buffer;
75
return ldc_supprimer_objet(liste_buffer_dynamiques,pointeur_buffer);
78
static void gbd_desallouer_buffer(pointeur_struct_buffer_nc)
79
ldc_objet_liste pointeur_struct_buffer_nc;
83
gbd_buffer_dynamique *pointeur_struct_buffer = (gbd_buffer_dynamique *) pointeur_struct_buffer_nc;
85
if (pointeur_struct_buffer -> desallouer != NULL)
87
buffer = (char *)(pointeur_struct_buffer -> pointeur_buffer);
88
for(compteur = 0; compteur < pointeur_struct_buffer -> nbre_elements_occupes; compteur++)
89
(pointeur_struct_buffer -> desallouer)(buffer + (pointeur_struct_buffer -> nbre_elements_occupes) * (pointeur_struct_buffer -> taille_elements));
91
(pointeur_struct_buffer -> liberer)(pointeur_struct_buffer -> pointeur_buffer);
92
(pointeur_struct_buffer -> liberer)(pointeur_struct_buffer);
95
/* Cette procedure permet d'augmenter la taille virtuelle d'un buffer dynamique. */
96
/* Si la taille virtuelle depasse la taille reelle du buffer, une reallocation */
97
/* est effectuee. Le nombre d'elements apres la reallocation sera toujours egal */
98
/* au nombre d'elements initial multiplie par une puissance de deux. */
99
void *gbd_augmenter_buffer_dynamique(pointeur_buffer,nombre_elements)
100
void *pointeur_buffer;
101
long nombre_elements;
103
return gbd_modifier_buffer_dynamique(pointeur_buffer,nombre_elements,1);
106
/* La taille virtuelle d'un buffer dynamique est diminuee. */
107
/* Aucune reallocation n'est effectuee. */
108
/** supprimer la duplication de code **/
109
void *gbd_diminuer_buffer_dynamique(pointeur_buffer,nombre_elements)
110
void *pointeur_buffer;
111
long nombre_elements;
113
return gbd_modifier_buffer_dynamique(pointeur_buffer,nombre_elements,-1);
116
static void *gbd_modifier_buffer_dynamique(pointeur_buffer,nombre_elements,operation)
117
void *pointeur_buffer;
118
long nombre_elements;
121
long nombre_elements_a_reallouer,nombre_elements_a_reallouer_p2;
122
gbd_buffer_dynamique *buffer_a_modifier;
123
void *nouvelle_adresse;
125
if ((buffer_a_modifier = ldc_rechercher_objet(liste_buffer_dynamiques,pointeur_buffer)) != NULL)
127
nombre_elements_a_reallouer = (buffer_a_modifier -> nbre_elements_occupes) + operation * nombre_elements;
128
if ((operation == 1 && (nombre_elements_a_reallouer <= (buffer_a_modifier -> nbre_elements_total))) ||
129
((operation == -1) && (nombre_elements_a_reallouer >= ((buffer_a_modifier -> nbre_elements_total) >> 1)) &&
130
(nombre_elements_a_reallouer > (buffer_a_modifier -> nbre_elements_initial))))
133
buffer_a_modifier -> nbre_elements_occupes += nombre_elements * operation;
134
return buffer_a_modifier -> pointeur_buffer;
138
nombre_elements_a_reallouer_p2 = puissance_2_sup(nombre_elements_a_reallouer);
140
nouvelle_adresse = (buffer_a_modifier -> reallouer)(buffer_a_modifier -> pointeur_buffer,nombre_elements_a_reallouer_p2 * buffer_a_modifier -> taille_elements);
141
buffer_a_modifier -> nbre_elements_total = nombre_elements_a_reallouer_p2;
142
buffer_a_modifier -> pointeur_buffer = nouvelle_adresse;
143
buffer_a_modifier -> nbre_elements_occupes = nombre_elements_a_reallouer;
145
return nouvelle_adresse;
151
/* Demande de la taille virtuelle d'un tableau dynamique */
152
long gbd_taille_buffer_dynamique(pointeur_buffer)
153
void *pointeur_buffer;
155
gbd_buffer_dynamique *buffer_recherche;
157
if ((buffer_recherche = ldc_rechercher_objet(liste_buffer_dynamiques,pointeur_buffer)) != NULL)
158
return buffer_recherche -> nbre_elements_total;
160
/** Erreur a gerer peut etre **/
164
/* Recherche de la structure d'un buffer dynamique, connaissant le pointeur */
165
/* sur le buffer dynamique. Si la recherche echoue, la fonction retourne NULL. */
166
static int gbd_chercher_buffer_dynamique(pointeur_struct_buffer_nc,pointeur_buffer_nc)
167
ldc_objet_liste pointeur_struct_buffer_nc;
168
ldc_element_correspondance pointeur_buffer_nc;
170
gbd_buffer_dynamique *pointeur_struct_buffer = (gbd_buffer_dynamique *) pointeur_struct_buffer_nc;
171
void *pointeur_buffer = (void *) pointeur_buffer_nc;
173
return (pointeur_struct_buffer -> pointeur_buffer == pointeur_buffer);
176
static long puissance_2_sup(nombre)
181
while(puissance < nombre)
187
/* Liberation mixte : libere un buffer dynamique ou un buffer ordinaire */
188
void gbd_liberer_mixte(buffer)
191
if (!gbd_detruire_buffer_dynamique(buffer))