]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/tipo3.c
- Changed routine: emufs_idx_agregar, cambiando el orden de los parametros 2 y 3...
[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, EMUFS_REG_ID ID, void *ptr)
42 {
43         char* bloque;
44         EMUFS_BLOCK_ID block;
45         EMUFS_REG_ID ID_aux;
46         EMUFS_BLOCK_SIZE iterador = 0;
47         
48         /*si existe, lo busco en el archivo de bloques*/
49         block = emufs_idx_buscar_registro(emu,ID); /*me devuelve el nro de bloque al que pertenece el registro*/
50         bloque = (char*)malloc(emu->tam_bloque);
51         if (bloque == NULL) {
52                 printf("No hay memoria.\n");
53                 return -1;
54         }
55         
56         if (emufs_tipo3_leer_bloque(emu, block, bloque)==-1) {
57                 free(bloque);
58                 printf("no se pudo leer el bloque\n");
59                 return -1; /*No se pudo leer el bloque*/
60         }
61
62         ID_aux = -1;
63         iterador = 0;
64         while ( iterador < emu->tam_bloque ) {
65                 memcpy(&ID_aux, bloque+iterador, sizeof(EMUFS_REG_ID));
66                 iterador += sizeof(EMUFS_REG_ID);
67                 if ( ID_aux == ID ){
68                         memcpy(ptr,bloque+iterador,emu->tam_reg);
69                         break;
70                 }
71                 iterador += emu->tam_reg;
72         }
73         
74         free(bloque);
75         return 0;
76 }
77
78 /*leo el bloque "ID" del archivo que viene en "emu->nombre", y lo almaceno en "ptr"*/
79 int emufs_tipo3_leer_bloque(EMUFS *emu, EMUFS_REG_ID ID, void* ptr)
80 {
81         FILE* file;
82         char name_f[255];
83         
84         strcpy(name_f,emu->nombre);
85         strcat(name_f,".dat");
86         
87         if ( (file = fopen(name_f,"r"))==NULL ) return -1; /*ERROR*/
88         fseek(file,sizeof(EMUFS_TYPE)+sizeof(EMUFS_BLOCK_SIZE)+sizeof(EMUFS_REG_SIZE),SEEK_SET);
89         /*FIXME: verificar que no se pase de fin de archivo*/
90         fseek(file,ID*emu->tam_bloque,SEEK_CUR);
91         if (fread(ptr,emu->tam_bloque,1,file)!=1) return -1;
92
93         fclose(file);
94         return 0;
95 }
96
97 EMUFS_REG_ID emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr)
98 {
99         EMUFS_REG_ID ID_aux;
100         EMUFS_FREE fs;
101         EMUFS_BLOCK_ID num_bloque;
102         EMUFS_BLOCK_SIZE cant;
103         FILE *file;
104         char name_f[255];
105         char* bloque;
106         
107         strcpy(name_f,emu->nombre);
108         strcat(name_f,".dat");
109         
110         /* me devuelve el ID del bloque donde quepa un registro y el espacio libre en "fs"*/
111         num_bloque = emufs_fsc_buscar_lugar(emu, emu->tam_reg, &fs);
112         /*si no hay bloques con suficiente espacio creo un bloque nuevo */
113         if (num_bloque == -1) {
114                 if ( (file = fopen(name_f,"a+"))==NULL ) return -1; /*ERROR*/
115                 /*crear un nuevo bloque en memoria */
116                 bloque = (char*)malloc(emu->tam_bloque);
117                 /* grabar el registro al principio del bloque */
118                 /*tengo que buscar un ID valido para el nuevo registro*/
119                 ID_aux = emufs_tipo3_get_id(emu);
120                 /*grabo el id en el bloque*/
121                 memcpy(bloque,&ID_aux,sizeof(EMUFS_REG_ID));
122                 /*grabo el registro en el bloque*/
123                 memcpy(bloque+sizeof(EMUFS_REG_ID),ptr,emu->tam_reg);
124                 /* me paro al final del archivo */
125                 fseek(file, 0, SEEK_END); 
126                 /* grabo el bloque en el final del archivo */
127                 fwrite(bloque,emu->tam_bloque,1,file);
128                 /*actualizo el archivo de espacios libres*/
129                 /*tengo que buscar la cantidad de bloques que existen*/
130                 /*me paro al principio salteando el encabezado del archivo*/
131                 fseek(file, 0, SEEK_END); /* Me paro al final */
132                 /* FIXME FIXME FIXME FALTA TRADUCIR A EMUFS_XXXX */
133                 cant = (ftell(file)-(sizeof(int)*2+sizeof(char))) / emu->tam_bloque;
134                 cant--; /* Resto uno porque el numero de bloque debe empezar en 0 */
135                 fclose(file);
136                 num_bloque = cant;
137                 /* grabo el nuevo registro en el archivo de espacios libres */
138                 /* FIXME FIXME FIXME FALTA TRADUCIR A EMUFS_XXXX */
139                 if ( emufs_fsc_agregar(emu, num_bloque, emu->tam_bloque - emu->tam_reg - sizeof(int)) != 0 ) {
140                         free(bloque);
141                         return -1;
142                 }
143         } else {
144                 /*cargo el bloque en "bloque"*/
145                 bloque = (char*)malloc(emu->tam_bloque);
146                 if ( emufs_tipo3_leer_bloque(emu,num_bloque,bloque)== -1) {
147                         printf("Error: no se pudo leer bloque\n");
148                         return -1; 
149                 }
150                 /*El error puede haberse producido porque la funcion leer_bloque devolvio -1, el cual es un bloque invalido*/
151                 /*insertar el registro en el bloque*/
152                 /*tengo que buscar un ID valido para el nuevo registro*/
153                 ID_aux = emufs_tipo3_get_id(emu);
154                 /*grabo el id en el bloque*/
155                 memcpy(bloque+emu->tam_bloque-fs,&ID_aux,sizeof(EMUFS_REG_ID));
156                 /*grabo el registro en el bloque*/
157                 memcpy(bloque+emu->tam_bloque-fs+sizeof(EMUFS_REG_ID),ptr,emu->tam_reg);
158                 /*guardo el bloque en el archivo*/
159                 if ( emufs_tipo3_grabar_bloque(emu, bloque, num_bloque) != 0) {
160                         printf("error al grabar bloque\n");
161                         return -1; /* se produjo un error */    
162                 }
163                 /*actualizo el archivo de espacios libres*/
164                 /* FIXME FIXME FIXME FALTA TRADUCIR A EMUFS_XXXX */
165                 if ( emufs_fsc_actualizar(emu, num_bloque, fs - emu->tam_reg - sizeof(int)) != 0 ){
166                         free(bloque);
167                         return -1;
168                 }
169         }
170                 
171         /*actualizo el archivo de bloques y registros*/
172         if ( emufs_idx_agregar(emu, num_bloque, ID_aux) != 0 ){
173                 free(bloque);
174                 return -1;
175         }
176         
177         free(bloque);
178         return ID_aux;
179 }
180
181 /*Busco en el archivo de Id`s un Id valido para un nuevo registro*/
182 EMUFS_REG_ID emufs_tipo3_get_id(EMUFS *emu)
183 {
184         EMUFS_REG_ID id;
185
186         if ( (id = emufs_did_get_last(emu)) == -1 )
187                 id = emufs_idx_buscar_mayor_id(emu);
188         return id;      
189 }
190
191 /*Graba un bloque en el archivo*/
192 int emufs_tipo3_grabar_bloque(EMUFS *emu, void *ptr, EMUFS_BLOCK_ID num)
193 {
194         FILE* file;
195         char name_f[255];
196         
197         strcpy(name_f,emu->nombre);
198         strcat(name_f,".dat");
199         
200         if ( (file = fopen(name_f,"r+"))==NULL ) return -1; /*ERROR*/
201         /* Salto el header del archivo */
202         fseek(file, sizeof(char)+sizeof(int)*2, SEEK_SET);
203         fseek(file, num*emu->tam_bloque, SEEK_CUR);     
204         fwrite(ptr, emu->tam_bloque, 1, file);
205         
206         fclose(file);
207         return 0;
208 }
209
210 /*borra un registro de un bloque y acomoda los registros que quedan*/
211 int emufs_tipo3_borrar_registro(EMUFS *emu, EMUFS_REG_ID ID)
212 {
213         EMUFS_BLOCK_SIZE num_bloque;
214         EMUFS_BLOCK_SIZE ptr_elim;
215         EMUFS_BLOCK_SIZE ptr_mov;
216         EMUFS_REG_ID ID_aux;
217         EMUFS_FREE fs;
218         char *bloque;
219
220         num_bloque = emufs_idx_buscar_registro(emu, ID);
221         bloque = (char*)malloc(emu->tam_bloque);
222         if ( emufs_tipo3_leer_bloque(emu,num_bloque, bloque) == -1 ) {
223                 printf("No se encontro el bloque\n");
224                 free(bloque);
225                 return -1;
226         }
227
228         /*apunto al registro que voy a eliminar*/
229         ptr_elim = 0;
230         while ( ptr_elim < emu->tam_bloque ){
231                 memcpy(&ID_aux, bloque+ptr_elim, sizeof(EMUFS_REG_ID));
232                 if ( ID_aux == ID )
233                         break;
234                 ptr_elim += emu->tam_reg + sizeof(EMUFS_REG_ID);
235         }
236         
237         /*apunto al registro que voy a mover*/
238         ptr_mov = ptr_elim + emu->tam_reg + sizeof(EMUFS_REG_ID);
239         
240         while ( ptr_mov < emu->tam_bloque ){
241                 memcpy(bloque+ptr_elim, bloque+ptr_mov, sizeof(EMUFS_REG_ID)+emu->tam_reg);
242                 ptr_elim = ptr_mov;
243                 ptr_mov += sizeof(EMUFS_REG_ID) + emu->tam_reg;
244         }
245         
246         /*grabo el bloque en el archivo*/       
247         if ( emufs_tipo3_grabar_bloque(emu, bloque, num_bloque) == -1 ){
248                 free(bloque);
249                 printf("No se pudo grabar el bloque\n"); 
250                 return -1;
251         }
252         
253         /*actualizo archivo .fsc*/
254         fs = emufs_fsc_get_fs(emu, num_bloque);
255         if ( emufs_fsc_actualizar(emu, num_bloque, fs + emu->tam_reg + sizeof(EMUFS_REG_ID)) != 0 ) return -1;
256         
257         /*actualizo archivo .did*/
258         if ( emufs_did_agregar(emu, ID) != 0 ) return -1;
259                 
260         /*actualizo archivo .idx*/
261         if ( emufs_idx_borrar(emu, ID) != 0 ) return -1; 
262         
263         free(bloque);
264         return 0;
265 }