+/* vim: set noexpandtab tabstop=4 shiftwidth=4 wrap:
+ *----------------------------------------------------------------------------
+ * emufs
+ *----------------------------------------------------------------------------
+ * This file is part of emufs.
+ *
+ * emufs is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * emufs is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with emufs; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ *----------------------------------------------------------------------------
+ * Creado: dom may 30 04:54:53 ART 2004
+ * Autores: Leandro Lucarella <llucare@fi.uba.ar>
+ *----------------------------------------------------------------------------
+ *
+ * $Id: tipo1.c 548 2004-05-28 22:44:27Z llucare $
+ *
+ */
+
+/** \file
+ *
+ * Archivo temporal con un fragmento ordenado del archivo original.
+ *
+ * Implementación de un archivo temporal con un fragmento ordenado del archivo
+ * original utilizado para hacer el ordenamiento por fusión (merge sort).
+ *
+ */
+
+#include "mergefile.h"
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+char* mergefile_makefilename(int i)
+{
+ 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));
+ 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);
+ 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;
+ return mf;
+}
+
+void mergefile_delete(MERGEFILE* mf)
+{
+ assert(mf);
+ assert(mf->fp);
+ assert(mf->filename);
+ fclose(mf->fp);
+ remove(mf->filename);
+ free(mf->filename);
+ free(mf);
+}
+
+int mergefile_peek_next(MERGEFILE* mf)
+{
+ assert(mf);
+ assert(mf->fp);
+ assert(mf->more);
+ return mf->next;
+}
+
+int mergefile_pop_next(MERGEFILE* mf)
+{
+ int ret;
+ assert(mf);
+ assert(mf->fp);
+ assert(mf->more);
+ ret = mf->next;
+ /* obtiene dato, si no hay más, se activa el flag */
+ if (fscanf(mf->fp, "%i", &(mf->next)) <= 0) mf->more = 0;
+ return ret;
+}
+
+int mergefile_has_more(MERGEFILE* mf)
+{
+ assert(mf);
+ assert(mf->fp);
+ return mf->more;
+}
+