1 /* vim: set noexpandtab tabstop=4 shiftwidth=4:
2 *----------------------------------------------------------------------------
4 *----------------------------------------------------------------------------
5 * This file is part of emufs.
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
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
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 *----------------------------------------------------------------------------
31 * Archivo con bloques y registros de longitud parametrizada.
33 * Implementación del archivo con bloques y registros de longitud
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)
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);
51 printf("No hay memoria.\n");
55 if (emufs_tipo3_leer_bloque(emu, block, bloque)==-1) {
57 printf("no se pudo leer el bloque\n");
58 return -1; /*No se pudo leer el bloque*/
63 while ( iterador < emu->tam_bloque ) {
64 memcpy(&ID_aux, bloque+iterador, sizeof(int));
65 iterador += sizeof(int);
67 memcpy(ptr,bloque+iterador,tam_reg);
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)
83 strcpy(name_f,emu->nombre);
84 strcat(name_f,".dat");
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;
96 int emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, unsigned long tam)
98 int ID_aux, fs, num_bloque, cant;
103 strcpy(name_f,emu->nombre);
104 strcat(name_f,".dat");
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 */
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 ) {
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");
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 */
157 /*actualizo el archivo de espacios libres*/
158 if ( emufs_fsc_actualizar(emu, num_bloque, fs - tam - sizeof(int)) != 0 ){
164 /*actualizo el archivo de bloques y registros*/
165 if ( emufs_idx_agregar(emu, num_bloque, ID_aux) != 0 ){
174 /*Busco en el archivo de Id`s un Id valido para un nuevo registro*/
175 int emufs_tipo3_get_id(EMUFS *emu)
179 if ( (id = emufs_did_get_last(emu)) == -1 )
180 id = emufs_idx_buscar_mayor_id(emu);
184 /*Graba un bloque en el archivo*/
185 int emufs_tipo3_grabar_bloque(EMUFS *emu, void *ptr, int num)
190 strcpy(name_f,emu->nombre);
191 strcat(name_f,".dat");
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);
203 /*borra un registro de un bloque y acomoda los registros que quedan*/
204 int emufs_tipo3_borrar_registro(EMUFS *emu, int ID, unsigned long tam_reg)
206 int num_bloque, ptr_elim, ptr_mov, ID_aux, fs;
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");
216 /*apunto al registro que voy a eliminar*/
218 while ( ptr_elim < emu->tam_bloque ){
219 memcpy(&ID_aux, bloque+ptr_elim, sizeof(int));
222 ptr_elim += tam_reg + sizeof(int);
225 /*apunto al registro que voy a mover*/
226 ptr_mov = ptr_elim + tam_reg + sizeof(int);
228 while ( ptr_mov < emu->tam_bloque ){
229 memcpy(bloque+ptr_elim, bloque+ptr_mov, sizeof(int)+tam_reg);
231 ptr_mov += sizeof(int) + tam_reg;
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");
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;
244 /*actualizo archivo .did*/
245 if ( emufs_did_agregar(emu, ID) != 0 ) return -1;
247 /*actualizo archivo .idx*/
248 /*busco el registro que tengo que eliminar*/
250 /* if ( (f_block_reg = fopen(name_f_block_reg,"r+")) == NULL ) return -1;
251 while ( !feof(f_block_reg) ){
252 if ( fread(®_b,sizeof(BLOCK_REG_T),1,f_block_reg) != 1 ) continue;
253 if ( reg_b.id_reg == ID )
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*/