* Autores: Leandro Lucarella <llucare@fi.uba.ar>
*----------------------------------------------------------------------------
*
- * $Id: tipo1.c 548 2004-05-28 22:44:27Z llucare $
+ * $Id$
*
*/
#include <string.h>
#include <assert.h>
-char* mergefile_makefilename(int i)
+MERGEFILE* mergefile_new(size_t reg_size)
{
- size_t size = sizeof(MERGEFILE_TEMPLATE) + 8; /* 8 más para el int */
- char* filename = malloc(size);
- if (!filename) return 0;
- /* Hasta que me de la memoria para crear el nombre del archivo */
- while (snprintf(filename, size, MERGEFILE_TEMPLATE, i) >= size) {
- char* new;
- size += 8;
- new = realloc(filename, size);
- if (new) {
- filename = new;
- } else {
- free(filename);
- return 0;
- }
- }
- return filename;
-}
-
-MERGEFILE* mergefile_new(int i)
-{
- MERGEFILE* mf = malloc(sizeof(MERGEFILE));
+ MERGEFILE* mf;
+ assert(reg_size);
+ mf = malloc(sizeof(MERGEFILE));
if (!mf) {
return 0;
}
- /* asigno el nombre de archivo */
- if (!(mf->filename = mergefile_makefilename(i))) {
- free(mf);
- return 0;
- }
/* abre archivo */
- if (!(mf->fp = fopen(mf->filename, "rb"))) {
- free(mf->filename);
+ if (!(mf->fp = tmpfile())) {
+ free(mf->next);
free(mf);
return 0;
}
- /* obtiene dato */
- if (fscanf(mf->fp, "%i", &(mf->next)) <= 0) {
- fclose(mf->fp);
- free(mf->filename);
- free(mf);
- return 0;
- }
- mf->more = 1;
+ mf->next = 0;
+ mf->reg_size = reg_size;
return mf;
}
{
assert(mf);
assert(mf->fp);
- assert(mf->filename);
fclose(mf->fp);
- remove(mf->filename);
- free(mf->filename);
+ if (mf->next) free(mf->next);
free(mf);
}
-int mergefile_peek_next(MERGEFILE* mf)
+int mergefile_switch_to_input(MERGEFILE* mf)
{
assert(mf);
assert(mf->fp);
- assert(mf->more);
- return mf->next;
+ assert(!mf->next);
+ /* retrocede al principio del archivo y obtiene el primer dato */
+ if (fseek(mf->fp, 0L, SEEK_SET)) return 0;
+ /* aloco memoria para el próximo */
+ if (!(mf->next = malloc(mf->reg_size))) return 0;
+ /* leo primer valor */
+ if (!fread(mf->next, mf->reg_size, 1, mf->fp)) {
+ free(mf->next);
+ mf->next = 0;
+ }
+ return 1; /* OK */
+}
+
+int mergefile_push(MERGEFILE* mf, void* data)
+{
+ assert(mf);
+ assert(mf->fp);
+ return fwrite(data, mf->reg_size, 1, mf->fp);
}
-int mergefile_pop_next(MERGEFILE* mf)
+void* mergefile_pop(MERGEFILE* mf)
{
- int ret;
+ void* ret;
assert(mf);
assert(mf->fp);
- assert(mf->more);
+ /* Si no hay más, devuelvo 0 */
+ if (!mf->next) return 0;
ret = mf->next;
+ /* aloco memoria para el próximo */
+ if (!(mf->next = malloc(mf->reg_size))) {
+ mf->next = ret;
+ return 0;
+ }
/* obtiene dato, si no hay más, se activa el flag */
- if (fscanf(mf->fp, "%i", &(mf->next)) <= 0) mf->more = 0;
+ if (!fread(mf->next, mf->reg_size, 1, mf->fp)) {
+ free(mf->next);
+ mf->next = 0;
+ }
return ret;
}
+void* mergefile_peek(MERGEFILE* mf)
+{
+ assert(mf);
+ assert(mf->fp);
+ return mf->next;
+}
+
int mergefile_has_more(MERGEFILE* mf)
{
assert(mf);
assert(mf->fp);
- return mf->more;
+ return mf->next != 0;
}