casereader: New function casereader_select(). fc11-i386-build48 fc11-x64-build45 lenny-x64-build69 sid-i386-build116
authorBen Pfaff <blp@gnu.org>
Sun, 6 Dec 2009 04:19:58 +0000 (20:19 -0800)
committerBen Pfaff <blp@gnu.org>
Sun, 6 Dec 2009 04:19:58 +0000 (20:19 -0800)
src/data/automake.mk
src/data/casereader-select.c [new file with mode: 0644]
src/data/casereader.h

index 3edfce6265dd978e2a509f61654994ec92849c81..ebfb680a09316b0a0fa486067616d77153cf5fcb 100644 (file)
@@ -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 (file)
index 0000000..a26ef67
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <data/casereader-provider.h>
+
+#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);
+    }
+}
index 62dc4e9176a0798f03222802b6dfb2d82d81bd46..a78afaeb27096974107ff1b17409e43318929e37 100644 (file)
@@ -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 *);