1 /* PSPP - computes sample statistics.
2 Copyright (C) 2006 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
20 #include "any-writer.h"
26 #include <libpspp/assertion.h>
27 #include <libpspp/message.h>
28 #include "file-handle-def.h"
29 #include "file-name.h"
30 #include "por-file-writer.h"
31 #include "sys-file-writer.h"
32 #include <libpspp/str.h>
33 #include "scratch-writer.h"
37 #define _(msgid) gettext (msgid)
39 /* Type of file backing an any_writer. */
42 SYSTEM_FILE, /* System file. */
43 PORTABLE_FILE, /* Portable file. */
44 SCRATCH_FILE /* Scratch file. */
47 /* Writer for any type of case-structured file. */
50 enum any_writer_type type; /* Type of file. */
51 void *private; /* Private data. */
54 /* Creates and returns a writer for HANDLE with the given DICT. */
56 any_writer_open (struct file_handle *handle, struct dictionary *dict)
58 switch (fh_get_referent (handle))
62 struct any_writer *writer;
65 extension = fn_extension (fh_get_file_name (handle));
66 str_lowercase (extension);
68 if (!strcmp (extension, ".por"))
69 writer = any_writer_from_pfm_writer (
70 pfm_open_writer (handle, dict, pfm_writer_default_options ()));
72 writer = any_writer_from_sfm_writer (
73 sfm_open_writer (handle, dict, sfm_writer_default_options ()));
80 msg (ME, _("The inline file is not allowed here."));
84 return any_writer_from_scratch_writer (scratch_writer_open (handle,
91 /* If PRIVATE is non-null, creates and returns a new any_writer,
92 initializing its fields to TYPE and PRIVATE. If PRIVATE is a
93 null pointer, just returns a null pointer. */
94 static struct any_writer *
95 make_any_writer (enum any_writer_type type, void *private)
99 struct any_writer *writer = xmalloc (sizeof *writer);
101 writer->private = private;
108 /* If SFM_WRITER is non-null, encapsulates SFM_WRITER in an
109 any_writer and returns it. If SFM_WRITER is null, just
110 returns a null pointer.
112 Useful when you need to pass options to sfm_open_writer().
114 any_writer_from_sfm_writer (sfm_open_writer (fh, dict, opts))
115 If you don't need to pass options, then any_writer_open() by
116 itself is easier and more straightforward. */
118 any_writer_from_sfm_writer (struct sfm_writer *sfm_writer)
120 return make_any_writer (SYSTEM_FILE, sfm_writer);
123 /* If PFM_WRITER is non-null, encapsulates PFM_WRITER in an
124 any_writer and returns it. If PFM_WRITER is null, just
125 returns a null pointer.
127 Useful when you need to pass options to pfm_open_writer().
129 any_writer_from_pfm_writer (pfm_open_writer (fh, dict, opts))
130 If you don't need to pass options, then any_writer_open() by
131 itself is easier and more straightforward. */
133 any_writer_from_pfm_writer (struct pfm_writer *pfm_writer)
135 return make_any_writer (PORTABLE_FILE, pfm_writer);
138 /* If SCRATCH_WRITER is non-null, encapsulates SCRATCH_WRITER in
139 an any_writer and returns it. If SCRATCH_WRITER is null, just
140 returns a null pointer.
142 Not particularly useful. Included just for consistency. */
144 any_writer_from_scratch_writer (struct scratch_writer *scratch_writer)
146 return make_any_writer (SCRATCH_FILE, scratch_writer);
149 /* Writes cases C to WRITER.
150 Returns true if successful, false on failure. */
152 any_writer_write (struct any_writer *writer, const struct ccase *c)
154 switch (writer->type)
157 return sfm_write_case (writer->private, c);
160 return pfm_write_case (writer->private, c);
163 return scratch_writer_write_case (writer->private, c);
168 /* Returns true if an I/O error has occurred on WRITER, false
171 any_writer_error (const struct any_writer *writer)
173 switch (writer->type)
176 return sfm_write_error (writer->private);
179 return pfm_write_error (writer->private);
182 return scratch_writer_error (writer->private);
188 Returns true if successful, false if an I/O error occurred. */
190 any_writer_close (struct any_writer *writer)
197 switch (writer->type)
200 ok = sfm_close_writer (writer->private);
204 ok = pfm_close_writer (writer->private);
208 ok = scratch_writer_close (writer->private);