]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/tipo2.c
- emufs.c: Utilizacion de emufs_tipo2_inicializar, idem a lo que hizo luca con su...
[z.facultad/75.06/emufs.git] / emufs / tipo2.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:  Fri Apr 10 17:10:00 ART 2004
22  * Autores: Alan Kennedy <kennedya@3dgames.com.ar>
23  *----------------------------------------------------------------------------
24  *
25  * $Id: tipo3.c 85 2004-04-08 23:39:28Z sagar $
26  *
27  */
28
29 /***************************************************************/
30 /* Implementación del Tipo Archivo 2: Registros Variables, Sin */
31 /* Bloques at all.                                             */
32 /***************************************************************/
33
34 #include "tipo2.h"
35 #include "idx.h"
36 #include "fsc.h"
37 #include "did.h"
38
39 /* Asigna los punteros a las funciones apropiadas para el Tipo2 */
40 int emufs_tipo2_inicializar(EMUFS* efs)
41 {
42         efs->grabar_registro = emufs_tipo2_grabar_registro;           
43     efs->borrar_registro = emufs_tipo2_borrar_registro;
44         efs->leer_registro = emufs_tipo2_leer_registro;
45 }
46
47 /**********************************************************************/
48 /* EMUFS_REG_ID emufs_tipo2_grabar_registro(EMUFS *efs, void *ptr,    */
49 /*                                 EMUFS_REG_SIZE n_RegSize)          */
50 /* Objetivo: Grabar un registro en un archivo del Tipo 2.             */
51 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
52 /*             void *ptr // Puntero al buffer (registro) a guardar    */
53 /*             EMUFS_REG_SIZE n_RegSize // Size del reg en cuestion   */
54 /**********************************************************************/
55 void *emufs_tipo2_leer_registro(EMUFS* efs, EMUFS_REG_ID reg_id,
56                         EMUFS_REG_SIZE* reg_size, int *err)
57 {
58         FILE* f_data;
59         char *registro; /* registro a leer */
60         char  name_f[255];      
61         EMUFS_OFFSET reg_offset; /* offset donde se encuentra el registro */
62         
63         strcpy(name_f,efs->nombre);
64         strcat(name_f,".dat");
65
66         /* Obtenemos la posicion del registro en el .dat */
67         reg_offset = emufs_idx_buscar_registro(efs, reg_id);
68         if (reg_offset == EMUFS_NOT_FOUND) {
69                 /* TODO Manejo de errores */
70                 PERR("Registro no encontrado");
71                 *err = EMUFS_NOT_FOUND;
72                 return NULL;
73         }
74         
75         /* Levantamos el registro */
76         if ((f_data = fopen(name_f, "rb")) == NULL) {
77                 PERR("No se puede abrir archivo");
78                 *err = 4; /* EMUFS_ERROR_CANT_OPEN_FILE */
79                 return NULL; /* FIXME ERROR */
80         }
81         fseek(f_data,reg_offset+sizeof(EMUFS_REG_ID),0);
82         fread(reg_size,sizeof(EMUFS_REG_SIZE),1,f_data);
83         registro = (char*)malloc(*reg_size);
84         fread(registro,*reg_size,1,f_data);
85         fclose(f_data);
86         
87         return registro;
88 }
89
90 /**********************************************************************/
91 /* EMUFS_REG_ID emufs_tipo2_grabar_registro(EMUFS *efs, void *ptr,    */
92 /*                                 EMUFS_REG_SIZE n_RegSize)          */
93 /* Objetivo: Grabar un registro en un archivo del Tipo 2.             */
94 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
95 /*             void *ptr // Puntero al buffer (registro) a guardar    */
96 /*             EMUFS_REG_SIZE n_RegSize // Size del reg en cuestion   */
97 /**********************************************************************/
98 EMUFS_REG_ID emufs_tipo2_grabar_registro(EMUFS *efs, void *ptr, EMUFS_REG_SIZE n_RegSize, int* err)
99 {
100         EMUFS_REG_ID n_IdReg;
101         EMUFS_FREE n_FreeSpace;
102         EMUFS_OFFSET n_WrtOffset,n_RegOffset;
103         unsigned long int n_FisicSize;
104         FILE *f_data;
105         char name_f[255];
106         
107         /* Armamos el filename del archivo de datos */
108         strcpy(name_f,efs->nombre);
109         strcat(name_f,".dat");
110         
111         if ( (f_data = fopen(name_f,"r+"))==NULL ) return -1; /*ERROR*/
112         
113         /* Obtengo un offset en donde iniciar la escritura de mi registro */
114         /* de manera segura (habra espacio suficiente) */
115         n_FisicSize = sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE)+n_RegSize;
116         n_WrtOffset = emufs_fsc_buscar_lugar(efs,n_FisicSize,&n_FreeSpace);
117         printf("tipo2.c >> Recording Reg > Searching FSC: Offset = %lu FSpace: %lu\n", n_WrtOffset, n_FreeSpace);
118         
119         /* Si no encontre un gap, entonces escribo el registro al final */
120         if (n_WrtOffset == -1) {                       
121                 
122                 /* Obtengo un ID libre para el registro y luego grabo a disco */
123         n_IdReg = emufs_idx_get_new_id(efs, err);
124                 fseek(f_data, 0, SEEK_END);
125                 n_RegOffset = ftell(f_data);
126
127                 /* Escribo [RegId]|[RegSize]|[RegData] */
128                 fwrite(&n_IdReg,sizeof(EMUFS_REG_ID),1,f_data);
129                 fwrite(&n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);
130                 fwrite(ptr,n_RegSize,1,f_data);
131                                 
132                 /* Bye */
133                 printf("Tipo2.c >> RegNr: %lu with FisicSize: %lu inserted at Offset: %lu\n",n_IdReg,n_FisicSize,n_RegOffset);
134                 fclose(f_data);
135                 
136         } else {
137                 
138                 /* Obtengo un ID libre para el registro y luego grabo en disco */
139         n_IdReg = emufs_idx_get_new_id(efs, err);
140                 n_RegOffset = n_WrtOffset;
141                 fseek(f_data,n_RegOffset,0);
142                 
143         /* Escribo [RegId]|[RegSize]|[RegData] */
144                 fwrite(&n_IdReg,sizeof(EMUFS_REG_ID),1,f_data);
145                 fwrite(&n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);
146                 fwrite(ptr,n_RegSize,1,f_data);
147                                 
148                 /* Bye */
149                 printf("Tipo2.c >> RegNr: %lu with FisicSize: %lu inserted at Offset: %lu\n",n_IdReg,n_FisicSize,n_RegOffset);
150                 fclose(f_data);
151                 
152                 /* Actualizo el espacio libre en el GAP donde puse el registro */
153                 if ((n_FreeSpace-n_FisicSize) == 0) emufs_fsc_remove_gap(efs,n_RegOffset);
154                 else emufs_fsc_actualizar_gap(efs,n_RegOffset,n_FreeSpace-n_FisicSize);         
155         }
156                 
157         /* Finalmente, actualizamos el indice de registros (offsets) */
158         emufs_idx_agregar(efs,n_IdReg,n_RegOffset);
159                 
160         return n_IdReg;
161 }
162
163 /**********************************************************************/
164 /* int emufs_tipo2_borrar_registro(EMUFS *efs, EMUFS_REG_ID n_IdReg)  */
165 /* Objetivo: Borra un registro determinado y actualiza los archivos   */
166 /*           de Posicion Relativa (Indice-Offset) y el de Gaps        */
167 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
168 /*             EMUFS_REG_ID n_IdReg // Id del registro a eliminar.    */
169 /**********************************************************************/
170 int emufs_tipo2_borrar_registro(EMUFS *efs, EMUFS_REG_ID n_IdReg)
171 {       
172         EMUFS_OFFSET n_RegOffset,n_RegSize;
173          
174         /* Obtenemos el offset donde arranca el registro */
175         if ((n_RegOffset = emufs_idx_buscar_registro(efs,n_IdReg)) != -1)
176           printf("tipo2.c >> Searching Reg %lu...Found at offset: %lu\n",n_IdReg,n_RegOffset);
177         else 
178           return -1;
179         
180         /* Obtenemos el Size del Registro en cuestion y hacemos un dummyfill*/
181         emufs_tipo2_get_regsize(efs,n_RegOffset,&n_RegSize);
182         printf ("tipo2.c >> About to delete Reg %lu of Size: %lu\n",n_IdReg,n_RegSize);
183         emufs_tipo2_dummyfill(efs,n_RegOffset,n_RegSize);
184         
185         /* Agregamos el GAP en el archivo de FSC, el cual hara un merge con */
186         /* otro GAP por delante y/o por detras en caso de hallarlo. */
187         emufs_fsc_agregar_gap(efs,n_RegOffset,n_RegSize+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE));
188         
189         /* Agrego el ID que se ha liberado al archivo de ID's Libres */
190         emufs_did_agregar(efs,n_IdReg); 
191         
192         /* Borramos el registro del indice de posiciones relativas */
193         emufs_idx_borrar(efs,n_IdReg);
194         
195         return(0);
196 }
197
198 /**********************************************************************/
199 /* int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos,     */
200 /*                             EMUFS_REG_SIZE *n_RegSize)             */
201 /* Objetivo: Devuelve el tamanio de un registro, dado su init offset  */
202 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
203 /*             EMUFS_OFFSET n_RegPos // Offset al inicio del registro */
204 /*             EMUFS_REG_SIZE *n_RegSize // Size to lookup and return */
205 /**********************************************************************/
206 int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos, EMUFS_REG_SIZE *n_RegSize)
207 {
208     FILE *f_data;
209         char name_f[255];
210
211     /* Armamos el filename del archivo de datos */
212         strcpy(name_f,efs->nombre);
213         strcat(name_f,".dat");
214
215     if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
216         fseek(f_data,n_RegPos+sizeof(EMUFS_REG_ID),SEEK_SET);
217         fread(n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);               
218         fclose(f_data);
219         
220         return (0);
221 }
222
223 /**********************************************************************/
224 /* int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos,       */
225 /*                           EMUFS_REG_SIZE n_Amount                  */
226 /* Objetivo: Pisa con basura lo que es hasta el momento un reg en     */
227 /*           el disco para indicar su borrado (Debug Purposes Only).  */
228 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
229 /*             EMUFS_OFFSET n_RegPos // Offset al inicio del registro */
230 /*             EMUFS_REG_SIZE *n_Amount // Size to lookup and return  */
231 /**********************************************************************/
232 int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos, EMUFS_REG_SIZE n_Amount)
233 {
234     FILE *f_data;
235         char name_f[255];
236     char *dummyfill;
237         char *ptr_cur;
238         unsigned long n_FillSize,n_count;
239         
240     /* Armamos el filename del archivo de datos */
241         strcpy(name_f,efs->nombre);
242         strcat(name_f,".dat");
243
244     if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
245         
246         /* Preparo el garbage y se lo tiro encima */
247         n_FillSize = n_Amount+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE);
248         dummyfill = (char*)malloc(n_FillSize);
249         ptr_cur = dummyfill;
250         for (n_count = 0; n_count < n_FillSize; ++n_count) memcpy(ptr_cur+n_count,"#",1);
251         fseek(f_data,n_RegPos,SEEK_SET);
252         fwrite(dummyfill,n_FillSize,1,f_data);
253         fclose(f_data);
254         
255         /* printf("Dummy Fill: %s\n",dummyfill); */ /*Uncomment to check */
256         free(dummyfill);
257         return (0);
258 }