1 /* PSPP - computes sample statistics.
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "any-writer.h"
27 #include <libpspp/assertion.h>
28 #include <libpspp/message.h>
29 #include "file-handle-def.h"
30 #include "file-name.h"
31 #include "por-file-writer.h"
32 #include "sys-file-writer.h"
33 #include <libpspp/str.h>
34 #include "scratch-writer.h"
38 #define _(msgid) gettext (msgid)
40 /* Type of file backing an any_writer. */
43 SYSTEM_FILE, /* System file. */
44 PORTABLE_FILE, /* Portable file. */
45 SCRATCH_FILE /* Scratch file. */
48 /* Writer for any type of case-structured file. */
51 enum any_writer_type type; /* Type of file. */
52 void *private; /* Private data. */
55 /* Creates and returns a writer for HANDLE with the given DICT. */
57 any_writer_open (struct file_handle *handle, struct dictionary *dict)
59 switch (fh_get_referent (handle))
63 struct any_writer *writer;
66 extension = fn_extension (fh_get_file_name (handle));
67 str_lowercase (extension);
69 if (!strcmp (extension, ".por"))
70 writer = any_writer_from_pfm_writer (
71 pfm_open_writer (handle, dict, pfm_writer_default_options ()));
73 writer = any_writer_from_sfm_writer (
74 sfm_open_writer (handle, dict, sfm_writer_default_options ()));
81 msg (ME, _("The inline file is not allowed here."));
85 return any_writer_from_scratch_writer (scratch_writer_open (handle,
92 /* If PRIVATE is non-null, creates and returns a new any_writer,
93 initializing its fields to TYPE and PRIVATE. If PRIVATE is a
94 null pointer, just returns a null pointer. */
95 static struct any_writer *
96 make_any_writer (enum any_writer_type type, void *private)
100 struct any_writer *writer = xmalloc (sizeof *writer);
102 writer->private = private;
109 /* If SFM_WRITER is non-null, encapsulates SFM_WRITER in an
110 any_writer and returns it. If SFM_WRITER is null, just
111 returns a null pointer.
113 Useful when you need to pass options to sfm_open_writer().
115 any_writer_from_sfm_writer (sfm_open_writer (fh, dict, opts))
116 If you don't need to pass options, then any_writer_open() by
117 itself is easier and more straightforward. */
119 any_writer_from_sfm_writer (struct sfm_writer *sfm_writer)
121 return make_any_writer (SYSTEM_FILE, sfm_writer);
124 /* If PFM_WRITER is non-null, encapsulates PFM_WRITER in an
125 any_writer and returns it. If PFM_WRITER is null, just
126 returns a null pointer.
128 Useful when you need to pass options to pfm_open_writer().
130 any_writer_from_pfm_writer (pfm_open_writer (fh, dict, opts))
131 If you don't need to pass options, then any_writer_open() by
132 itself is easier and more straightforward. */
134 any_writer_from_pfm_writer (struct pfm_writer *pfm_writer)
136 return make_any_writer (PORTABLE_FILE, pfm_writer);
139 /* If SCRATCH_WRITER is non-null, encapsulates SCRATCH_WRITER in
140 an any_writer and returns it. If SCRATCH_WRITER is null, just
141 returns a null pointer.
143 Not particularly useful. Included just for consistency. */
145 any_writer_from_scratch_writer (struct scratch_writer *scratch_writer)
147 return make_any_writer (SCRATCH_FILE, scratch_writer);
150 /* Writes cases C to WRITER.
151 Returns true if successful, false on failure. */
153 any_writer_write (struct any_writer *writer, const struct ccase *c)
155 switch (writer->type)
158 return sfm_write_case (writer->private, c);
161 return pfm_write_case (writer->private, c);
164 return scratch_writer_write_case (writer->private, c);
169 /* Returns true if an I/O error has occurred on WRITER, false
172 any_writer_error (const struct any_writer *writer)
174 switch (writer->type)
177 return sfm_write_error (writer->private);
180 return pfm_write_error (writer->private);
183 return scratch_writer_error (writer->private);
189 Returns true if successful, false if an I/O error occurred. */
191 any_writer_close (struct any_writer *writer)
198 switch (writer->type)
201 ok = sfm_close_writer (writer->private);
205 ok = pfm_close_writer (writer->private);
209 ok = scratch_writer_close (writer->private);