]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/tipo3.c
ac3e7eea20538ac312e6591891538d53e669cfe3
[z.facultad/75.06/emufs.git] / emufs / tipo3.c
1 /* vim: set noexpandtab tabstop=4 shiftwidth=4:
2  *----------------------------------------------------------------------------
3  *                                  emufs
4  *----------------------------------------------------------------------------
5  * This file is part of emufs.
6  *
7  * emufs is free software; you can redistribute it and/or modify it under the
8  * terms of the GNU General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option) any later
10  * version.
11  *
12  * emufs is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with emufs; if not, write to the Free Software Foundation, Inc., 59 Temple
19  * Place, Suite 330, Boston, MA  02111-1307  USA
20  *----------------------------------------------------------------------------
21  * Creado:  mié mar 31 17:26:46 ART 2004
22  * Autores: Nicolás Dimov <sagardua@uolsinectis.com.ar>
23  *----------------------------------------------------------------------------
24  *
25  * $Id$
26  *
27  */
28
29 /** \file
30  *
31  * Archivo con bloques y registros de longitud parametrizada.
32  * 
33  * Implementación del archivo con bloques y registros de longitud
34  * parametrizada.
35  *
36  */
37
38 #include "tipo3.h"
39
40 /** Leo un registro del archivo, devuelve cero si no lo encuentra.**/
41 int emufs_tipo3_leer_registro(EMUFS *emu, int ID, void *ptr, unsigned long tam_reg)
42 {
43         FILE* f_block_reg;
44         char* bloque;
45         char name_f_block_reg[255];
46         int block, ID_aux;
47         int iterador = 0;
48         strcpy(name_f_block_reg,emu->nombre);
49         strcat(name_f_block_reg,".idx");
50
51
52         if ( (f_block_reg = fopen(name_f_block_reg,"a+")) == NULL )
53                 return -1; /*ERROR*/
54         
55
56         /*si existe, lo busco en el archivo de bloques*/
57         block = emufs_idx_buscar_registro(emu,ID); /*me devuelve el nro de bloque al que pertenece el registro*/
58         bloque = (char*)malloc(emu->tam_bloque);
59         if (bloque == NULL) {
60                 printf("No hay memoria.\n");
61                 return -1;
62         }
63         
64         if (emufs_tipo3_leer_bloque(emu, block, bloque)==-1) {
65                 free(bloque);
66                 printf("no se pudo leer el bloque\n");
67                 return -1; /*No se pudo leer el bloque*/
68         }
69
70         ID_aux = -1;
71         iterador = 0;
72         while ( iterador < emu->tam_bloque ) {
73                 memcpy(&ID_aux, bloque+iterador, sizeof(int));
74                 iterador += sizeof(int);
75                 if ( ID_aux == ID ){
76                         memcpy(ptr,bloque+iterador,tam_reg);
77                         break;
78                 }
79                 iterador += tam_reg;
80         }
81         
82         fclose(f_block_reg);
83         free(bloque);
84         return 0;
85 }
86
87 /*leo el bloque "ID" del archivo que viene en "emu->nombre", y lo almaceno en "ptr"*/
88 int emufs_tipo3_leer_bloque(EMUFS *emu, int ID, void* ptr)
89 {
90         FILE* file;
91         char name_f[255];
92         
93         strcpy(name_f,emu->nombre);
94         strcat(name_f,".dat");
95         
96         if ( (file = fopen(name_f,"r"))==NULL ) return -1; /*ERROR*/
97         fseek(file,sizeof(int)+sizeof(char)+sizeof(int),SEEK_SET);
98         /*FIXME: verificar que no se pase de fin de archivo*/
99         fseek(file,ID*emu->tam_bloque,SEEK_CUR);
100         if (fread(ptr,emu->tam_bloque,1,file)!=1) return -1;
101
102         fclose(file);
103         return 0;
104 }
105
106 int emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, unsigned long tam)
107 {
108         int ID_aux, fs, num_bloque, cant;
109         FILE *file;
110         char name_f[255];
111         char* bloque;
112         
113         strcpy(name_f,emu->nombre);
114         strcat(name_f,".dat");
115         
116         if ( (file = fopen(name_f,"a+"))==NULL ) return -1; /*ERROR*/
117         /* me devuelve el ID del bloque donde quepa un registro y el espacio libre en "fs"*/
118         num_bloque = emufs_fsc_buscar_lugar(emu, tam, &fs);
119         printf("Lugar = %d   bloque = %d\n", fs, num_bloque);
120         /*si no hay bloques con suficiente espacio creo un bloque nuevo */
121         if (num_bloque == -1) {
122                 /*crear un nuevo bloque en memoria */
123                 bloque = (char*)malloc(emu->tam_bloque);
124                 /* grabar el registro al principio del bloque */
125                 /*tengo que buscar un ID valido para el nuevo registro*/
126                 ID_aux = emufs_tipo3_get_id(emu);
127                 /*grabo el id en el bloque*/
128                 memcpy(bloque,&ID_aux,sizeof(int));
129                 /*grabo el registro en el bloque*/
130                 memcpy(bloque+sizeof(int),ptr,tam);
131                 /* me paro al final del archivo */
132                 fseek(file, 0, SEEK_END); 
133                 /* grabo el bloque en el final del archivo */
134                 fwrite(bloque,emu->tam_bloque,1,file);
135                 /*actualizo el archivo de espacios libres*/
136                 /*tengo que buscar la cantidad de bloques que existen*/
137                 /*me paro al principio salteando el encabezado del archivo*/
138                 fseek(file, 0, SEEK_END); /* Me paro al final */
139                 cant = (ftell(file)-(sizeof(int)*2+sizeof(char))) / emu->tam_bloque;
140                 cant--; /* Resto uno porque el numero de bloque debe empezar en 0 */
141                 fclose(file);
142                 num_bloque = cant;
143                 /* grabo el nuevo registro en el archivo de espacios libres */
144                 if ( emufs_fsc_agregar(emu, num_bloque, emu->tam_bloque - tam - sizeof(int)) != 0 ) {
145                         free(bloque);
146                         return -1;
147                 }
148         } else {
149                 /*cargo el bloque en "bloque"*/
150                 bloque = (char*)malloc(emu->tam_bloque);        
151                 if ( emufs_tipo3_leer_bloque(emu,num_bloque,bloque)== -1) {
152                         printf("Error: no se pudo leer bloque\n");
153                         return -1; 
154                 }
155                 /*El error puede haberse producido porque la funcion leer_bloque devolvio -1, el cual es un bloque invalido*/
156                 /*insertar el registro en el bloque*/
157                 /*tengo que buscar un ID valido para el nuevo registro*/
158                 ID_aux = emufs_tipo3_get_id(emu);
159                 /*grabo el id en el bloque*/
160                 memcpy(bloque+emu->tam_bloque-fs,&ID_aux,sizeof(int));
161                 /*grabo el registro en el bloque*/
162                 memcpy(bloque+emu->tam_bloque-fs+sizeof(int),ptr,tam);
163                 /*guardo el bloque en el archivo*/
164                 if ( emufs_tipo3_grabar_bloque(emu, bloque, num_bloque) != 0) {
165                         printf("error al grabar bloque\n");
166                         return -1; /* se produjo un error */    
167                 }
168                 /*actualizo el archivo de espacios libres*/
169                 if ( emufs_fsc_actualizar(emu, num_bloque, fs - tam - sizeof(int)) != 0 ){
170                         free(bloque);
171                         return -1;
172                 }
173         }
174                 
175         /*actualizo el archivo de bloques y registros*/
176         if ( emufs_idx_agregar(emu, num_bloque, ID_aux) != 0 ){
177                 free(bloque);
178                 return -1;
179         }
180         
181         free(bloque);
182         return ID_aux;
183 }
184
185 /*Busco en el archivo de Id`s un Id valido para un nuevo registro*/
186 int emufs_tipo3_get_id(EMUFS *emu)
187 {
188         int id;
189
190         if ( (id = emufs_did_get_last(emu)) == -1 )
191                 id = emufs_idx_buscar_mayor_id(emu);
192         return id;      
193 }
194
195 /*Graba un bloque en el archivo*/
196 int emufs_tipo3_grabar_bloque(EMUFS *emu, void *ptr, int num)
197 {
198         FILE* file;
199         char name_f[255];
200         
201         strcpy(name_f,emu->nombre);
202         strcat(name_f,".dat");
203         
204         if ( (file = fopen(name_f,"r+"))==NULL ) return -1; /*ERROR*/
205         fseek(file,sizeof(char)+sizeof(int)*2,SEEK_SET);
206         fseek(file,num*emu->tam_bloque,SEEK_CUR);       
207         fwrite(ptr, emu->tam_bloque, 1, file);
208         
209         fclose(file);
210         return 0;
211 }
212
213 /*borra un registro de un bloque y acomoda los registros que quedan*/
214 int emufs_tipo3_borrar_registro(EMUFS *emu, int ID, int tam_reg)
215 {
216         int num_bloque, ptr_elim, ptr_mov, ID_aux, cant, i, fs;
217         long size;
218         char *bloque;
219         FILE *f_block_reg;
220         BLOCK_REG_T reg_b;
221         BLOCK_REG_T buffer[10];
222         char name_f_block_reg[255];
223         
224         strcpy(name_f_block_reg,emu->nombre);
225         strcat(name_f_block_reg,".idx");
226
227         num_bloque = emufs_idx_buscar_registro(emu, ID);
228         bloque = (char*)malloc(emu->tam_bloque);
229         if ( emufs_tipo3_leer_bloque(emu,num_bloque, bloque) == -1 ){
230                 printf("No se encontro el bloque\n");
231                 return -1;
232         }
233
234         /*apunto al registro que voy a eliminar*/
235         ptr_elim = 0;
236         while ( ptr_elim < emu->tam_bloque ){
237                 memcpy(&ID_aux, bloque+ptr_elim, sizeof(int));
238                 if ( ID_aux == ID )
239                         break;
240                 ptr_elim += tam_reg + sizeof(int);
241         }
242         
243         /*apunto al registro que voy a mover*/
244         ptr_mov = ptr_elim + tam_reg + sizeof(int);
245         
246         while ( ptr_mov < emu->tam_bloque ){
247                 memcpy(bloque+ptr_elim, bloque+ptr_mov, sizeof(int)+tam_reg);
248                 ptr_elim = ptr_mov;
249                 ptr_mov += sizeof(int) + tam_reg;
250         }
251         
252         /*grabo el bloque en el archivo*/       
253         if ( emufs_tipo3_grabar_bloque(emu, bloque, num_bloque) == -1 ){
254                 printf("No se pudo grabar el bloque\n"); 
255                 return -1;
256         }
257         
258         /*actualizo archivo .fsc*/
259         fs = emufs_fsc_get_fs(emu, num_bloque);
260         if ( emufs_fsc_actualizar(emu, num_bloque, fs + tam_reg + sizeof(int)) != 0 ) return -1;
261         
262         /*actualizo archivo .did*/
263         if ( emufs_did_agregar(emu, ID) != 0 ) return -1;
264                 
265         /*actualizo archivo .idx*/
266         /*busco el registro que tengo que eliminar*/
267         if ( (f_block_reg = fopen(name_f_block_reg,"r+")) == NULL ) return -1;
268         while ( !feof(f_block_reg) ){
269                 if ( fread(&reg_b,sizeof(BLOCK_REG_T),1,f_block_reg) != 1 ) continue;
270                 if ( reg_b.id_reg == ID )
271                         break;
272         }
273         fseek(f_block_reg, -sizeof(BLOCK_REG_T), SEEK_CUR);
274         /* Estoy parado sobre el punto id/registro que debo borrar */
275         printf("registro borrado= %ld   en bloque = %d\n",reg_b.id_reg,reg_b.block);
276         /*justifico en archivo a la izquieda*/
277
278         /* GAZER : aca hago una prueba */
279         {
280                 long final, actual;
281                 actual = ftell(f_block_reg); /* Guardo la posicion actual */
282                 fseek(f_block_reg, 0, SEEK_END); /* me voy al final */
283                 final = ftell(f_block_reg); /* veo cuando ocupa el archivo */
284                 fseek(f_block_reg, actual, SEEK_SET); /* vuelvo al lugar desde donde quiero justificar */
285
286                 cant = (final-actual)/sizeof(BLOCK_REG_T);
287                 for(i=0; i<cant; i++) {
288                         /* Calculo donde empieza el proximo elemento a mover */
289                         final = actual+sizeof(BLOCK_REG_T);
290                         /* Me paro en ese lugar */
291                         fseek(f_block_reg, final, SEEK_SET);
292                         /* y lo leo */
293                         fread(buffer, sizeof(BLOCK_REG_T), 1, f_block_reg);
294
295                         /* Ahora me paro en la nueva posicion de este item */
296                         fseek(f_block_reg, actual, SEEK_SET);
297                         /* y lo guardo */
298                         fwrite(buffer, sizeof(BLOCK_REG_T), 1, f_block_reg);
299
300                         /* Ahora el proximo item va en la posicion siguiente */
301                         actual += sizeof(BLOCK_REG_T);
302                 }
303
304         }
305         /*trunco el ultimo registro del archiv*/
306         fseek(f_block_reg,0,SEEK_END);
307   size = ftell(f_block_reg);
308   fclose(f_block_reg);
309         truncate(name_f_block_reg,size - sizeof(BLOCK_REG_T));
310
311         free(bloque);
312
313 return 0;
314 }