]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/tipo2.c
Tipo2 ya reutiliza ID's y Gaps en el archivo de datos. Aun falta fixear el borrado...
[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 /**********************************************************************/
40 /* EMUFS_REG_ID emufs_tipo2_grabar_registro(EMUFS *efs, void *ptr,    */
41 /*                                 EMUFS_REG_SIZE n_RegSize)          */
42 /* Objetivo: Grabar un registro en un archivo del Tipo 2.             */
43 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
44 /*             void *ptr // Puntero al buffer (registro) a guardar    */
45 /*             EMUFS_REG_SIZE n_RegSize // Size del reg en cuestion   */
46 /**********************************************************************/
47 EMUFS_REG_ID emufs_tipo2_grabar_registro(EMUFS *efs, void *ptr, EMUFS_REG_SIZE n_RegSize, int* err)
48 {
49         EMUFS_REG_ID n_IdReg;
50         EMUFS_FREE n_FreeSpace;
51         EMUFS_OFFSET n_WrtOffset,n_RegOffset;
52         unsigned long int n_FisicSize;
53         FILE *f_data;
54         char name_f[255];
55         
56         /* Armamos el filename del archivo de datos */
57         strcpy(name_f,efs->nombre);
58         strcat(name_f,".dat");
59         
60         if ( (f_data = fopen(name_f,"r+"))==NULL ) return -1; /*ERROR*/
61         
62         /* Obtengo un offset en donde iniciar la escritura de mi registro */
63         /* de manera segura (habra espacio suficiente) */
64         n_FisicSize = sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE)+n_RegSize;
65         n_WrtOffset = emufs_fsc_buscar_lugar(efs,n_FisicSize,&n_FreeSpace);
66         printf("tipo2.c >> Searching FSC: Offset = %lu FSpace: %lu\n", n_WrtOffset, n_FreeSpace);
67         
68         /* Si no encontre un gap, entonces escribo el registro al final */
69         if (n_WrtOffset == -1) {                       
70                 
71                 /* Obtengo un ID libre para el registro y luego grabo a disco */
72         n_IdReg = emufs_tipo2_get_id(efs);
73                 fseek(f_data, 0, SEEK_END);
74                 n_RegOffset = ftell(f_data);
75
76                 /* Escribo [RegId]|[RegSize]|[RegData] */
77                 fwrite(&n_IdReg,sizeof(EMUFS_REG_ID),1,f_data);
78                 fwrite(&n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);
79                 fwrite(ptr,n_RegSize,1,f_data);
80                                 
81                 /* Bye */
82                 printf("Tipo2.c >> RegNr: %lu with FisicSize: %lu inserted at Offset: %lu\n",n_IdReg,n_FisicSize,n_RegOffset);
83                 fclose(f_data);
84                 
85         } else {
86                 
87                 /* Obtengo un ID libre para el registro y luego grabo en disco */
88         n_IdReg = emufs_tipo2_get_id(efs);
89                 n_RegOffset = n_WrtOffset;
90                 fseek(f_data,n_RegOffset,0);
91                 
92         /* Escribo [RegId]|[RegSize]|[RegData] */
93                 fwrite(&n_IdReg,sizeof(EMUFS_REG_ID),1,f_data);
94                 fwrite(&n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);
95                 fwrite(ptr,n_RegSize,1,f_data);
96                                 
97                 /* Bye */
98                 printf("Tipo2.c >> RegNr: %lu with FisicSize: %lu inserted at Offset: %lu\n",n_IdReg,n_FisicSize,n_RegOffset);
99                 fclose(f_data);
100                 
101                 /* Actualizo el espacio libre en el GAP donde puse el registro */
102                 emufs_fsc_actualizar(efs,n_WrtOffset,n_FreeSpace-n_FisicSize);          
103         }
104                 
105         /* Finalmente, actualizamos el indice de registros (offsets) */
106         emufs_idx_agregar(efs,n_IdReg,n_RegOffset);
107                 
108         return n_IdReg;
109 }
110
111 /**********************************************************************/
112 /* int emufs_tipo2_borrar_registro(EMUFS *efs, EMUFS_REG_ID n_IdReg)  */
113 /* Objetivo: Borra un registro determinado y actualiza los archivos   */
114 /*           de Posicion Relativa (Indice-Offset) y el de Gaps        */
115 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
116 /*             EMUFS_REG_ID n_IdReg // Id del registro a eliminar.    */
117 /**********************************************************************/
118 int emufs_tipo2_borrar_registro(EMUFS *efs, EMUFS_REG_ID n_IdReg)
119 {       
120         FILE *f_data;
121         char name_f[255];
122         EMUFS_OFFSET n_RegOffset,n_RegSize;
123          
124         /* Obtenemos el offset donde arranca el registro */
125         if ((n_RegOffset = emufs_idx_buscar_registro(efs,n_IdReg)) != -1)
126           printf("tipo2.c >> Searching Reg %lu...Found at offset: %lu\n",n_IdReg,n_RegOffset);
127         else 
128           return -1;
129         
130         /* Obtenemos el Size del Registro en cuestion y hacemos un dummfill*/
131         emufs_tipo2_get_regsize(efs,n_RegOffset,&n_RegSize);
132         printf ("tipo2.c >> About to delete Reg %lu of Size: %lu\n",n_IdReg,n_RegSize);
133         emufs_tipo2_dummyfill(efs,n_RegOffset,n_RegSize);
134         
135         /* Agregamos el GAP en el archivo de FSC, el cual hara un merge con */
136         /* otro GAP por delante y/o por detras en caso de hallarlo. */
137         emufs_fsc_agregar_gap(efs,n_RegOffset,n_RegSize+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE));
138         
139         /* Agrego el ID que se ha liberado al archivo de ID's Libres */
140         emufs_did_agregar(efs,n_IdReg); 
141         
142         /* Borramos el registro del indice de posiciones relativas */
143         /*emufs_idx_borrar(efs,n_IdReg);*/
144         
145         return(0);
146 }
147
148 /**********************************************************************/
149 /* int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos,     */
150 /*                             EMUFS_REG_SIZE *n_RegSize)             */
151 /* Objetivo: Devuelve el tamanio de un registro, dado su init offset  */
152 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
153 /*             EMUFS_OFFSET n_RegPos // Offset al inicio del registro */
154 /*             EMUFS_REG_SIZE *n_RegSize // Size to lookup and return */
155 /**********************************************************************/
156 int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos, EMUFS_REG_SIZE *n_RegSize)
157 {
158     FILE *f_data;
159         char name_f[255];
160
161     /* Armamos el filename del archivo de datos */
162         strcpy(name_f,efs->nombre);
163         strcat(name_f,".dat");
164
165     if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
166         fseek(f_data,n_RegPos+sizeof(EMUFS_REG_ID),SEEK_SET);
167         fread(n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);               
168         fclose(f_data);
169         
170         return (0);
171 }
172
173 /**********************************************************************/
174 /* int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos,       */
175 /*                           EMUFS_REG_SIZE n_Amount                  */
176 /* Objetivo: Pisa con basura lo que es hasta el momento un reg en     */
177 /*           el disco para indicar su borrado (Debug Purposes Only).  */
178 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
179 /*             EMUFS_OFFSET n_RegPos // Offset al inicio del registro */
180 /*             EMUFS_REG_SIZE *n_Amount // Size to lookup and return  */
181 /**********************************************************************/
182 int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos, EMUFS_REG_SIZE n_Amount)
183 {
184     FILE *f_data;
185         char name_f[255];
186     void *dummyfill;
187         void *ptr_cur;
188         unsigned long n_FillSize,n_count;
189         
190     /* Armamos el filename del archivo de datos */
191         strcpy(name_f,efs->nombre);
192         strcat(name_f,".dat");
193
194     if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
195         
196         /* Preparo el garbage y se lo tiro encima */
197         n_FillSize = n_Amount+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE);
198         dummyfill = (char*)malloc(n_FillSize);
199         ptr_cur = dummyfill;
200         for (n_count = 0; n_count < n_FillSize; ++n_count) memcpy(ptr_cur+n_count,"#",1);
201         fseek(f_data,n_RegPos,SEEK_SET);
202         fwrite(dummyfill,n_FillSize,1,f_data);
203         fclose(f_data);
204         
205         /* printf("Dummy Fill: %s\n",dummyfill); */ /*Uncomment to check */
206         
207         return (0);
208 }
209
210 /**********************************************************************/
211 /* EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *efs)                        */
212 /* Objetivo: Devuelve un Id apropiado y disponible para un nuevo reg  */
213 /* Parametros: EMUFS *emu // Struct con handlers + info del openfile. */
214 /**********************************************************************/
215 EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *efs)
216 {
217         EMUFS_REG_ID n_RegId;
218
219         /* Si no se hallo un id libre, entonces debo usar el maximo + 1 */
220         if ( (n_RegId = emufs_did_get_last(efs)) == -1 )
221                 n_RegId = emufs_idx_buscar_mayor_id(efs);
222         
223         return n_RegId; 
224 }