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, EMUFS_REG_ID ID, void *ptr,
42 EMUFS_REG_SIZE tam_reg)
47 EMUFS_BLOCK_SIZE iterador = 0;
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);
53 printf("No hay memoria.\n");
57 if (emufs_tipo3_leer_bloque(emu, block, bloque)==-1) {
59 printf("no se pudo leer el bloque\n");
60 return -1; /*No se pudo leer el bloque*/
65 while ( iterador < emu->tam_bloque ) {
66 memcpy(&ID_aux, bloque+iterador, sizeof(EMUFS_REG_ID));
67 iterador += sizeof(EMUFS_REG_ID);
69 memcpy(ptr,bloque+iterador,tam_reg);
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)
85 strcpy(name_f,emu->nombre);
86 strcat(name_f,".dat");
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;
98 EMUFS_REG_ID emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, EMUFS_REG_SIZE tam)
102 EMUFS_BLOCK_ID num_bloque;
103 EMUFS_BLOCK_SIZE cant;
108 strcpy(name_f,emu->nombre);
109 strcat(name_f,".dat");
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 */
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 ) {
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");
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 */
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 ){
172 /*actualizo el archivo de bloques y registros*/
173 if ( emufs_idx_agregar(emu, num_bloque, ID_aux) != 0 ){
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)
187 if ( (id = emufs_did_get_last(emu)) == -1 )
188 id = emufs_idx_buscar_mayor_id(emu);
192 /*Graba un bloque en el archivo*/
193 int emufs_tipo3_grabar_bloque(EMUFS *emu, void *ptr, EMUFS_BLOCK_ID num)
198 strcpy(name_f,emu->nombre);
199 strcat(name_f,".dat");
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);
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)
214 EMUFS_BLOCK_SIZE num_bloque;
215 EMUFS_BLOCK_SIZE ptr_elim;
216 EMUFS_BLOCK_SIZE ptr_mov;
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");
228 /*apunto al registro que voy a eliminar*/
230 while ( ptr_elim < emu->tam_bloque ){
231 memcpy(&ID_aux, bloque+ptr_elim, sizeof(EMUFS_REG_ID));
234 ptr_elim += tam_reg + sizeof(EMUFS_REG_ID);
237 /*apunto al registro que voy a mover*/
238 ptr_mov = ptr_elim + tam_reg + sizeof(EMUFS_REG_ID);
240 while ( ptr_mov < emu->tam_bloque ){
241 memcpy(bloque+ptr_elim, bloque+ptr_mov, sizeof(EMUFS_REG_ID)+tam_reg);
243 ptr_mov += sizeof(EMUFS_REG_ID) + tam_reg;
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");
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;
256 /*actualizo archivo .did*/
257 if ( emufs_did_agregar(emu, ID) != 0 ) return -1;
259 /*actualizo archivo .idx*/
261 if ( emufs_idx_borrar(emu, ID) != 0 ) return -1;
264 /*busco el registro que tengo que eliminar*/
266 /* if ( (f_block_reg = fopen(name_f_block_reg,"r+")) == NULL ) return -1;
267 while ( !feof(f_block_reg) ){
268 if ( fread(®_b,sizeof(BLOCK_REG_T),1,f_block_reg) != 1 ) continue;
269 if ( reg_b.id_reg == ID )
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*/