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