X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcasefile.c;h=d81ec29efa0a2c9d331ea08114e6b4be8986aaa4;hb=13a7d7fb2c398784b25f7f5f363c3fd86dc93eed;hp=95e0388c4e8733ed74b6a3e89ebd780a0dbbe771;hpb=57b436a22d9ae0e395fb2e3ce101c2b5c2e6939e;p=pspp-builds.git diff --git a/src/data/casefile.c b/src/data/casefile.c index 95e0388c..d81ec29e 100644 --- a/src/data/casefile.c +++ b/src/data/casefile.c @@ -1,6 +1,5 @@ /* PSPP - computes sample statistics. - Copyright (C) 2004, 2006 Free Software Foundation, Inc. - Written by Ben Pfaff . + Copyright (C) 2004, 2006, 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 @@ -26,6 +25,7 @@ #include "case.h" #include "casefile.h" #include "casefile-private.h" +#include "casefilter.h" struct ccase; @@ -116,6 +116,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 +141,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 = 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; @@ -144,19 +157,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) ; - 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); @@ -173,6 +185,22 @@ casereader_destroy (struct casereader *r) 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) @@ -213,10 +241,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); @@ -245,7 +274,7 @@ casefile_get_destructive_reader (struct casefile *cf) bool casefile_append (struct casefile *cf, const struct ccase *c) { - assert (c->case_data->value_cnt >= casefile_get_value_cnt (cf)); + assert (case_get_value_cnt (c) >= casefile_get_value_cnt (cf)); return cf->class->append(cf, c); } @@ -256,7 +285,7 @@ casefile_append (struct casefile *cf, const struct ccase *c) bool casefile_append_xfer (struct casefile *cf, struct ccase *c) { - assert (c->case_data->value_cnt >= casefile_get_value_cnt (cf)); + assert (case_get_value_cnt (c) >= casefile_get_value_cnt (cf)); cf->class->append (cf, c); case_destroy (c);