From 93f8f57386093a80e28042de6db226bc010e9e49 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 5 Dec 2009 20:19:58 -0800 Subject: [PATCH] casereader: New function casereader_select(). --- src/data/automake.mk | 1 + src/data/casereader-select.c | 81 ++++++++++++++++++++++++++++++++++++ src/data/casereader.h | 4 ++ 3 files changed, 86 insertions(+) create mode 100644 src/data/casereader-select.c diff --git a/src/data/automake.mk b/src/data/automake.mk index 3edfce62..ebfb680a 100644 --- a/src/data/automake.mk +++ b/src/data/automake.mk @@ -27,6 +27,7 @@ src_data_libdata_la_SOURCES = \ src/data/casereader-filter.c \ src/data/casereader-project.c \ src/data/casereader-provider.h \ + src/data/casereader-select.c \ src/data/casereader-translator.c \ src/data/casereader.c \ src/data/casereader.h \ diff --git a/src/data/casereader-select.c b/src/data/casereader-select.c new file mode 100644 index 00000000..a26ef674 --- /dev/null +++ b/src/data/casereader-select.c @@ -0,0 +1,81 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2009 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 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include + +#include "gl/xalloc.h" + +struct casereader_select + { + casenumber by; + casenumber i; + }; + +static bool +casereader_select_include (const struct ccase *c UNUSED, void *cs_) +{ + struct casereader_select *cs = cs_; + if (++cs->i >= cs->by) + { + cs->i = 0; + return true; + } + else + return false; +} + +static bool +casereader_select_destroy (void *cs_) +{ + struct casereader_select *cs = cs_; + free (cs); + return true; +} + +/* Returns a casereader that contains cases FIRST though LAST, exclusive, of + those within SUBREADER. (The first case in SUBREADER is number 0.) If BY + is greater than 1, then it specifies a step between cases, e.g. a BY value + of 2 causes the cases numbered FIRST + 1, FIRST + 3, FIRST + 5, and so on + to be omitted. + + The caller gives up ownership of SUBREADER, transferring it into this + function. */ +struct casereader * +casereader_select (struct casereader *subreader, + casenumber first, casenumber last, casenumber by) +{ + if (by == 0) + by = 1; + + casereader_advance (subreader, first); + if (last >= first) + casereader_truncate (subreader, (last - first) / by * by); + + if (by == 1) + return casereader_rename (subreader); + else + { + struct casereader_select *cs = xmalloc (sizeof *cs); + cs->by = by; + cs->i = 0; + return casereader_create_filter_func (subreader, + casereader_select_include, + casereader_select_destroy, + cs, NULL); + } +} diff --git a/src/data/casereader.h b/src/data/casereader.h index 62dc4e91..a78afaeb 100644 --- a/src/data/casereader.h +++ b/src/data/casereader.h @@ -129,6 +129,10 @@ casereader_translate_stateless (struct casereader *, struct casereader *casereader_project (struct casereader *, const struct subcase *); struct casereader *casereader_project_1 (struct casereader *, int column); +struct casereader *casereader_select (struct casereader *, + casenumber first, casenumber last, + casenumber by); + /* A function which creates a numberic value from an existing case */ typedef double new_value_func (const struct ccase *, casenumber, void *); -- 2.30.2