X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcasefile.c;h=ba45063349174e7dd69cca23bab3b10d87d86d0f;hb=f43378497b8400e9c22a3485c534693dc1bc9554;hp=e6c6fa676baa35e3315f94c9a080f9f9fbced1f2;hpb=1959a8562768999654fb385a5f8892a0c3a69f93;p=pspp-builds.git diff --git a/src/data/casefile.c b/src/data/casefile.c index e6c6fa67..ba450633 100644 --- a/src/data/casefile.c +++ b/src/data/casefile.c @@ -26,6 +26,7 @@ #include "case.h" #include "casefile.h" #include "casefile-private.h" +#include "casefilter.h" struct ccase; @@ -116,6 +117,24 @@ casereader_cnum(const struct casereader *r) 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. @@ -123,16 +142,11 @@ casereader_cnum(const struct casereader *r) bool casereader_read (struct casereader *reader, struct ccase *c) { - struct casefile *cf = casereader_get_casefile (reader); - - struct ccase *read_case = NULL; + struct ccase * read_case = get_next_case (reader) ; - 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; @@ -144,20 +158,18 @@ casereader_read (struct casereader *reader, struct ccase *c) 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) ; - case_nullify (c); - 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); @@ -178,10 +190,16 @@ casereader_destroy (struct casereader *r) struct casereader * casereader_clone(const struct casereader *r) { + struct casereader *r2; + /* Would we ever want to clone a destructive reader ?? */ assert ( ! r->destructive ) ; - return r->class->clone (r); + r2 = r->class->clone (r); + + r2->filter = r->filter; + + return r2; } /* Destroys casefile CF. */ @@ -224,10 +242,11 @@ casefile_get_value_cnt (const 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);