Write message to status bar on saving syntax files
[pspp-builds.git] / src / data / casewriter-translator.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2007 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU 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, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include <data/casewriter.h>
20 #include <data/casewriter-provider.h>
21
22 #include <stdlib.h>
23
24 #include <libpspp/taint.h>
25
26 #include "xalloc.h"
27
28 struct casewriter_translator
29   {
30     struct casewriter *subwriter;
31
32     void (*translate) (struct ccase *input, struct ccase *output, void *aux);
33     bool (*destroy) (void *aux);
34     void *aux;
35   };
36
37 static const struct casewriter_class casewriter_translator_class;
38
39 /* Creates and returns a new casewriter whose cases are passed
40    through TRANSLATE, which must create case OUTPUT, with
41    OUTPUT_VALUE_CNT values, and populate it based on INPUT and
42    auxiliary data AUX.  The translated cases are then written to
43    SUBWRITER.  TRANSLATE must also destroy INPUT.
44
45    When the translating casewriter is destroyed, DESTROY will be
46    called to allow any state maintained by TRANSLATE to be freed.
47
48    After this function is called, SUBWRITER must not ever again
49    be referenced directly.  It will be destroyed automatically
50    when the translating casewriter is destroyed. */
51 struct casewriter *
52 casewriter_create_translator (struct casewriter *subwriter,
53                               size_t translated_value_cnt,
54                               void (*translate) (struct ccase *input,
55                                                  struct ccase *output,
56                                                  void *aux),
57                               bool (*destroy) (void *aux),
58                               void *aux)
59 {
60   struct casewriter_translator *ct = xmalloc (sizeof *ct);
61   struct casewriter *writer;
62   ct->subwriter = casewriter_rename (subwriter);
63   ct->translate = translate;
64   ct->destroy = destroy;
65   ct->aux = aux;
66   writer = casewriter_create (translated_value_cnt,
67                               &casewriter_translator_class, ct);
68   taint_propagate (casewriter_get_taint (ct->subwriter),
69                    casewriter_get_taint (writer));
70   return writer;
71 }
72
73 static void
74 casewriter_translator_write (struct casewriter *writer UNUSED,
75                              void *ct_, struct ccase *c)
76 {
77   struct casewriter_translator *ct = ct_;
78   struct ccase tmp;
79
80   ct->translate (c, &tmp, ct->aux);
81   casewriter_write (ct->subwriter, &tmp);
82 }
83
84 static void
85 casewriter_translator_destroy (struct casewriter *writer UNUSED, void *ct_)
86 {
87   struct casewriter_translator *ct = ct_;
88   casewriter_destroy (ct->subwriter);
89   ct->destroy (ct->aux);
90   free (ct);
91 }
92
93 static struct casereader *
94 casewriter_translator_convert_to_reader (struct casewriter *writer UNUSED,
95                                          void *ct_)
96 {
97   struct casewriter_translator *ct = ct_;
98   struct casereader *reader = casewriter_make_reader (ct->subwriter);
99   free (ct);
100   ct->destroy (ct->aux);
101   return reader;
102 }
103
104 static const struct casewriter_class casewriter_translator_class =
105   {
106     casewriter_translator_write,
107     casewriter_translator_destroy,
108     casewriter_translator_convert_to_reader,
109   };