Add casereaders and casewriters, the basis of the new data processing
[pspp-builds.git] / src / data / casereader-translator.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 2007 Free Software Foundation, Inc.
3
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.
8
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.
13
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
17    02110-1301, USA. */
18
19 #include <config.h>
20
21 #include <data/casereader.h>
22
23 #include <stdlib.h>
24
25 #include <data/casereader-provider.h>
26 #include <libpspp/taint.h>
27
28 #include "xalloc.h"
29
30 struct casereader_translator
31   {
32     struct casereader *subreader;
33
34     void (*translate) (const struct ccase *input, struct ccase *output,
35                        void *aux);
36     bool (*destroy) (void *aux);
37     void *aux;
38   };
39
40 static struct casereader_class casereader_translator_class;
41
42 struct casereader *
43 casereader_create_translator (struct casereader *subreader,
44                               size_t output_value_cnt,
45                               void (*translate) (const struct ccase *input,
46                                                  struct ccase *output,
47                                                  void *aux),
48                               bool (*destroy) (void *aux),
49                               void *aux) 
50 {
51   struct casereader_translator *ct = xmalloc (sizeof *ct);
52   struct casereader *reader;
53   ct->subreader = casereader_rename (subreader);
54   ct->translate = translate;
55   ct->destroy = destroy;
56   ct->aux = aux;
57   reader = casereader_create_sequential (
58     NULL, output_value_cnt, casereader_get_case_cnt (ct->subreader),
59     &casereader_translator_class, ct);
60   taint_propagate (casereader_get_taint (ct->subreader),
61                    casereader_get_taint (reader));
62   return reader;
63 }
64
65 static bool
66 casereader_translator_read (struct casereader *reader UNUSED,
67                             void *ct_, struct ccase *c) 
68 {
69   struct casereader_translator *ct = ct_;
70   struct ccase tmp;
71
72   if (casereader_read (ct->subreader, &tmp)) 
73     {
74       ct->translate (&tmp, c, ct->aux);
75       return true; 
76     }
77   else
78     return false;
79 }
80
81 static void
82 casereader_translator_destroy (struct casereader *reader UNUSED, void *ct_) 
83 {
84   struct casereader_translator *ct = ct_;
85   casereader_destroy (ct->subreader);
86   ct->destroy (ct->aux);
87   free (ct);
88 }
89
90 static struct casereader_class casereader_translator_class = 
91   {
92     casereader_translator_read,
93     casereader_translator_destroy,
94     NULL,
95     NULL,
96   };