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: Fri Apr 10 17:10:00 ART 2004
22 * Autores: Alan Kennedy <kennedya@3dgames.com.ar>
23 *----------------------------------------------------------------------------
25 * $Id: tipo3.c 85 2004-04-08 23:39:28Z sagar $
29 /***************************************************************/
30 /* Implementación del Tipo Archivo 2: Registros Variables, Sin */
32 /***************************************************************/
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)
50 EMUFS_FREE n_FreeSpace;
51 EMUFS_OFFSET n_WrtOffset,n_RegOffset;
52 unsigned long int n_FisicSize;
56 /* Armamos el filename del archivo de datos */
57 strcpy(name_f,efs->nombre);
58 strcat(name_f,".dat");
60 if ( (f_data = fopen(name_f,"r+"))==NULL ) return -1; /*ERROR*/
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);
68 /* Si no encontre un gap, entonces escribo el registro al final */
69 if (n_WrtOffset == -1) {
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);
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);
82 printf("Tipo2.c >> RegNr: %lu with FisicSize: %lu inserted at Offset: %lu\n",n_IdReg,n_FisicSize,n_RegOffset);
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);
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);
98 printf("Tipo2.c >> RegNr: %lu with FisicSize: %lu inserted at Offset: %lu\n",n_IdReg,n_FisicSize,n_RegOffset);
101 /* Actualizo el espacio libre en el GAP donde puse el registro */
102 emufs_fsc_actualizar(efs,n_WrtOffset,n_FreeSpace-n_FisicSize);
105 /* Finalmente, actualizamos el indice de registros (offsets) */
106 emufs_idx_agregar(efs,n_IdReg,n_RegOffset);
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)
122 EMUFS_OFFSET n_RegOffset,n_RegSize;
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);
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);
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));
139 /* Agrego el ID que se ha liberado al archivo de ID's Libres */
140 emufs_did_agregar(efs,n_IdReg);
142 /* Borramos el registro del indice de posiciones relativas */
143 /*emufs_idx_borrar(efs,n_IdReg);*/
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)
161 /* Armamos el filename del archivo de datos */
162 strcpy(name_f,efs->nombre);
163 strcat(name_f,".dat");
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);
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)
188 unsigned long n_FillSize,n_count;
190 /* Armamos el filename del archivo de datos */
191 strcpy(name_f,efs->nombre);
192 strcat(name_f,".dat");
194 if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
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);
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);
205 /* printf("Dummy Fill: %s\n",dummyfill); */ /*Uncomment to check */
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)
217 EMUFS_REG_ID n_RegId;
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);