X-Git-Url: https://git.llucax.com/z.facultad/75.06/jacu.git/blobdiff_plain/6ceb9e978d795143bdf7679855a932540eef18b2..HEAD:/src/vfile/vfile.c diff --git a/src/vfile/vfile.c b/src/vfile/vfile.c index 1ca5607..7136eed 100644 --- a/src/vfile/vfile.c +++ b/src/vfile/vfile.c @@ -22,7 +22,7 @@ * Autores: Leandro Lucarella *---------------------------------------------------------------------------- * - * $Id: bufford.c 624 2004-05-30 20:18:04Z llucare $ + * $Id$ * */ @@ -77,6 +77,7 @@ VFILE* vfopen(const char* path, const char* mode, long volsize) } /* 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!"); @@ -97,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; @@ -126,27 +132,58 @@ int vfputc(int c, VFILE* vfp) 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) + int ret = 0; + if (vfp->fp) { - 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. */ - /* Guardo cabecera para indicar si es el último volumen o no. */ - if ((ret = fputc(vfp->lastvol, vfp->fp))) return ret; /* fputc error. */ + /* 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))) + { + 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)) == EOF) + { + PERR("vfvol_close: fputc error"); + return ret; /* fputc error. */ + } + } + ret = fclose(vfp->fp); + vfp->fp = 0; } - return fclose(vfp->fp); + return ret; } int vfvol_open_next(VFILE* vfp) @@ -175,12 +212,63 @@ 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). */ + /* Si es para escritura, guardo header por default (hay más volúmenes). */ if (vfp->mode == VFWRITE) { - vfp->room = vfp->volsize; - return !fputc(1, vfp->fp); + vfp->room = vfp->volsize; /* tengo todo el espacio disponible. */ + return fputc(vfp->lastvol, vfp->fp) == EOF; } return 0; } +long vfsize(const char* path) +{ + VFILE* vfp = vfopen(path, "r", 0); + long size; + if (!vfp) return -1; /* error */ + if (fseek(vfp->fp, 0l, SEEK_END) == -1) + { + vfclose(vfp); + return -1; /* error */ + } + else + { + size = ftell(vfp->fp); + if (size == -1) + { + vfclose(vfp); + return -1; /* error */ + } + } + while (!vfp->lastvol) /* mientras no sea el último volumen */ + { + if (vfvol_open_next(vfp)) + { + vfclose(vfp); + return -1; /* error */ + } + if (fseek(vfp->fp, 0l, SEEK_END) == -1) + { + vfclose(vfp); + return -1; /* error */ + } + else + { + long curr_size = ftell(vfp->fp); + if (curr_size == -1) + { + vfclose(vfp); + return -1; /* error */ + } + size += curr_size; + } + if (vfvol_close(vfp)) + { + vfclose(vfp); + return -1; /* error */ + } + } + vfclose(vfp); + return size; +} +