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