]> git.llucax.com Git - z.facultad/75.06/jacu.git/blobdiff - src/vfile/vfile.c
* Guardo el k en el array de salida del BS para que el MTF lo tenga en cuenta.
[z.facultad/75.06/jacu.git] / src / vfile / vfile.c
index c8bde5d834047e32fcfbc4b4122b93890c898ace..589d4aa1212bf1af2ca3fedd95c9f527561164df 100644 (file)
@@ -22,7 +22,7 @@
  * Autores: Leandro Lucarella <llucare@fi.uba.ar>
  *----------------------------------------------------------------------------
  *
- * $Id: bufford.c 624 2004-05-30 20:18:04Z llucare $
+ * $Id$
  *
  */
 
@@ -69,14 +69,15 @@ VFILE* vfopen(const char* path, const char* mode, long volsize)
                free(vfp);
                return 0;
        }
-       if (!(vfp->name = strdup(path))) /* no hay más memoria */
+       if (!(vfp->name = str_dup(path))) /* no hay más memoria */
        {
-               PERR("vfopen: no se pudo hacer strdup!");
+               PERR("vfopen: no se pudo hacer str_dup!");
                free(vfp);
                return 0;
        }
        /* Abrimos primer archivo de los volumenes. */
        vfp->currvol = -1;
+       vfp->lastvol = 0;
        if (vfvol_open_next(vfp)) /* no se pudo abrir el primer volumen. */
        {
                PERR("vfopen: no se pudo abrir archivo inicial!");
@@ -84,10 +85,7 @@ VFILE* vfopen(const char* path, const char* mode, long volsize)
                free(vfp);
                return 0;
        }
-       /* todo ok. */
-       vfp->room    = vfp->volsize;
-       vfp->lastvol = 0;
-       return vfp;
+       return vfp; /* todo ok. */
 }
 
 int vfclose(VFILE* vfp)
@@ -100,6 +98,11 @@ int vfclose(VFILE* vfp)
        return ret;
 }
 
+int vfeof(VFILE* vfp)
+{
+       return vfp->lastvol && feof(vfp->fp);
+}
+
 int vfgetc(VFILE* vfp)
 {
        int c;
@@ -119,34 +122,60 @@ int vfputc(int c, VFILE* vfp)
 {
        /* Si no es multivolumen o hay lugar, agrego y salgo. */
        if (!vfp->volsize || vfp->room--) return fputc(c, vfp->fp);
+       PERR("vfputc: Necesito otro volumen!\n");
        /* Si no hay lugar, abro otro volumen. */
        if (vfvol_close(vfp)) return EOF; /* error al cerrar. */
        if (vfvol_open_next(vfp)) return EOF; /* error al abrir. */
-       vfp->room = vfp->volsize;
+       vfp->room--; /* resto de nuevo el espacio porque al abrirlo lo resetea. */
        return fputc(c, vfp->fp);
 }
 
 size_t vfread(void* ptr, size_t size, size_t nmemb, VFILE* vfp)
 {
-       return 0;
+       int c;
+       size_t i = 0;
+       size_t total = size * nmemb;
+       /* leo uno a uno y si hay error salgo. */
+       while (i < total)
+       {
+               if ((c = vfgetc(vfp)) == EOF)
+               {
+                       PERR("vfread: EOF");
+                       break;
+               }
+               else ((char*)ptr)[i++] = c;
+       }
+       return i / size;
 }
 
 size_t vfwrite(const void *ptr, size_t size, size_t nmemb, VFILE* vfp)
 {
-       return 0;
+       size_t i = 0;
+       size_t total = size * nmemb;
+       /* escribo uno a uno y si hay error salgo. */
+       while (i < total && (vfputc(((char*)ptr)[i++], vfp)) != EOF);
+       return i / size;
 }
 
 int vfvol_close(VFILE* vfp)
 {
-       /* Si es de escritura tengo que guardar la cabecera. */
-       if (vfp->mode == VFWRITE)
+       /* Si es de escritura y el último guardo la cabecera. */
+       if (vfp->mode == VFWRITE && vfp->lastvol)
        {
                int ret;
                PERR("vfvol_close: modo == VFWRITE");
                /* Me posiciono al principio del archivo. */
-               if ((ret = fseek(vfp->fp, 0l, SEEK_SET))) return ret; /* fseek error. */
+               if ((ret = fseek(vfp->fp, 0l, SEEK_SET)))
+               {
+                       PERR("vfvol_close: fseek error");
+                       return ret; /* fseek error. */
+               }
                /* Guardo cabecera para indicar si es el último volumen o no. */
-               if ((ret = fputc(vfp->lastvol, vfp->fp))) return ret; /* fputc error. */
+               if ((ret = fputc(vfp->lastvol, vfp->fp)) == EOF)
+               {
+                       PERR("vfvol_close: fputc error");
+                       return ret; /* fputc error. */
+               }
        }
        return fclose(vfp->fp);
 }
@@ -177,8 +206,12 @@ int vfvol_open_next(VFILE* vfp)
        if (volname) free(volname);
        /* Si es para lectura, me fijo si es el últio a leer. */
        if (vfp->mode == VFREAD) vfp->lastvol = fgetc(vfp->fp);
-       /* Si es para escritura, guardo header dummy (supongo que es el último). */
-       if (vfp->mode == VFWRITE) return !fputc(1, vfp->fp);
+       /* Si es para escritura, guardo header por default (hay más volúmenes). */
+       if (vfp->mode == VFWRITE)
+       {
+               vfp->room = vfp->volsize; /* tengo todo el espacio disponible. */
+               return fputc(vfp->lastvol, vfp->fp) == EOF;
+       }
        return 0;
 }