]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
New module 'fd-ostream': Output stream referring to a file descriptor.
authorBruno Haible <bruno@clisp.org>
Tue, 7 Nov 2006 14:46:06 +0000 (14:46 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:14:20 +0000 (12:14 +0200)
gnulib-local/lib/fd-ostream.oo.c [new file with mode: 0644]
gnulib-local/lib/fd-ostream.oo.h [new file with mode: 0644]
gnulib-local/modules/fd-ostream [new file with mode: 0644]

diff --git a/gnulib-local/lib/fd-ostream.oo.c b/gnulib-local/lib/fd-ostream.oo.c
new file mode 100644 (file)
index 0000000..06a9e44
--- /dev/null
@@ -0,0 +1,170 @@
+/* Output stream referring to a file descriptor.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "fd-ostream.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "error.h"
+#include "exit.h"
+#include "full-write.h"
+#include "xalloc.h"
+#include "gettext.h"
+
+#define _(str) gettext (str)
+
+struct fd_ostream : struct ostream
+{
+fields:
+  int fd;
+  char *filename;
+  char *buffer;                        /* A buffer, or NULL.  */
+  size_t avail;                        /* Number of bytes available in the buffer.  */
+};
+
+#define BUFSIZE 4096
+
+/* Implementation of ostream_t methods.  */
+
+static void
+fd_ostream::write_mem (fd_ostream_t stream, const void *data, size_t len)
+{
+  if (len > 0)
+    {
+      if (stream->buffer != NULL)
+       {
+         /* Buffered.  */
+         assert (stream->avail > 0);
+         #if 0 /* unoptimized */
+         do
+           {
+             size_t n = (len <= stream->avail ? len : stream->avail);
+             if (n > 0)
+               {
+                 memcpy (stream->buffer + BUFSIZE - stream->avail, data, n);
+                 data = (char *) data + n;
+                 stream->avail -= n;
+                 len -= n;
+               }
+             if (stream->avail == 0)
+               {
+                 if (full_write (stream->fd, stream->buffer, BUFSIZE) < BUFSIZE)
+                   error (EXIT_FAILURE, errno, _("error writing to %s"),
+                          stream->filename);
+                 stream->avail = BUFSIZE;
+               }
+           }
+         while (len > 0);
+         #else /* optimized */
+         if (len < stream->avail)
+           {
+             /* Move the data into the buffer.  */
+             memcpy (stream->buffer + BUFSIZE - stream->avail, data, len);
+             stream->avail -= len;
+           }
+         else
+           {
+             /* Split the data into:
+                  - a first chunk, which is added to the buffer and output,
+                  - a series of chunks of size BUFSIZE, which can be output
+                    directly, without going through the buffer, and
+                  - a last chunk, which is copied to the buffer.  */
+             size_t n = stream->avail;
+             memcpy (stream->buffer + BUFSIZE - stream->avail, data, n);
+             data = (char *) data + n;
+             len -= n;
+             if (full_write (stream->fd, stream->buffer, BUFSIZE) < BUFSIZE)
+               error (EXIT_FAILURE, errno, _("error writing to %s"),
+                      stream->filename);
+
+             while (len >= BUFSIZE)
+               {
+                 if (full_write (stream->fd, data, BUFSIZE) < BUFSIZE)
+                   error (EXIT_FAILURE, errno, _("error writing to %s"),
+                          stream->filename);
+                 data = (char *) data + BUFSIZE;
+                 len -= BUFSIZE;
+               }
+
+             if (len > 0)
+               memcpy (stream->buffer, data, len);
+             stream->avail = BUFSIZE - len;
+           }
+         #endif
+         assert (stream->avail > 0);
+       }
+      else
+       {
+         /* Unbuffered.  */
+         if (full_write (stream->fd, data, len) < len)
+           error (EXIT_FAILURE, errno, _("error writing to %s"),
+                  stream->filename);
+       }
+    }
+}
+
+static void
+fd_ostream::flush (fd_ostream_t stream)
+{
+  if (stream->buffer != NULL && stream->avail < BUFSIZE)
+    {
+      size_t filled = BUFSIZE - stream->avail;
+      if (full_write (stream->fd, stream->buffer, filled) < filled)
+       error (EXIT_FAILURE, errno, _("error writing to %s"), stream->filename);
+      stream->avail = BUFSIZE;
+    }
+}
+
+static void
+fd_ostream::free (fd_ostream_t stream)
+{
+  fd_ostream_flush (stream);
+  free (stream->filename);
+  free (stream);
+}
+
+/* Constructor.  */
+
+fd_ostream_t
+fd_ostream_create (int fd, const char *filename, bool buffered)
+{
+  fd_ostream_t stream =
+    (struct fd_ostream_representation *)
+    xmalloc (sizeof (struct fd_ostream_representation)
+            + (buffered ? BUFSIZE : 0));
+
+  stream->base.vtable = &fd_ostream_vtable;
+  stream->fd = fd;
+  stream->filename = xstrdup (filename);
+  if (buffered)
+    {
+      stream->buffer =
+       (char *) (void *) stream + sizeof (struct fd_ostream_representation);
+      stream->avail = BUFSIZE;
+    }
+  else
+    stream->buffer = NULL;
+
+  return stream;
+}
diff --git a/gnulib-local/lib/fd-ostream.oo.h b/gnulib-local/lib/fd-ostream.oo.h
new file mode 100644 (file)
index 0000000..c9495f5
--- /dev/null
@@ -0,0 +1,49 @@
+/* Output stream referring to a file descriptor.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _FD_OSTREAM_H
+#define _FD_OSTREAM_H
+
+#include <stdbool.h>
+
+#include "ostream.h"
+
+
+struct fd_ostream : struct ostream
+{
+methods:
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Create an output stream referring to the file descriptor FD.
+   FILENAME is used only for error messages.
+   Note that the resulting stream must be closed before FD can be closed.  */
+extern fd_ostream_t fd_ostream_create (int fd, const char *filename,
+                                      bool buffered);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FD_OSTREAM_H */
diff --git a/gnulib-local/modules/fd-ostream b/gnulib-local/modules/fd-ostream
new file mode 100644 (file)
index 0000000..1ac8af4
--- /dev/null
@@ -0,0 +1,33 @@
+Description:
+Output stream referring to a file descriptor.
+
+Files:
+lib/fd-ostream.oo.h
+lib/fd-ostream.oo.c
+
+Depends-on:
+ostream
+error
+exit
+full-write
+gettext
+xalloc
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += fd-ostream.c
+fd-ostream.h fd-ostream.c : $(top_srcdir)/build-aux/moopp fd-ostream.oo.h fd-ostream.oo.c ostream.oo.h
+       $(top_srcdir)/build-aux/moopp $(srcdir)/fd-ostream.oo.c $(srcdir)/fd-ostream.oo.h $(srcdir)/ostream.oo.h
+BUILT_SOURCES += fd-ostream.h fd-ostream.c fd_ostream.priv.h fd_ostream.vt.h
+CLEANFILES += fd-ostream.h fd-ostream.c fd_ostream.priv.h fd_ostream.vt.h
+
+Include:
+"fd-ostream.h"
+
+License:
+GPL
+
+Maintainer:
+Bruno Haible
+