pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] pspp/src libpspp/taint.h libpspp/taint.c data/s... [simpler-p


From: Ben Pfaff
Subject: [Pspp-cvs] pspp/src libpspp/taint.h libpspp/taint.c data/s... [simpler-proc]
Date: Mon, 07 May 2007 04:38:39 +0000

CVSROOT:        /cvsroot/pspp
Module name:    pspp
Branch:         simpler-proc
Changes by:     Ben Pfaff <blp> 07/05/07 04:38:39

Modified files:
        src/libpspp    : taint.h taint.c 
        src/data       : sys-file-reader.c casewriter.h casewriter.c 
                         casewriter-private.h casereader.c 
                         casereader-private.h automake.mk 
Added files:
        src/data       : casewriter-translator.c 

Log message:
        Continue cleanup.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/libpspp/taint.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/libpspp/taint.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.1&r2=1.1.2.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/sys-file-reader.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.32.2.2&r2=1.32.2.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.3&r2=1.1.2.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.4&r2=1.1.2.5
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter-private.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.2&r2=1.1.2.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casereader.c?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.6&r2=1.1.2.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casereader-private.h?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.1.2.2&r2=1.1.2.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/automake.mk?cvsroot=pspp&only_with_tag=simpler-proc&r1=1.15.2.3&r2=1.15.2.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/data/casewriter-translator.c?cvsroot=pspp&only_with_tag=simpler-proc&rev=1.1.2.1

Patches:
Index: libpspp/taint.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/libpspp/Attic/taint.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- libpspp/taint.h     4 May 2007 03:48:48 -0000       1.1.2.1
+++ libpspp/taint.h     7 May 2007 04:38:39 -0000       1.1.2.2
@@ -124,9 +124,9 @@
 void taint_propagate (const struct taint *from, const struct taint *to);
 
 bool taint_is_tainted (const struct taint *);
-void taint_set_taint (struct taint *);
+void taint_set_taint (const struct taint *);
 
 bool taint_has_tainted_successor (const struct taint *);
-void taint_reset_successor_taint (struct taint *);
+void taint_reset_successor_taint (const struct taint *);
 
 #endif /* libpspp/taint.h */

Index: libpspp/taint.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/libpspp/Attic/taint.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -b -r1.1.2.1 -r1.1.2.2
--- libpspp/taint.c     4 May 2007 03:48:48 -0000       1.1.2.1
+++ libpspp/taint.c     7 May 2007 04:38:39 -0000       1.1.2.2
@@ -160,8 +160,9 @@
 /* Marks TAINT tainted and propagates the taint to all of its
    successors. */
 void
-taint_set_taint (struct taint *taint) 
+taint_set_taint (const struct taint *taint_) 
 {
+  struct taint *taint = (struct taint *) taint_;
   if (!taint->tainted)
     recursively_set_taint (taint);
 }
@@ -180,8 +181,10 @@
 /* Attempts to reset the successor-taint on TAINT.  This is
    successful only if TAINT currently has no tainted successor. */
 void
-taint_reset_successor_taint (struct taint *taint) 
+taint_reset_successor_taint (const struct taint *taint_) 
 {
+  struct taint *taint = (struct taint *) taint_;
+
   if (taint->tainted_successor) 
     {
       size_t i;

Index: data/sys-file-reader.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/sys-file-reader.c,v
retrieving revision 1.32.2.2
retrieving revision 1.32.2.3
diff -u -b -r1.32.2.2 -r1.32.2.3
--- data/sys-file-reader.c      4 May 2007 03:48:47 -0000       1.32.2.2
+++ data/sys-file-reader.c      7 May 2007 04:38:39 -0000       1.32.2.3
@@ -1100,7 +1100,7 @@
 /* Reads one case from READER's file into C.  Returns true only
    if successful. */
 static bool
-sys_file_casereader_read (struct casereader *reader UNUSED, void *r_,
+sys_file_casereader_read (struct casereader *reader, void *r_,
                           struct ccase *c)
 {
   struct sfm_reader *r = r_;

Index: data/casewriter.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casewriter.h,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -b -r1.1.2.3 -r1.1.2.4
--- data/casewriter.h   4 May 2007 03:48:47 -0000       1.1.2.3
+++ data/casewriter.h   7 May 2007 04:38:39 -0000       1.1.2.4
@@ -26,20 +26,20 @@
 
 struct casewriter;
 
-struct casewriter *mem_writer_create (size_t value_cnt);
-struct casewriter *tmpfile_writer_create (size_t value_cnt);
-struct casewriter *autopaging_writer_create (size_t value_cnt);
-
-struct casewriter *casewriter_rename (struct casewriter *);
-
 void casewriter_write (struct casewriter *, struct ccase *);
 bool casewriter_destroy (struct casewriter *);
 
+struct casereader *casewriter_make_reader (struct casewriter *);
+
+struct casewriter *casewriter_rename (struct casewriter *);
+
 bool casewriter_error (const struct casewriter *);
 void casewriter_force_error (struct casewriter *);
 const struct taint *casewriter_get_taint (const struct casewriter *);
 
-struct casereader *casewriter_make_reader (struct casewriter *);
+struct casewriter *mem_writer_create (size_t value_cnt);
+struct casewriter *tmpfile_writer_create (size_t value_cnt);
+struct casewriter *autopaging_writer_create (size_t value_cnt);
 
 struct casewriter *
 casewriter_create_translator (struct casewriter *, 

Index: data/casewriter.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casewriter.c,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -b -r1.1.2.4 -r1.1.2.5
--- data/casewriter.c   6 May 2007 22:48:27 -0000       1.1.2.4
+++ data/casewriter.c   7 May 2007 04:38:39 -0000       1.1.2.5
@@ -34,25 +34,68 @@
 
 #include "xalloc.h"
 
+/* A casewriter. */
 struct casewriter
   {
     struct taint *taint;
     casenumber case_cnt;
     const struct casewriter_class *class;
-    void *private;
+    void *aux;
   };
 
-struct casewriter *
-casewriter_create (const struct casewriter_class *class, void *private) 
+static struct casewriter *create_casewriter_window (size_t value_cnt,
+                                                    casenumber max_in_core);
+
+/* Writes case C to WRITER. */
+void
+casewriter_write (struct casewriter *writer, struct ccase *c)
 {
-  struct casewriter *writer = xmalloc (sizeof *writer);
-  writer->taint = taint_create ();
-  writer->case_cnt = 0;
-  writer->class = class;
-  writer->private = private;
-  return writer;
+  writer->class->write (writer, writer->aux, c);
 }
 
+/* Destroys WRITER.
+   Returns true if successful, false if an I/O error was
+   encountered on WRITER or on some object on which WRITER has a
+   dependency. */
+bool
+casewriter_destroy (struct casewriter *writer) 
+{
+  bool ok = true;
+  if (writer != NULL)
+    {
+      writer->class->destroy (writer, writer->aux);
+      ok = taint_destroy (writer->taint);
+      free (writer);
+    }
+  return ok;
+}
+
+/* Destroys WRITER and in its place returns a casereader that can
+   be used to read back the data written to WRITER.  WRITER must
+   not be used again after calling this function, even as an
+   argument to casewriter_destroy.
+
+   Not all casewriters implement this function.  Behavior is
+   undefined if it is called on one that does not.
+
+   If an I/O error was encountered on WRITER or on some object on
+   which WRITER has a dependency, then the error will be
+   propagated to the new casereader. */
+struct casereader *
+casewriter_make_reader (struct casewriter *writer)
+{
+  struct casereader *reader;
+  reader = writer->class->convert_to_reader (writer, writer->aux);
+  taint_propagate (writer->taint, casereader_get_taint (reader));
+  taint_destroy (writer->taint);
+  free (writer);
+  return reader;
+}
+
+/* Returns a copy of WRITER, which is itself destroyed.
+   Useful for taking over ownership of a casewriter, to enforce
+   preventing the original owner from accessing the casewriter
+   again. */
 struct casewriter *
 casewriter_rename (struct casewriter *writer)
 {
@@ -61,86 +104,109 @@
   return new;
 }
 
-void
-casewriter_write (struct casewriter *writer, struct ccase *c)
-{
-  writer->class->write (writer, writer->private, c);
-}
-
+/* Returns true if an I/O error or another hard error has
+   occurred on WRITER, a clone of WRITER, or on some object on
+   which WRITER's data has a dependency, false otherwise. */
 bool
 casewriter_error (const struct casewriter *writer) 
 {
   return taint_is_tainted (writer->taint);
 }
 
+/* Marks WRITER as having encountered an error.
+
+   Ordinarily, this function should be called by the
+   implementation of a casewriter, not by the casewriter's
+   client.  Instead, casewriter clients should usually ensure
+   that a casewriter's error state is correct by using
+   taint_propagate to propagate to the casewriter's taint
+   structure, which may be obtained via casewriter_get_taint. */
 void
 casewriter_force_error (struct casewriter *writer) 
 {
   taint_set_taint (writer->taint);
 }
 
+/* Returns WRITER's associate taint object, for use with
+   taint_propagate and other taint functions. */
 const struct taint *
 casewriter_get_taint (const struct casewriter *writer) 
 {
   return writer->taint;
 }
 
-bool
-casewriter_destroy (struct casewriter *writer) 
+/* Creates and returns a new casewriter with the given CLASS and
+   auxiliary data AUX. */
+struct casewriter *
+casewriter_create (const struct casewriter_class *class, void *aux) 
 {
-  bool ok = true;
-  if (writer != NULL)
-    {
-      writer->class->destroy (writer, writer->private);
-      ok = taint_destroy (writer->taint);
-      free (writer);
-    }
-  return ok;
+  struct casewriter *writer = xmalloc (sizeof *writer);
+  writer->taint = taint_create ();
+  writer->case_cnt = 0;
+  writer->class = class;
+  writer->aux = aux;
+  return writer;
 }
 
-struct casereader *
-casewriter_make_reader (struct casewriter *writer)
-{
-  struct casereader *reader;
-  reader = writer->class->convert_to_reader (writer, writer->private);
-  taint_propagate (writer->taint, casereader_get_taint (reader));
-  taint_destroy (writer->taint);
-  free (writer);
-  return reader;
-}
+/* Returns a casewriter for cases with VALUE_CNT struct values
+   per case.  The cases written to the casewriter will be kept in
+   memory, unless the amount of memory used grows too large, in
+   which case they will be written to disk.
 
-static const struct casewriter_class casewriter_window_class;
-static const struct buffered_reader_class casereader_window_class;
+   A casewriter created with this function may be passed to
+   casewriter_make_reader. 
 
-static struct casewriter *
-create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases) 
+   This is usually the right kind of casewriter to use. */
+struct casewriter *
+autopaging_writer_create (size_t value_cnt) 
 {
-  struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
-  struct casewriter *writer = casewriter_create (&casewriter_window_class,
-                                                 window);
-  taint_propagate (casewindow_get_taint (window),
-                   casewriter_get_taint (writer));
-  return writer;
+  return create_casewriter_window (value_cnt, get_workspace_cases (value_cnt));
 }
 
+/* Returns a casewriter for cases with VALUE_CNT struct values
+   per case.  The cases written to the casewriter will be kept in
+   memory.
+
+   A casewriter created with this function may be passed to
+   casewriter_make_reader. */
 struct casewriter *
 mem_writer_create (size_t value_cnt) 
 {
   return create_casewriter_window (value_cnt, CASENUMBER_MAX);
 }
 
+/* Returns a casewriter for cases with VALUE_CNT struct values
+   per case.  The cases written to the casewriter will be written
+   to disk.
+
+   A casewriter created with this function may be passed to
+   casewriter_make_reader. */
 struct casewriter *
 tmpfile_writer_create (size_t value_cnt) 
 {
   return create_casewriter_window (value_cnt, 0);
 }
 
-struct casewriter *
-autopaging_writer_create (size_t value_cnt) 
+static const struct casewriter_class casewriter_window_class;
+static const struct buffered_reader_class casereader_window_class;
+
+/* Creates and returns a new casewriter based on a casewindow.
+   Each of the casewriter's cases are composed of VALUE_CNT
+   struct values.  The casewriter's cases will be maintained in
+   memory until MAX_IN_CORE_CASES have been written, at which
+   point they will be written to disk. */
+static struct casewriter *
+create_casewriter_window (size_t value_cnt, casenumber max_in_core_cases) 
 {
-  return create_casewriter_window (value_cnt, get_workspace_cases (value_cnt));
+  struct casewindow *window = casewindow_create (value_cnt, max_in_core_cases);
+  struct casewriter *writer = casewriter_create (&casewriter_window_class,
+                                                 window);
+  taint_propagate (casewindow_get_taint (window),
+                   casewriter_get_taint (writer));
+  return writer;
 }
 
+/* Writes case C to casewindow writer WINDOW. */
 static void
 casewriter_window_write (struct casewriter *writer UNUSED, void *window_,
                          struct ccase *c) 
@@ -149,6 +215,7 @@
   casewindow_push_head (window, c);
 }
 
+/* Destroys casewindow writer WINDOW. */
 static void
 casewriter_window_destroy (struct casewriter *writer UNUSED, void *window_)
 {
@@ -156,6 +223,8 @@
   casewindow_destroy (window);
 }
 
+/* Converts casewindow writer WINDOW to a casereader and returns
+   the casereader. */
 static struct casereader *
 casewriter_window_convert_to_reader (struct casewriter *writer UNUSED,
                                      void *window_) 
@@ -167,16 +236,20 @@
                                  &casereader_window_class, window);
 }
 
+/* Reads the case at the given 0-based OFFSET from the front of
+   WINDOW into C.  Returns true if successful, false if
+   OFFSET is beyond the end of file or upon I/O error. */
 static bool
-casereader_window_read (void *window_, casenumber case_idx, struct ccase *c) 
+casereader_window_read (void *window_, casenumber offset, struct ccase *c) 
 {
   struct casewindow *window = window_;
-  if (case_idx >= casewindow_get_case_cnt (window))
+  if (offset >= casewindow_get_case_cnt (window))
     return false;
   else
-    return casewindow_get_case (window, case_idx, c);
+    return casewindow_get_case (window, offset, c);
 }
 
+/* Destroys casewindow reader WINDOW. */
 static void
 casereader_window_destroy (void *window_)
 {
@@ -184,6 +257,7 @@
   casewindow_destroy (window);
 }
 
+/* Discards CASE_CNT cases from the front of WINDOW. */
 static void
 casereader_window_advance (void *window_, casenumber case_cnt) 
 {
@@ -191,6 +265,7 @@
   casewindow_pop_tail (window, case_cnt);
 }
 
+/* Class for casewindow writer. */
 static const struct casewriter_class casewriter_window_class = 
   {
     casewriter_window_write,
@@ -198,6 +273,7 @@
     casewriter_window_convert_to_reader,
   };
 
+/* Class for casewindow reader. */
 static const struct buffered_reader_class casereader_window_class = 
   {
     casereader_window_read,
@@ -205,60 +281,3 @@
     casereader_window_advance,
   };
 
-struct casewriter_translator
-  {
-    struct casewriter *subwriter;
-
-    void (*translate) (const struct ccase *input, struct ccase *output,
-                       void *aux);
-    bool (*destroy) (void *aux);
-    void *aux;
-  };
-
-static struct casewriter_class casewriter_translator_class;
-
-struct casewriter *
-casewriter_create_translator (struct casewriter *subwriter,
-                              void (*translate) (const struct ccase *input,
-                                                 struct ccase *output,
-                                                 void *aux),
-                              bool (*destroy) (void *aux),
-                              void *aux) 
-{
-  struct casewriter_translator *ct = xmalloc (sizeof *ct);
-  struct casewriter *writer;
-  ct->subwriter = casewriter_rename (subwriter);
-  ct->translate = translate;
-  ct->destroy = destroy;
-  ct->aux = aux;
-  writer = casewriter_create (&casewriter_translator_class, ct);
-  taint_propagate (casewriter_get_taint (ct->subwriter),
-                   casewriter_get_taint (writer));
-  return writer;
-}
-
-static void
-casewriter_translator_write (struct casewriter *writer UNUSED,
-                             void *ct_, struct ccase *c) 
-{
-  struct casewriter_translator *ct = ct_;
-  struct ccase tmp;
-
-  ct->translate (c, &tmp, ct->aux);
-  casewriter_write (ct->subwriter, &tmp);
-}
-
-static void
-casewriter_translator_destroy (struct casewriter *writer UNUSED, void *ct_) 
-{
-  struct casewriter_translator *ct = ct_;
-  casewriter_destroy (ct->subwriter);
-  ct->destroy (ct->aux);
-  free (ct);
-}
-
-static struct casewriter_class casewriter_translator_class = 
-  {
-    casewriter_translator_write,
-    casewriter_translator_destroy,
-  };

Index: data/casewriter-private.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casewriter-private.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -b -r1.1.2.2 -r1.1.2.3
--- data/casewriter-private.h   4 May 2007 03:48:47 -0000       1.1.2.2
+++ data/casewriter-private.h   7 May 2007 04:38:39 -0000       1.1.2.3
@@ -23,12 +23,38 @@
 
 struct casewriter_class 
   {
-    /* Mandatory. */
-    /* Ownership of the case is transferred to the callee. */
-    void (*write) (struct casewriter *, void *aux, struct ccase *);
-    void (*destroy) (struct casewriter *, void *aux);
+    /* Mandatory.
 
-    /* Optional. */
+       Writes case C to WRITER.  Destroys C before returning.
+
+       If an I/O error occurs, this function should call
+       casewriter_force_error on WRITER.  Some I/O error
+       detection may be deferred to the "destroy" member function
+       (e.g. writes to disk need not be flushed by "write") . */
+    void (*write) (struct casewriter *writer, void *aux, struct ccase *c);
+
+    /* Mandatory.
+
+       Finalizes output and destroys WRITER.
+
+       If an I/O error is detected while finalizing output
+       (e.g. while flushing output to disk), this function should
+       call casewriter_force_error on WRITER. */
+    void (*destroy) (struct casewriter *writer, void *aux);
+
+    /* Optional: supply if practical and desired by clients.
+
+       Finalizes output to WRITER, destroys WRITER, and in its
+       place returns a casereader that can be used to read back
+       the data written to WRITER.  WRITER will not be used again
+       after calling this function, even as an argument to
+       casewriter_destroy.
+
+       If an I/O error is detected while finalizing output
+       (e.g. while flushing output to disk), this function should
+       call casewriter_force_error on WRITER.  The caller will
+       ensure that the error is propagated to the returned
+       casereader. */
     struct casereader *(*convert_to_reader) (struct casewriter *, void *aux);
   };
 

Index: data/casereader.c
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casereader.c,v
retrieving revision 1.1.2.6
retrieving revision 1.1.2.7
diff -u -b -r1.1.2.6 -r1.1.2.7
--- data/casereader.c   6 May 2007 22:48:27 -0000       1.1.2.6
+++ data/casereader.c   7 May 2007 04:38:39 -0000       1.1.2.7
@@ -163,6 +163,8 @@
         insert_casereader_buffer (reader);
       if (reader->class->peek (reader, reader->aux, idx, c))
         return true;
+      else if (casereader_error (reader)) 
+        reader->case_cnt = 0;
     }
   if (reader->case_cnt > idx)
     reader->case_cnt = idx;
@@ -390,10 +392,10 @@
 
 /* Discards CNT cases from the front of B's window. */
 static void
-casereader_buffer_advance (void *b_, casenumber cnt)
+casereader_buffer_advance (void *b_, casenumber case_cnt)
 {
   struct casereader_buffer *b = b_;
-  casewindow_pop_tail (b->window, cnt);
+  casewindow_pop_tail (b->window, case_cnt);
 }
 
 /* Class for the buffered reader. */

Index: data/casereader-private.h
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/Attic/casereader-private.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -b -r1.1.2.2 -r1.1.2.3
--- data/casereader-private.h   4 May 2007 03:48:47 -0000       1.1.2.2
+++ data/casereader-private.h   7 May 2007 04:38:39 -0000       1.1.2.3
@@ -24,20 +24,69 @@
 /* This header file should really be renamed: it's not really
    private. */
 
+/* Casereader class. */
 struct casereader_class 
   {
-    /* Mandatory. */
-    bool (*read) (struct casereader *, void *aux, struct ccase *);
-    void (*destroy) (struct casereader *, void *aux);
-
-    /* Optional.  If convenient and efficiently implementable,
-       supply as an optimization for use by casereader_clone. */
-    struct casereader *(*clone) (struct casereader *, void *aux);
-
-    /* Optional.  If convenient and efficiently implementable,
-       supply as an optimization for use by casereader_peek. */
-    bool (*peek) (struct casereader *, void *aux, casenumber idx,
-                  struct ccase *);
+    /* Mandatory.
+
+       Reads the next case from READER into case C, which the
+       casereader must create and which the client is responsible
+       for destroying.  If successful, returns true and advances
+       READER to the next case, so that the next call to this
+       function will read the next case.  The case just read will
+       never be read again by a call to this function for READER.
+
+       At end of file or upon an I/O error, returns false.  After
+       false is returned once, this function will not be called
+       again for the given READER.
+
+       If an I/O error occurs, this function should call
+       casereader_force_error on READER. */
+    bool (*read) (struct casereader *reader, void *aux, struct ccase *c);
+
+    /* Mandatory.
+
+       Destroys READER.
+
+       If an I/O error is detected during destruction, this
+       function should call casereader_force_error on READER. */
+    void (*destroy) (struct casereader *reader, void *aux);
+
+    /* Optional: if convenient and efficiently implementable,
+       supply this function as an optimization for use by
+       casereader_clone.
+
+       Creates and returns a clone of READER.  The clone must
+       read the same case data in the same sequence as READER,
+       starting from the same position.  The only allowable
+       exception to this rule is that I/O errors may force the
+       clone or the original casereader to stop reading after
+       differing numbers of cases.
+
+       The clone should have a clone of READER's taint object,
+       accomplished by passing casereader_get_taint (READER) to
+       casereader_create. */
+    struct casereader *(*clone) (struct casereader *reader, void *aux);
+
+    /* Optional: if convenient and efficiently implementable,
+       supply as an optimization for use by casereader_peek.
+
+       Reads the case at 0-based offset IDX from the beginning of
+       READER into case C, which the casereader must create and
+       which the client is responsible for destroying.
+
+       At end of file or upon an I/O error, returns false.  If
+       this function returns false, then it will never be called
+       again for an equal or greater value of IDX, and the "read"
+       member function will never be called to advance as far as
+       IDX cases further into the casereader.  That is, returning
+       false indicates that the casereader has fewer than IDX
+       cases left.
+
+       If an I/O error occurs, this function should call
+       casereader_force_error on READER. */
+    bool (*peek) (struct casereader *reader, void *aux, casenumber idx,
+                  struct ccase *c);
   };
 
 struct casereader *casereader_create (const struct taint *,

Index: data/automake.mk
===================================================================
RCS file: /cvsroot/pspp/pspp/src/data/automake.mk,v
retrieving revision 1.15.2.3
retrieving revision 1.15.2.4
diff -u -b -r1.15.2.3 -r1.15.2.4
--- data/automake.mk    6 May 2007 22:48:27 -0000       1.15.2.3
+++ data/automake.mk    7 May 2007 04:38:39 -0000       1.15.2.4
@@ -27,6 +27,7 @@
        src/data/casewindow.c \
        src/data/casewindow.h \
        src/data/casewriter.c \
+       src/data/casewriter-translator.c \
        src/data/casewriter.h \
        src/data/casewriter-private.h \
        src/data/category.c \

Index: data/casewriter-translator.c
===================================================================
RCS file: data/casewriter-translator.c
diff -N data/casewriter-translator.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ data/casewriter-translator.c        7 May 2007 04:38:39 -0000       1.1.2.1
@@ -0,0 +1,86 @@
+/* PSPP - computes sample statistics.
+   Copyright (C) 2007 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 the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA. */
+
+#include <config.h>
+
+#include <data/casewriter.h>
+#include <data/casewriter-private.h>
+
+#include <stdlib.h>
+
+#include <libpspp/taint.h>
+
+#include "xalloc.h"
+
+struct casewriter_translator
+  {
+    struct casewriter *subwriter;
+
+    void (*translate) (const struct ccase *input, struct ccase *output,
+                       void *aux);
+    bool (*destroy) (void *aux);
+    void *aux;
+  };
+
+static struct casewriter_class casewriter_translator_class;
+
+struct casewriter *
+casewriter_create_translator (struct casewriter *subwriter,
+                              void (*translate) (const struct ccase *input,
+                                                 struct ccase *output,
+                                                 void *aux),
+                              bool (*destroy) (void *aux),
+                              void *aux) 
+{
+  struct casewriter_translator *ct = xmalloc (sizeof *ct);
+  struct casewriter *writer;
+  ct->subwriter = casewriter_rename (subwriter);
+  ct->translate = translate;
+  ct->destroy = destroy;
+  ct->aux = aux;
+  writer = casewriter_create (&casewriter_translator_class, ct);
+  taint_propagate (casewriter_get_taint (ct->subwriter),
+                   casewriter_get_taint (writer));
+  return writer;
+}
+
+static void
+casewriter_translator_write (struct casewriter *writer UNUSED,
+                             void *ct_, struct ccase *c) 
+{
+  struct casewriter_translator *ct = ct_;
+  struct ccase tmp;
+
+  ct->translate (c, &tmp, ct->aux);
+  casewriter_write (ct->subwriter, &tmp);
+}
+
+static void
+casewriter_translator_destroy (struct casewriter *writer UNUSED, void *ct_) 
+{
+  struct casewriter_translator *ct = ct_;
+  casewriter_destroy (ct->subwriter);
+  ct->destroy (ct->aux);
+  free (ct);
+}
+
+static struct casewriter_class casewriter_translator_class = 
+  {
+    casewriter_translator_write,
+    casewriter_translator_destroy,
+  };




reply via email to

[Prev in Thread] Current Thread [Next in Thread]