[balsa] Add the new libnetclient files to the repo



commit 5ddce7604062cdfbeb84cb4f72bd241f2076d4b9
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Thu Jun 7 09:07:28 2018 -0400

    Add the new libnetclient files to the repo
    
    Must have forgotten to add them with the previous commit!

 libbalsa/imap/siobuf-nc.h        |  34 +++++
 libnetclient/net-client-siobuf.c | 305 +++++++++++++++++++++++++++++++++++++++
 libnetclient/net-client-siobuf.h | 184 +++++++++++++++++++++++
 3 files changed, 523 insertions(+)
---
diff --git a/libbalsa/imap/siobuf-nc.h b/libbalsa/imap/siobuf-nc.h
new file mode 100644
index 00000000..80ec7b24
--- /dev/null
+++ b/libbalsa/imap/siobuf-nc.h
@@ -0,0 +1,34 @@
+/*
+ * siobuf-nc.h
+ * libnetclient <--> libbalsa/imap glue layer
+ * Written by (C) Albrecht Dreß <mailto:albrecht dress arcor de> 2018
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBBALSA_IMAP_SIOBUF_NC_H_
+#define LIBBALSA_IMAP_SIOBUF_NC_H_
+
+#include "net-client-siobuf.h"
+
+
+#define sio_read(sio, bufp, buflen)                    net_client_siobuf_read(sio, bufp, buflen, NULL)
+#define sio_getc(sio)                                          net_client_siobuf_getc(sio, NULL)
+#define sio_ungetc(sio)                                                net_client_siobuf_ungetc(sio)
+#define sio_gets(sio, buf, buflen)                     net_client_siobuf_gets(sio, buf, buflen, NULL)
+#define sio_write(sio, buf, buflen)                    net_client_siobuf_write(sio, buf, buflen)
+#define sio_printf(sio, format, ...)           net_client_siobuf_printf(sio, format, ##__VA_ARGS__)
+
+
+#endif /* LIBBALSA_IMAP_SIOBUF_NC_H_ */
diff --git a/libnetclient/net-client-siobuf.c b/libnetclient/net-client-siobuf.c
new file mode 100644
index 00000000..ea82b9a2
--- /dev/null
+++ b/libnetclient/net-client-siobuf.c
@@ -0,0 +1,305 @@
+/* NetClient - simple line-based network client library
+ *
+ * Copyright (C) Albrecht Dreß <mailto:albrecht dress arcor de> 2018
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 
General Public License
+ * as published by the Free Software Foundation; either version 3 of the License, or (at your option) any 
later version.
+ *
+ * This library 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 Lesser General Public License for more 
details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library. If not, 
see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib/gi18n.h>
+#include "net-client-utils.h"
+#include "net-client-siobuf.h"
+
+
+struct _NetClientSioBufPrivate {
+       GString *buffer;                /**< hold a line read from the remote server, including the 
terminating CRLF */
+       gchar *read_ptr;                /**< point to the next char which shall be read in buffer's 
GString::str. */
+       GString *writebuf;              /**< buffer for buffered write functions */
+};
+
+
+G_DEFINE_TYPE(NetClientSioBuf, net_client_siobuf, NET_CLIENT_TYPE)
+
+
+static void net_client_siobuf_finalise(GObject *object);
+static gboolean net_client_siobuf_fill(NetClientSioBuf *client, GError **error);
+
+
+NetClientSioBuf *
+net_client_siobuf_new(const gchar *host, guint16 port)
+{
+       NetClientSioBuf *client;
+
+       g_return_val_if_fail(host != NULL, NULL);
+
+       client = NET_CLIENT_SIOBUF(g_object_new(NET_CLIENT_SIOBUF_TYPE, NULL));
+       if (client != NULL) {
+               if (!net_client_configure(NET_CLIENT(client), host, port, 0, NULL)) {
+                       g_object_unref(G_OBJECT(client));
+                       client = NULL;
+               } else {
+                       client->priv->buffer = g_string_sized_new(1024U);
+                       client->priv->read_ptr = NULL;
+                       client->priv->writebuf = g_string_sized_new(1024U);
+               }
+       }
+
+       return client;
+}
+
+
+gint
+net_client_siobuf_read(NetClientSioBuf *client, void *buffer, gsize count, GError **error)
+{
+       NetClientSioBufPrivate *priv;
+       gboolean fill_res;
+       gchar *dest;
+       gsize left;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client) && (buffer != NULL) && (count > 0U), -1);
+
+       priv = client->priv;
+       dest = (gchar *) buffer;
+       left = count;
+       fill_res = net_client_siobuf_fill(client, error);
+       while (fill_res && (left > 0U)) {
+               gsize avail;
+               gsize chunk;
+
+               avail = priv->buffer->len - (priv->read_ptr - priv->buffer->str);
+               if (avail > left) {
+                       chunk = left;
+               } else {
+                       chunk = avail;
+               }
+
+               memcpy(dest, priv->read_ptr, chunk);
+               dest += chunk;
+               priv->read_ptr += chunk;
+               left -= chunk;
+               if (left > 0U) {
+                       fill_res = net_client_siobuf_fill(client, error);
+               }
+       }
+
+       return (left < count) ? (gint) (count - left) : -1;
+}
+
+
+gint
+net_client_siobuf_getc(NetClientSioBuf *client, GError **error)
+{
+       gint retval;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client), -1);
+
+       if (net_client_siobuf_fill(client, error)) {
+               retval = *client->priv->read_ptr++;
+       } else {
+               retval = -1;
+       }
+       return retval;
+}
+
+
+gint
+net_client_siobuf_ungetc(NetClientSioBuf *client)
+{
+       NetClientSioBufPrivate *priv;
+       gint retval;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client), -1);
+
+       priv = client->priv;
+       if ((priv->buffer->len != 0U) && (priv->read_ptr > priv->buffer->str)) {
+               priv->read_ptr--;
+               retval = 0;
+       } else {
+               retval = -1;
+       }
+       return retval;
+}
+
+
+gchar *
+net_client_siobuf_gets(NetClientSioBuf *client, gchar *buffer, gsize buflen, GError **error)
+{
+       NetClientSioBufPrivate *priv;
+       gchar *result;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client) && (buffer != NULL) && (buflen > 0U), NULL);
+
+       priv = client->priv;
+       if (net_client_siobuf_fill(client, error)) {
+               gsize avail;
+               gsize chunk;
+
+               avail = priv->buffer->len - (priv->read_ptr - priv->buffer->str);
+               if (avail > (buflen - 1U)) {
+                       chunk = buflen - 1U;
+               } else {
+                       chunk = avail;
+               }
+               memcpy(buffer, priv->read_ptr, chunk);
+               priv->read_ptr += chunk;
+               buffer[chunk] = '\0';
+               result = buffer;
+       } else {
+               result = NULL;
+       }
+
+       return result;
+}
+
+
+gchar *
+net_client_siobuf_get_line(NetClientSioBuf *client, GError **error)
+{
+       NetClientSioBufPrivate *priv;
+       gchar *result;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client), NULL);
+
+       priv = client->priv;
+       if (net_client_siobuf_fill(client, error)) {
+               gsize avail;
+
+               avail = priv->buffer->len - (priv->read_ptr - priv->buffer->str);
+               if (avail > 2U) {
+                       result = g_strndup(priv->read_ptr, avail - 2U);
+               } else {
+                       result = g_strdup("");
+               }
+               priv->buffer->len = 0U;
+       } else {
+               result = NULL;
+       }
+
+       return result;
+}
+
+
+gint
+net_client_siobuf_discard_line(NetClientSioBuf *client, GError **error)
+{
+       gint result;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client), -1);
+
+       if (net_client_siobuf_fill(client, error)) {
+               client->priv->buffer->len = 0U;
+               result = '\n';
+       } else {
+               result = -1;
+       }
+
+       return result;
+}
+
+
+void
+net_client_siobuf_write(NetClientSioBuf *client, const void *buffer, gsize count)
+{
+       g_return_if_fail(NET_IS_CLIENT_SIOBUF(client) && (buffer != NULL) && (count > 0U));
+
+       g_string_append_len(client->priv->writebuf, (const gchar *) buffer, count);
+}
+
+
+void
+net_client_siobuf_printf(NetClientSioBuf *client, const gchar *format, ...)
+{
+       va_list args;
+
+       g_return_if_fail(NET_IS_CLIENT_SIOBUF(client) && (format != NULL));
+
+       va_start(args, format);
+       g_string_append_vprintf(client->priv->writebuf, format, args);
+       va_end(args);
+}
+
+
+gboolean
+net_client_siobuf_flush(NetClientSioBuf *client, GError **error)
+{
+       NetClientSioBufPrivate *priv;
+       gboolean result;
+
+       g_return_val_if_fail(NET_IS_CLIENT_SIOBUF(client), FALSE);
+
+       priv = client->priv;
+       if (priv->writebuf->len > 0U) {
+               g_string_append(priv->writebuf, "\r\n");
+               result = net_client_write_buffer(NET_CLIENT(client), priv->writebuf->str, 
priv->writebuf->len, error);
+               g_string_truncate(priv->writebuf, 0U);
+       } else {
+               result = FALSE;
+       }
+
+       return result;
+}
+
+
+/* == local functions 
=========================================================================================================== */
+
+static void
+net_client_siobuf_class_init(NetClientSioBufClass *klass)
+{
+       GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+       gobject_class->finalize = net_client_siobuf_finalise;
+}
+
+
+static void
+net_client_siobuf_init(NetClientSioBuf *self)
+{
+       self->priv = g_new0(NetClientSioBufPrivate, 1U);
+}
+
+
+static gboolean
+net_client_siobuf_fill(NetClientSioBuf *client, GError **error)
+{
+       NetClientSioBufPrivate *priv = client->priv;
+       gboolean result;
+
+       if ((priv->buffer->len == 0U) || (priv->read_ptr == NULL) || (*priv->read_ptr == '\0')) {
+               gchar *read_buf;
+
+               result = net_client_read_line(NET_CLIENT(client), &read_buf, error);
+               if (result) {
+                       g_string_assign(priv->buffer, read_buf);
+                       g_string_append(priv->buffer, "\r\n");
+                       priv->read_ptr = priv->buffer->str;
+                       g_free(read_buf);
+               }
+       } else {
+               result = TRUE;
+       }
+
+       return result;
+}
+
+
+static void
+net_client_siobuf_finalise(GObject *object)
+{
+       const NetClientSioBuf *client = NET_CLIENT_SIOBUF(object);
+       const GObjectClass *parent_class = G_OBJECT_CLASS(net_client_siobuf_parent_class);
+
+       if (client->priv != NULL) {
+               g_string_free(client->priv->buffer, TRUE);
+               g_string_free(client->priv->writebuf, TRUE);
+               g_free(client->priv);
+       }
+       (*parent_class->finalize)(object);
+}
diff --git a/libnetclient/net-client-siobuf.h b/libnetclient/net-client-siobuf.h
new file mode 100644
index 00000000..91af01a3
--- /dev/null
+++ b/libnetclient/net-client-siobuf.h
@@ -0,0 +1,184 @@
+/* NetClient - simple line-based network client library
+ *
+ * Copyright (C) Albrecht Dreß <mailto:albrecht dress arcor de> 2018
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 
General Public License
+ * as published by the Free Software Foundation; either version 3 of the License, or (at your option) any 
later version.
+ *
+ * This library 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 Lesser General Public License for more 
details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library. If not, 
see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NET_CLIENT_SIOBUF_H_
+#define NET_CLIENT_SIOBUF_H_
+
+
+#include "net-client.h"
+
+
+G_BEGIN_DECLS
+
+
+#define NET_CLIENT_SIOBUF_TYPE                         (net_client_siobuf_get_type())
+#define NET_CLIENT_SIOBUF(obj)                         (G_TYPE_CHECK_INSTANCE_CAST((obj), 
NET_CLIENT_SIOBUF_TYPE, NetClientSioBuf))
+#define NET_IS_CLIENT_SIOBUF(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE((obj), 
NET_CLIENT_SIOBUF_TYPE))
+#define NET_CLIENT_SIOBUF_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST((klass), NET_CLIENT_SIOBUF_TYPE, 
NetClientSioBufClass))
+#define NET_IS_CLIENT_SIOBUF_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE((klass), NET_CLIENT_SIOBUF_TYPE))
+#define NET_CLIENT_SIOBUF_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS((obj), NET_CLIENT_SIOBUF_TYPE, 
NetClientSioBufClass))
+
+#define NET_CLIENT_SIOBUF_ERROR_QUARK          (g_quark_from_static_string("net-client-siobuf"))
+
+
+typedef struct _NetClientSioBuf NetClientSioBuf;
+typedef struct _NetClientSioBufClass NetClientSioBufClass;
+typedef struct _NetClientSioBufPrivate NetClientSioBufPrivate;
+
+
+struct _NetClientSioBuf {
+    NetClient parent;
+    NetClientSioBufPrivate *priv;
+};
+
+
+struct _NetClientSioBufClass {
+       NetClientClass parent;
+};
+
+
+GType net_client_siobuf_get_type(void)
+       G_GNUC_CONST;
+
+
+/** @brief Create a new SIOBUF network client
+ *
+ * @param host host name or IP address to connect
+ * @param port port number to connect
+ * @return the SIOBUF network client object
+ */
+NetClientSioBuf *net_client_siobuf_new(const gchar *host, guint16 port);
+
+
+/** @brief Read a number of bytes from a SIOBUF network client object
+ *
+ * @param client SIOBUF network client object
+ * @param buffer destination buffer
+ * @param count number of bytes which shall be read
+ * @param error filled with error information on error
+ * @return the number of bytes actually read, or -1 if nothing could be read
+ *
+ * Read a number of bytes, including the CRLF line terminations if applicable, from the remote server.  Note 
that the error location
+ * may be filled on a short read (i. e. when the number of bytes read is smaller than the requested count).
+ */
+gint net_client_siobuf_read(NetClientSioBuf *client, void *buffer, gsize count, GError **error);
+
+
+/** @brief Read a character from a SIOBUF network client object
+ *
+ * @param client SIOBUF network client object
+ * @param error filled with error information on error
+ * @return the next character, or -1 if reading more data from the remote server failed
+ *
+ * Read the next character from the remote server.  This includes the terminating CR and LF characters of 
each line.
+ */
+gint net_client_siobuf_getc(NetClientSioBuf *client, GError **error);
+
+
+/** @brief Read a character from a SIOBUF network client object
+ *
+ * @param client SIOBUF network client object
+ * @return 0 on success, or ä1 on error
+ *
+ * Put back the last character read from the remote server.  The function fails if no data is available or 
if the start of the
+ * internal buffer has been reached.
+ */
+gint net_client_siobuf_ungetc(NetClientSioBuf *client);
+
+
+/** @brief Read a buffer from a SIOBUF network client object
+ *
+ * @param client SIOBUF network client object
+ * @param buffer destination buffer
+ * @param buflen number of characters which shall be read
+ * @param error filled with error information on error
+ * @return the passed buffer on success, or NULL on error
+ *
+ * Fill the passed buffer with data from the remote server until either the end of the line is reached, or 
the buffer is full.  The
+ * CRLF termination sequence is included in the buffer.  The buffer is always NUL-terminated.
+ */
+gchar *net_client_siobuf_gets(NetClientSioBuf *client, gchar *buffer, gsize buflen, GError **error);
+
+
+/** @brief Read a line from a SIOBUF network client object
+ *
+ * @param client SIOBUF network client object
+ * @param error filled with error information on error
+ * @return a line of data, excluding the terminating CRLF on success, or NULL on error
+ *
+ * Return a newly allocated buffer, containing data from the remote server, but excluding the terminating 
CRLF sequence.  If the
+ * read buffer contains only 1 or 2 characters (i. e. the terminating CRLF or only LF), the function returns 
an empty string.  The
+ * internal read buffer is empty after calling this function.
+ *
+ * @note The caller must free the returned buffer when it is not needed any more.
+ */
+gchar *net_client_siobuf_get_line(NetClientSioBuf *client, GError **error)
+       G_GNUC_WARN_UNUSED_RESULT;
+
+
+/** @brief Empty the SIOBUF network client object read buffer
+ *
+ * @param client SIOBUF network client object
+ * @param error filled with error information on error
+ * @return '\n' on success, or -1 on error
+ *
+ * Discard all pending data in the read buffer.  If the read buffer is empty, the function reads the next 
line and discards it.
+ */
+gint net_client_siobuf_discard_line(NetClientSioBuf *client, GError **error);
+
+
+/** @brief Write data to the SIOBUF output buffer
+ *
+ * @param client SIOBUF network client object
+ * @param buffer data buffer which shall be written
+ * @param count number of bytes which shall be written
+ *
+ * Append the the passed data to the client's internal write buffer.  Call net_client_siobuf_flush() to 
actually send the data to
+ * the remote server.
+ */
+void net_client_siobuf_write(NetClientSioBuf *client, const void *buffer, gsize count);
+
+
+/** @brief Print to the SIOBUF output buffer
+ *
+ * @param client SIOBUF network client object
+ * @param format printf-like format string
+ * @param ... additional arguments according to the format string
+ *
+ * Format a string according to the passed arguments, and append the the passed data to the client's 
internal write buffer.  Call
+ * net_client_siobuf_flush() to actually send the data to the remote server.
+ */
+void net_client_siobuf_printf(NetClientSioBuf *client, const gchar *format, ...)
+       G_GNUC_PRINTF(2, 3);
+
+
+/** @brief Send buffered SIOBUF output data
+ *
+ * @param client SIOBUF network client object
+ * @param error filled with error information on error
+ * @return TRUE is the send operation was successful, FALSE on error
+ *
+ * Transmit the client's internal write buffer, followed by a CRLF sequence, to the remote server and clear 
it.
+ */
+gboolean net_client_siobuf_flush(NetClientSioBuf *client, GError **error);
+
+
+/** @file
+ *
+ * This module implements a glue layer client class for Balsa's imap implementation.  In addition to the 
base class, it implements
+ * an internal input line buffer which provides reading single characters and lines, reading an exact amount 
of bytes, and buffered
+ * write operations.
+ */
+
+#endif /* NET_CLIENT_SIOBUF_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]