#include "data/casewriter.h"
#include "data/dictionary.h"
#include "data/file-handle-def.h"
-#include "data/file-name.h"
#include "data/format.h"
#include "data/make-file.h"
#include "data/missing-values.h"
#include "data/short-names.h"
#include "data/value-labels.h"
#include "data/variable.h"
+#include "libpspp/fbuf.h"
#include "libpspp/float-format.h"
#include "libpspp/i18n.h"
#include "libpspp/integer-format.h"
{
struct file_handle *fh; /* File handle. */
struct fh_lock *lock; /* Mutual exclusion for file. */
- FILE *file; /* File stream. */
+ struct fbuf *fbuf; /* File stream. */
struct replace_file *rf; /* Ticket for replacing output file. */
enum any_compression compression;
w = xzalloc (sizeof *w);
w->fh = fh_ref (fh);
w->lock = NULL;
- w->file = NULL;
+ w->fbuf = NULL;
w->rf = NULL;
/* Use the requested compression, except that no EBCDIC-based ZLIB compressed
mode = 0444;
if (opts.create_writeable)
mode |= 0222;
- w->rf = replace_file_start (fh, "wb", mode, &w->file, NULL);
+
+ int fd;
+ w->rf = replace_file_start_fd (fh, true, mode, &fd);
if (w->rf == NULL)
{
msg (ME, _("Error opening `%s' for writing as a system file: %s."),
fh_get_file_name (fh), strerror (errno));
goto error;
}
+ w->fbuf = fbuf_open_fd (fd);
get_encoding_info (&encoding_info, dict_get_encoding (d));
w->space = encoding_info.space[0];
w->zstream.zalloc = Z_NULL;
w->zstream.zfree = Z_NULL;
w->zstream.opaque = Z_NULL;
- w->zstart = ftello (w->file);
+ w->zstart = fbuf_tell (w->fbuf);
write_int64 (w, w->zstart);
write_int64 (w, 0);
{
const char *dict_encoding = dict_get_encoding (d);
char prod_name[61];
- char creation_date[10];
- char creation_time[9];
const char *file_label;
struct variable *weight;
write_float (w, COMPRESSION_BIAS);
/* Creation date and time. */
+ char *creation_date, *creation_time;
if (time (&t) == (time_t) -1)
{
- strcpy (creation_date, "01 Jan 70");
- strcpy (creation_time, "00:00:00");
+ creation_date = xstrdup ("01 Jan 70");
+ creation_time = xstrdup ( "00:00:00");
}
else
{
int min = rerange (tmp->tm_min + 1);
int sec = rerange (tmp->tm_sec + 1);
- snprintf (creation_date, sizeof creation_date,
- "%02d %s %02d", day, month_name[mon - 1], year);
- snprintf (creation_time, sizeof creation_time,
- "%02d:%02d:%02d", hour - 1, min - 1, sec - 1);
+ creation_date = xasprintf ("%02d %s %02d",
+ day, month_name[mon - 1], year);
+ creation_time = xasprintf ("%02d:%02d:%02d", hour - 1, min - 1, sec - 1);
}
write_utf8_string (w, dict_encoding, creation_date, 9);
write_utf8_string (w, dict_encoding, creation_time, 8);
+ free (creation_time);
+ free (creation_date);
/* File label. */
file_label = dict_get_label (d);
struct attrset_iterator i;
for (attr = attrset_first (attrs, &i); attr != NULL;
- attr = attrset_next (attrs, &i))
+ attr = attrset_next (attrs, &i))
{
size_t n_values = attribute_get_n_values (attr);
size_t j;
ds_put_cstr (string, attribute_get_name (attr));
ds_put_byte (string, '(');
- for (j = 0; j < n_values; j++)
+ for (j = 0; j < n_values; j++)
ds_put_format (string, "'%s'\n", attribute_get_value (attr, j));
ds_put_byte (string, ')');
}
size_t i;
for (i = 0; i < n_vars; i++)
- {
+ {
struct variable *v = dict_get_var (d, i);
struct attrset attrs;
write_int (w, 1); /* Data item (byte) size. */
write_int (w, size); /* Number of data items. */
- start = ftello (w->file);
+ start = fbuf_tell (w->fbuf);
for (i = 0; i < n_vars; i++)
{
struct variable *var = dict_get_var (dict, i);
free (label);
}
}
- assert (ftello (w->file) == start + size);
+ assert (fbuf_tell (w->fbuf) == start + size);
}
static void
write_int (w, 1); /* Data item (byte) size. */
write_int (w, size); /* Number of data items. */
- start = ftello (w->file);
+ start = fbuf_tell (w->fbuf);
for (i = 0; i < n_vars; i++)
{
struct variable *var = dict_get_var (dict, i);
write_bytes (w, value_str (value, width), 8);
}
}
- assert (ftello (w->file) == start + size);
+ assert (fbuf_tell (w->fbuf) == start + size);
}
static void
{
struct sfm_writer *w = w_;
- if (ferror (w->file))
+ if (fbuf_get_status (w->fbuf) > 0)
{
casewriter_force_error (writer);
case_unref (c);
static bool
write_error (const struct sfm_writer *writer)
{
- return ferror (writer->file);
+ return fbuf_get_status (writer->fbuf) > 0;
}
/* Closes a system file after we're done with it.
return true;
ok = true;
- if (w->file != NULL)
+ if (w->fbuf != NULL)
{
/* Flush buffer. */
flush_compressed (w);
finish_zstream (w);
write_ztrailer (w);
}
- fflush (w->file);
+ fbuf_flush (w->fbuf);
ok = !write_error (w);
/* Seek back to the beginning and update the number of cases.
This is just a courtesy to later readers, so there's no need
to check return values or report errors. */
- if (ok && w->case_cnt <= INT32_MAX && !fseeko (w->file, 80, SEEK_SET))
+ if (ok && w->case_cnt <= INT32_MAX && !fbuf_seek (w->fbuf, 80))
{
write_int (w, w->case_cnt);
- clearerr (w->file);
+ fbuf_clear_status (w->fbuf);
}
- if (fclose (w->file) == EOF)
+ if (fbuf_close (w->fbuf) != 0)
ok = false;
if (!ok)
block = &w->blocks[w->n_blocks++];
block->uncompressed_size = w->zstream.total_in;
block->compressed_size = w->zstream.total_out;
+ deflateEnd (&w->zstream);
}
static void
compressed_ofs += block->compressed_size;
}
- if (!fseeko (w->file, w->zstart + 8, SEEK_SET))
+ if (!fbuf_seek (w->fbuf, w->zstart + 8))
{
write_int64 (w, compressed_ofs);
write_int64 (w, 24 + (w->n_blocks * 24));
size_t pad_bytes = width - data_bytes;
write_bytes (w, string, data_bytes);
while (pad_bytes-- > 0)
- putc (w->space, w->file);
+ fbuf_putc (w->fbuf, w->space);
}
/* Recodes null-terminated UTF-8 encoded STRING into ENCODING, and writes the
static void
write_bytes (struct sfm_writer *w, const void *data, size_t size)
{
- fwrite (data, 1, size, w->file);
+ fbuf_write (w->fbuf, data, size);
}
/* Writes N zeros to W's output file. */
write_zeros (struct sfm_writer *w, size_t n)
{
while (n-- > 0)
- putc (0, w->file);
+ fbuf_putc (w->fbuf, 0);
}
/* Writes N spaces to W's output file. */
write_spaces (struct sfm_writer *w, size_t n)
{
while (n-- > 0)
- putc (w->space, w->file);
+ fbuf_putc (w->fbuf, w->space);
}