1 /* PSPP - computes sample statistics.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <data/casereader.h>
25 #include <data/casereader-provider.h>
26 #include <libpspp/taint.h>
30 /* Casereader that applies a user-supplied function to translate
31 each case into another in an arbitrary fashion. */
33 /* A translating casereader. */
34 struct casereader_translator
36 struct casereader *subreader; /* Source of input cases. */
38 void (*translate) (const struct ccase *input, struct ccase *output,
40 bool (*destroy) (void *aux);
44 static struct casereader_class casereader_translator_class;
46 /* Creates and returns a new casereader whose cases are produced
47 by reading from SUBREADER and passing through TRANSLATE, which
48 must create case OUTPUT, with OUTPUT_VALUE_CNT values, and
49 populate it based on INPUT and auxiliary data AUX. TRANSLATE
50 must also destroy INPUT.
52 When the translating casereader is destroyed, DESTROY will be
53 called to allow any state maintained by TRANSLATE to be freed.
55 After this function is called, SUBREADER must not ever again
56 be referenced directly. It will be destroyed automatically
57 when the translating casereader is destroyed. */
59 casereader_create_translator (struct casereader *subreader,
60 size_t output_value_cnt,
61 void (*translate) (const struct ccase *input,
64 bool (*destroy) (void *aux),
67 struct casereader_translator *ct = xmalloc (sizeof *ct);
68 struct casereader *reader;
69 ct->subreader = casereader_rename (subreader);
70 ct->translate = translate;
71 ct->destroy = destroy;
73 reader = casereader_create_sequential (
74 NULL, output_value_cnt, casereader_get_case_cnt (ct->subreader),
75 &casereader_translator_class, ct);
76 taint_propagate (casereader_get_taint (ct->subreader),
77 casereader_get_taint (reader));
81 /* Internal read function for translating casereader. */
83 casereader_translator_read (struct casereader *reader UNUSED,
84 void *ct_, struct ccase *c)
86 struct casereader_translator *ct = ct_;
89 if (casereader_read (ct->subreader, &tmp))
91 ct->translate (&tmp, c, ct->aux);
98 /* Internal destroy function for translating casereader. */
100 casereader_translator_destroy (struct casereader *reader UNUSED, void *ct_)
102 struct casereader_translator *ct = ct_;
103 casereader_destroy (ct->subreader);
104 ct->destroy (ct->aux);
108 /* Casereader class for translating casereader. */
109 static struct casereader_class casereader_translator_class =
111 casereader_translator_read,
112 casereader_translator_destroy,