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,"a+"))==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);
89 /* Finalmente, actualizamos el indice de registros (offsets) */
90 emufs_idx_agregar(efs,n_IdReg,n_RegOffset);
95 /**********************************************************************/
96 /* int emufs_tipo2_borrar_registro(EMUFS *efs, EMUFS_REG_ID n_IdReg) */
97 /* Objetivo: Borra un registro determinado y actualiza los archivos */
98 /* de Posicion Relativa (Indice-Offset) y el de Gaps */
99 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
100 /* EMUFS_REG_ID n_IdReg // Id del registro a eliminar. */
101 /**********************************************************************/
102 int emufs_tipo2_borrar_registro(EMUFS *efs, EMUFS_REG_ID n_IdReg)
106 EMUFS_OFFSET n_RegOffset,n_RegSize;
108 /* Obtenemos el offset donde arranca el registro */
109 if ((n_RegOffset = emufs_idx_buscar_registro(efs,n_IdReg)) != -1)
110 printf("tipo2.c >> Searching Reg %lu...Found at offset: %lu\n",n_IdReg,n_RegOffset);
114 /* Obtenemos el Size del Registro en cuestion y hacemos un dummfill*/
115 emufs_tipo2_get_regsize(efs,n_RegOffset,&n_RegSize);
116 printf ("tipo2.c >> About to delete Reg %lu of Size: %lu\n",n_IdReg,n_RegSize);
117 emufs_tipo2_dummyfill(efs,n_RegOffset,n_RegSize);
122 /**********************************************************************/
123 /* int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos, */
124 /* EMUFS_REG_SIZE *n_RegSize) */
125 /* Objetivo: Devuelve el tamanio de un registro, dado su init offset */
126 /* Parametros: EMUFS *efs // Struct con handlers + info del openfile. */
127 /* EMUFS_OFFSET n_RegPos // Offset al inicio del registro */
128 /* EMUFS_REG_SIZE *n_RegSize // Size to lookup and return */
129 /**********************************************************************/
130 int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos, EMUFS_REG_SIZE *n_RegSize)
135 /* Armamos el filename del archivo de datos */
136 strcpy(name_f,efs->nombre);
137 strcat(name_f,".dat");
139 if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
140 fseek(f_data,n_RegPos+sizeof(EMUFS_REG_ID),SEEK_SET);
141 fread(n_RegSize,sizeof(EMUFS_REG_SIZE),1,f_data);
147 /**********************************************************************/
148 /* int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos, */
149 /* EMUFS_REG_SIZE n_Amount */
150 /* Objetivo: Pisa con basura lo que es hasta el momento un reg en */
151 /* el disco para indicar su borrado (Debug Purposes Only). */
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_Amount // Size to lookup and return */
155 /**********************************************************************/
156 int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos, EMUFS_REG_SIZE n_Amount)
162 unsigned long n_FillSize,n_count;
164 /* Armamos el filename del archivo de datos */
165 strcpy(name_f,efs->nombre);
166 strcat(name_f,".dat");
168 if ((f_data = fopen(name_f,"r+")) == NULL) return -1; /* ERROR */
170 /* Preparo el garbage y se lo tiro encima */
171 n_FillSize = n_Amount+sizeof(EMUFS_REG_ID)+sizeof(EMUFS_REG_SIZE);
172 dummyfill = (char*)malloc(n_FillSize);
174 for (n_count = 0; n_count < n_FillSize; ++n_count) memcpy(ptr_cur+n_count,"#",1);
175 fseek(f_data,n_RegPos,SEEK_SET);
176 fwrite(dummyfill,n_FillSize,1,f_data);
179 /* printf("Dummy Fill: %s\n",dummyfill); */ /*Uncomment to check */
184 /**********************************************************************/
185 /* EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *efs) */
186 /* Objetivo: Devuelve un Id apropiado y disponible para un nuevo reg */
187 /* Parametros: EMUFS *emu // Struct con handlers + info del openfile. */
188 /**********************************************************************/
189 EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *efs)
191 EMUFS_REG_ID n_RegId;
193 /* Si no se hallo un id libre, entonces debo usar el maximo + 1 */
194 if ( (n_RegId = emufs_did_get_last(efs)) == -1 )
195 n_RegId = emufs_idx_buscar_mayor_id(efs);