X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fcasereader.c;h=8b78645627e1243f4efb875612b97eac2666cc70;hb=c90c44ab307b3ba49f606d2bae80e6aff1e228d7;hp=3c062d9068b6355ace4f8e3caf005b89cd7c25ad;hpb=d908f52b818f4fdf2ab23797756812ec2986bd2b;p=pspp diff --git a/src/data/casereader.c b/src/data/casereader.c index 3c062d9068..8b78645627 100644 --- a/src/data/casereader.c +++ b/src/data/casereader.c @@ -1,20 +1,18 @@ -/* PSPP - computes sample statistics. +/* PSPP - a program for statistical analysis. 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 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 3 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. + 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. */ + along with this program. If not, see . */ #include @@ -58,19 +56,30 @@ static void insert_shim (struct casereader *); bool casereader_read (struct casereader *reader, struct ccase *c) { - if (reader->case_cnt != 0 && reader->class->read (reader, reader->aux, c)) + if (reader->case_cnt != 0) { - assert (case_get_value_cnt (c) == reader->value_cnt); + /* ->read may use casereader_swap to replace itself by + another reader and then delegate to that reader by + recursively calling casereader_read. Currently only + lazy_casereader does this and, with luck, nothing else + ever will. + + To allow this to work, however, we must decrement + case_cnt before calling ->read. If we decremented + case_cnt after calling ->read, then this would actually + drop two cases from case_cnt instead of one, and we'd + lose the last case in the casereader. */ if (reader->case_cnt != CASENUMBER_MAX) reader->case_cnt--; - return true; - } - else - { - reader->case_cnt = 0; - case_nullify (c); - return false; + if (reader->class->read (reader, reader->aux, c)) + { + assert (case_get_value_cnt (c) >= reader->value_cnt); + return true; + } } + reader->case_cnt = 0; + case_nullify (c); + return false; } /* Destroys READER. @@ -313,6 +322,26 @@ casereader_create_sequential (const struct taint *taint, reader->aux = aux; return reader; } + +/* If READER is a casereader of the given CLASS, returns its + associated auxiliary data; otherwise, returns a null pointer. + + This function is intended for use from casereader + implementations, not by casereader users. Even within + casereader implementations, its usefulness is quite limited, + for at least two reasons. First, every casereader member + function already receives a pointer to the casereader's + auxiliary data. Second, a casereader's class can change + (through a call to casereader_swap) and this is in practice + quite common (e.g. any call to casereader_clone on a + casereader that does not directly support clone will cause the + casereader to be replaced by a shim caseader). */ +void * +casereader_dynamic_cast (struct casereader *reader, + struct casereader_class *class) +{ + return reader->class == class ? reader->aux : NULL; +} /* Random-access casereader implementation.