/* PSPP - computes sample statistics.
Copyright (C) 2004, 2006 Free Software Foundation, Inc.
- Written by Ben Pfaff <blp@gnu.org>.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "case.h"
#include "casefile.h"
#include "casefile-private.h"
+#include "casefilter.h"
struct ccase;
return r->class->cnum(r);
}
+static struct ccase *
+get_next_case(struct casereader *reader)
+{
+ struct ccase *read_case = NULL;
+ struct casefile *cf = casereader_get_casefile (reader);
+
+ do
+ {
+ if ( casefile_error (cf) )
+ return NULL;
+
+ read_case = reader->class->get_next_case (reader);
+ }
+ while ( read_case && reader->filter
+ && casefilter_skip_case (reader->filter, read_case) ) ;
+
+ return read_case;
+}
/* Reads a copy of the next case from READER into C.
Caller is responsible for destroying C.
bool
casereader_read (struct casereader *reader, struct ccase *c)
{
- struct casefile *cf = casereader_get_casefile (reader);
+ struct ccase * read_case = get_next_case (reader) ;
- struct ccase *read_case = NULL;
-
- if ( casefile_error (cf) )
+ if ( NULL == read_case )
return false;
- read_case = reader->class->get_next_case (reader);
- if ( ! read_case ) return false;
-
case_clone (c, read_case );
return true;
Returns true if successful, false at end of file or on I/O
error. */
bool
-casereader_read_xfer (struct casereader *ffr, struct ccase *c)
+casereader_read_xfer (struct casereader *reader, struct ccase *c)
{
- struct casefile *cf = casereader_get_casefile (ffr);
+ struct casefile *cf = casereader_get_casefile (reader);
+ struct ccase *read_case ;
+ case_nullify (c);
- struct ccase *read_case = NULL ;
+ read_case = get_next_case (reader) ;
- if ( casefile_error (cf) )
+ if ( NULL == read_case )
return false;
- read_case = ffr->class->get_next_case (ffr);
- if ( ! read_case ) return false;
-
- if ( ffr->destructive && casefile_in_core (cf) )
+ if ( reader->destructive && casefile_in_core (cf) )
case_move (c, read_case);
else
case_clone (c, read_case);
r->class->destroy(r);
}
+/* Creates a copy of R and returns it */
+struct casereader *
+casereader_clone(const struct casereader *r)
+{
+ struct casereader *r2;
+
+ /* Would we ever want to clone a destructive reader ?? */
+ assert ( ! r->destructive ) ;
+
+ r2 = r->class->clone (r);
+
+ r2->filter = r->filter;
+
+ return r2;
+}
+
/* Destroys casefile CF. */
void
casefile_destroy(struct casefile *cf)
/* Creates and returns a casereader for CF. A casereader can be used to
sequentially read the cases in a casefile. */
struct casereader *
-casefile_get_reader (const struct casefile *cf)
+casefile_get_reader (const struct casefile *cf, struct casefilter *filter)
{
struct casereader *r = cf->class->get_reader(cf);
r->cf = (struct casefile *) cf;
+ r->filter = filter;
assert (r->class);