Remove "Written by Ben Pfaff <blp@gnu.org>" lines everywhere.
[pspp-builds.git] / src / data / storage-stream.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000, 2006 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/storage-stream.h>
22
23 #include <assert.h>
24 #include <stdlib.h>
25
26 #include <data/case-sink.h>
27 #include <data/case-source.h>
28 #include <data/case.h>
29 #include <data/casefile.h> 
30 #include <data/fastfile.h> 
31
32 #include "xalloc.h"
33
34 /* Information about storage sink or source. */
35 struct storage_stream_info 
36   {
37     struct casefile *casefile;  /* Storage. */
38   };
39 \f
40 /* Storage sink. */
41
42 /* Initializes a storage sink. */
43 static void
44 storage_sink_open (struct case_sink *sink)
45 {
46   struct storage_stream_info *info;
47
48   sink->aux = info = xmalloc (sizeof *info);
49   info->casefile = fastfile_create (sink->value_cnt);
50 }
51
52 /* Destroys storage stream represented by INFO. */
53 static void
54 destroy_storage_stream_info (struct storage_stream_info *info) 
55 {
56   if (info != NULL) 
57     {
58       casefile_destroy (info->casefile);
59       free (info); 
60     }
61 }
62
63 /* Writes case C to the storage sink SINK.
64    Returns true if successful, false if an I/O error occurred. */
65 static bool
66 storage_sink_write (struct case_sink *sink, const struct ccase *c)
67 {
68   struct storage_stream_info *info = sink->aux;
69
70   return casefile_append (info->casefile, c);
71 }
72
73 /* Destroys internal data in SINK. */
74 static void
75 storage_sink_destroy (struct case_sink *sink)
76 {
77   destroy_storage_stream_info (sink->aux);
78 }
79
80 /* Closes the sink and returns a storage source to read back the
81    written data. */
82 static struct case_source *
83 storage_sink_make_source (struct case_sink *sink) 
84 {
85   struct case_source *source
86     = create_case_source (&storage_source_class, sink->aux);
87   sink->aux = NULL;
88   return source;
89 }
90
91 /* Storage sink. */
92 const struct case_sink_class storage_sink_class = 
93   {
94     "storage",
95     storage_sink_open,
96     storage_sink_write,
97     storage_sink_destroy,
98     storage_sink_make_source,
99   };
100 \f
101 /* Storage source. */
102
103 /* Returns the number of cases that will be read by
104    storage_source_read(). */
105 static int
106 storage_source_count (const struct case_source *source) 
107 {
108   struct storage_stream_info *info = source->aux;
109
110   return casefile_get_case_cnt (info->casefile);
111 }
112
113 /* Reads all cases from the storage source and passes them one by one to
114    write_case(). */
115 static bool
116 storage_source_read (struct case_source *source,
117                      struct ccase *output_case,
118                      write_case_func *write_case, write_case_data wc_data)
119 {
120   struct storage_stream_info *info = source->aux;
121   struct ccase casefile_case;
122   struct casereader *reader;
123   bool ok = true;
124
125   for (reader = casefile_get_reader (info->casefile, NULL);
126        ok && casereader_read (reader, &casefile_case);
127        case_destroy (&casefile_case))
128     {
129       case_copy (output_case, 0,
130                  &casefile_case, 0,
131                  casefile_get_value_cnt (info->casefile));
132       ok = write_case (wc_data);
133     }
134   casereader_destroy (reader);
135
136   return ok;
137 }
138
139 /* Destroys the source's internal data. */
140 static void
141 storage_source_destroy (struct case_source *source)
142 {
143   destroy_storage_stream_info (source->aux);
144 }
145
146 /* Storage source. */
147 const struct case_source_class storage_source_class = 
148   {
149     "storage",
150     storage_source_count,
151     storage_source_read,
152     storage_source_destroy,
153   };
154
155 /* Returns the casefile encapsulated by SOURCE. */
156 struct casefile *
157 storage_source_get_casefile (struct case_source *source) 
158 {
159   struct storage_stream_info *info = source->aux;
160
161   assert (source->class == &storage_source_class);
162   return info->casefile;
163 }
164
165 /* Destroys SOURCE and returns the casefile that it
166    encapsulated. */
167 struct casefile *
168 storage_source_decapsulate (struct case_source *source) 
169 {
170   struct storage_stream_info *info = source->aux;
171   struct casefile *casefile;
172
173   assert (source->class == &storage_source_class);
174   casefile = info->casefile;
175   info->casefile = NULL;
176   free_case_source (source);
177   return casefile;
178 }
179
180 /* Creates and returns a new storage stream that encapsulates
181    CASEFILE. */
182 struct case_source *
183 storage_source_create (struct casefile *casefile)
184 {
185   struct storage_stream_info *info;
186
187   info = xmalloc (sizeof *info);
188   info->casefile = casefile;
189
190   return create_case_source (&storage_source_class, info);
191 }