X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fext-array.c;h=9129d365d6e10f66e1206432541cc2c492093dbc;hb=d97c0f1ed2858c48173c023964cec8234b5bc831;hp=57ff8e4a7d6225e3b56c9b71c0760e6e9570f635;hpb=32ee0e0402d6d56674f53a47d879ec5c07dabe09;p=pspp diff --git a/src/libpspp/ext-array.c b/src/libpspp/ext-array.c index 57ff8e4a7d..9129d365d6 100644 --- a/src/libpspp/ext-array.c +++ b/src/libpspp/ext-array.c @@ -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 #include "libpspp/ext-array.h" +#include "libpspp/message.h" #include #include @@ -29,13 +30,18 @@ #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; } @@ -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,