output: Rename caption to title.
[pspp] / src / libpspp / ext-array.c
index 68bbe954f38768d80d48a9c1f90ae71873daf086..9129d365d6e10f66e1206432541cc2c492093dbc 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
 #include <config.h>
 
 #include "libpspp/ext-array.h"
+#include "libpspp/message.h"
 
 #include <errno.h>
 #include <stdio.h>
 #include "libpspp/cast.h"
 #include "libpspp/temp-file.h"
 
-#include "gl/error.h"
 #include "gl/unlocked-io.h"
 #include "gl/xalloc.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
+enum op
+  {
+    OP_WRITE, /* writing */
+    OP_READ   /* reading */
+  };
+
 struct ext_array
   {
     FILE *file;                 /* Underlying file. */
@@ -45,6 +51,9 @@ struct ext_array
        the stream buffer, making the common case of sequential
        access to cases unreasonably slow. */
     off_t position;
+
+    /* The most recent operation performed */
+    enum op op;
   };
 
 /* Creates and returns a new external array. */
@@ -54,8 +63,9 @@ ext_array_create (void)
   struct ext_array *ea = xmalloc (sizeof *ea);
   ea->file = create_temp_file ();
   if (ea->file == NULL)
-    error (0, errno, _("failed to create temporary file"));
+    msg_error (errno, _("failed to create temporary file"));
   ea->position = 0;
+  ea->op = OP_WRITE;
   return ea;
 }
 
@@ -69,7 +79,7 @@ ext_array_destroy (struct ext_array *ea)
     {
       ok = !ext_array_error (ea);
       if (ea->file != NULL)
-        fclose (ea->file);
+        close_temp_file (ea->file);
       free (ea);
     }
   return ok;
@@ -80,13 +90,12 @@ ext_array_destroy (struct ext_array *ea)
    Returns true if the seek is successful and EA is not
    otherwise tainted, false otherwise. */
 static bool
-do_seek (const struct ext_array *ea_, off_t offset)
+do_seek (const struct ext_array *ea_, off_t offset, enum op op)
 {
   struct ext_array *ea = CONST_CAST (struct ext_array *, ea_);
-
   if (!ext_array_error (ea))
     {
-      if (ea->position == offset)
+      if (ea->position == offset && ea->op == op)
         return true;
       else if (fseeko (ea->file, offset, SEEK_SET) == 0)
         {
@@ -94,7 +103,7 @@ do_seek (const struct ext_array *ea_, off_t offset)
           return true;
         }
       else
-        error (0, errno, _("seeking in temporary file"));
+        msg_error (errno, _("seeking in temporary file"));
     }
 
   return false;
@@ -113,14 +122,15 @@ do_read (const struct ext_array *ea_, void *buffer, size_t bytes)
   if (bytes > 0 && fread (buffer, bytes, 1, ea->file) != 1)
     {
       if (ferror (ea->file))
-        error (0, errno, _("reading temporary file"));
+        msg_error (errno, _("reading temporary file"));
       else if (feof (ea->file))
-        error (0, 0, _("unexpected end of file reading temporary file"));
+        msg_error ( 0, _("unexpected end of file reading temporary file"));
       else
         NOT_REACHED ();
       return false;
     }
   ea->position += bytes;
+  ea->op = OP_READ;
   return true;
 }
 
@@ -134,10 +144,11 @@ do_write (struct ext_array *ea, const void *buffer, size_t bytes)
   assert (!ext_array_error (ea));
   if (bytes > 0 && fwrite (buffer, bytes, 1, ea->file) != 1)
     {
-      error (0, errno, _("writing to temporary file"));
+      msg_error (errno, _("writing to temporary file"));
       return false;
     }
   ea->position += bytes;
+  ea->op = OP_WRITE;
   return true;
 }
 
@@ -146,16 +157,17 @@ do_write (struct ext_array *ea, const void *buffer, size_t bytes)
 bool
 ext_array_read (const struct ext_array *ea, off_t offset, size_t n, void *data)
 {
-  return do_seek (ea, offset) && do_read (ea, data, n);
+  return do_seek (ea, offset, OP_READ) && do_read (ea, data, n);
 }
 
+
 /* Writes the N bytes in DATA to EA at byte offset OFFSET.
    Returns true if successful, false on failure.  */
 bool
 ext_array_write (struct ext_array *ea, off_t offset, size_t n,
                  const void *data)
 {
-  return do_seek (ea, offset) && do_write (ea, data, n);
+  return do_seek (ea, offset, OP_WRITE) && do_write (ea, data, n);
 }
 
 /* Returns true if an error has occurred in I/O on EA,