summaryrefslogtreecommitdiff
path: root/snprintfv/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'snprintfv/stream.c')
-rw-r--r--snprintfv/stream.c226
1 files changed, 226 insertions, 0 deletions
diff --git a/snprintfv/stream.c b/snprintfv/stream.c
new file mode 100644
index 0000000..a979f33
--- /dev/null
+++ b/snprintfv/stream.c
@@ -0,0 +1,226 @@
+/* -*- Mode: C -*- */
+
+/* stream.c --- customizable stream routines
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003 Gary V. Vaughan
+ * Originally by Gary V. Vaughan, 1998
+ * This file is part of Snprintfv
+ *
+ * Snprintfv 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 of the
+ * License, or (at your option) any later version.
+ *
+ * Snprintfv 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.
+ *
+ * As a special exception to the GNU General Public License, if you
+ * distribute this file as part of a program that also links with and
+ * uses the libopts library from AutoGen, you may include it under
+ * the same distribution terms used by the libopts library.
+ */
+
+/* Code: */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef WITH_DMALLOC
+# include <dmalloc.h>
+#endif
+
+#include "compat.h"
+#include "stream.h"
+#include "mem.h"
+
+struct stream
+{
+ snv_pointer stream;
+ unsigned long limit;
+
+ StreamGet get_func;
+ StreamPut put_func;
+};
+
+static int
+stream_not_readable (STREAM *stream)
+{
+ (void)stream;
+ return -1;
+}
+
+static int
+stream_not_writable (int ch, STREAM *stream)
+{
+ (void)stream;
+ (void)ch;
+ return -1;
+}
+
+/**
+ * stream_new: constructor
+ * @dets: user supplied stream details to be passed into the various funcs.
+ * @limit: the maximum number of consecutive bytes to fit in @dets.
+ * @get_func: function to get a character from @dets stream.
+ * @put_func: function to put a character in @dets stream.
+ *
+ * Allocate and initialize a new %STREAM data type. The @get_func
+ * and @put_func can be NULL if you intend to create a non-readable
+ * or non-writable stream, respectively.
+ *
+ * Return value:
+ * The address of the newly allocated and initialised stream is returned.
+ **/
+STREAM *
+stream_new (snv_pointer dets, unsigned long limit, StreamGet get_func, StreamPut put_func)
+{
+ STREAM *new = snv_new (STREAM, 1);
+
+ new->stream = dets;
+ new->limit = limit;
+
+ new->get_func = get_func ? get_func : stream_not_readable;
+ new->put_func = put_func ? put_func : stream_not_writable;
+
+ return new;
+}
+
+
+/**
+ * stream_delete: destructor
+ * @stream: The stream pending deletion
+ *
+ * The memory associated with @stream is recycled.
+
+ * Return value:
+ * The %dets supplied by the user when the stream was created are
+ * returned for handling by the calling function.
+ **/
+snv_pointer
+stream_delete (STREAM *stream)
+{
+ snv_pointer dets = stream->stream;
+ snv_delete (stream);
+ return dets;
+}
+
+/**
+ * stream_details:
+ * @stream: the stream being queried.
+ *
+ * The finalization function specified when @stream was created (if any)
+ * is called, and then the memory associated with @stream is recycled.
+ * It is the responsibility of the finalization function to recycle, or
+ * otherwise manage, any memory associated with the user supplied %dets.
+ * Return value:
+ * This function returns the stream details associated with @stream
+ * when it was originally created.
+ **/
+snv_pointer
+stream_details (STREAM *stream)
+{
+ return stream ? stream->stream : NULL;
+}
+
+/**
+ * stream_put:
+ * @ch: A single character to be placed in @stream.
+ * @stream: The stream to be written to.
+ *
+ * This function will @ch in @stream if that stream's output limit will
+ * not be exceeded.
+ *
+ * Return value:
+ * If @stream is full, return 1. Otherwise, if any other error occurs,
+ * that error code is returned unchanged. This is of course dependant
+ * on what the handler function uses to indicate an error. If the stream
+ * is not full and the stream's writing function succeeds, 1 (the number of
+ * characters emitted!) is returned.
+ **/
+int
+stream_put (int ch, STREAM *stream)
+{
+ int ch_or_errorcode;
+
+ if (!stream)
+ return -1;
+
+ if (stream->limit < 1)
+ return 1;
+
+ stream->limit -= 1;
+ ch_or_errorcode = (*stream->put_func) ((unsigned char) ch, stream);
+
+ return (ch_or_errorcode < 0) ? ch_or_errorcode : 1;
+}
+
+/**
+ * stream_puts:
+ * @s: A string to be placed in @stream.
+ * @stream: The stream to be written to.
+ *
+ * This function will @ch in @stream if that stream's output limit will
+ * not be exceeded.
+ *
+ * Return value:
+ * If any other error occurs, that error code is returned unchanged.
+ * This is of course dependant on what the handler function uses to
+ * indicate an error. If the stream becomes full, the remaining
+ * characters are not printed. If the stream's writing function
+ * always succeeds, the number of characters emitted or skipped is
+ * returned.
+ **/
+int
+stream_puts (char *s, STREAM *stream)
+{
+ int ch_or_errorcode;
+ int num;
+
+ if (!stream)
+ return -1;
+
+ for (num = 0; *s; num++, s++)
+ {
+ if (stream->limit < 1)
+ return num + strlen (s);
+
+ stream->limit -= 1;
+ ch_or_errorcode = (*stream->put_func) ((unsigned char) *s, stream);
+
+ if (ch_or_errorcode < 0)
+ return ch_or_errorcode;
+ }
+
+ return num;
+}
+
+/**
+ * stream_get:
+ * @stream: The stream to be read from.
+ *
+ * This function will try to read a single character from @stream.
+ *
+ * Return value:
+ * If an error occurs or the end of @stream is reached, -1 is returned.
+ * Under normal circumstances the value if the character read (cast to
+ * an int) is returned.
+ **/
+int
+stream_get (STREAM *stream)
+{
+ return (*stream->get_func) (stream);
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "gnu"
+ * indent-tabs-mode: nil
+ * End:
+ * end of snprintfv/stream.c */