core: New interface gpgme_data_new_from_estream.
authorWerner Koch <wk@gnupg.org>
Thu, 19 Jul 2018 07:50:30 +0000 (09:50 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 19 Jul 2018 07:51:45 +0000 (09:51 +0200)
* src/gpgme.h.in (gpgme_data_new_from_estream): New.
* src/data-estream.c: New.
* src/data.h (gpgme_data): New union member e_stream.
--

The estream functions (gpgrt_fopen et al.) are any waypart of the
required libgpg-error library and thus it makes sense to provide this
convenience interface.

Signed-off-by: Werner Koch <wk@gnupg.org>
NEWS
doc/gpgme.texi
src/Makefile.am
src/data-estream.c [new file with mode: 0644]
src/data.h
src/gpgme.h.in

diff --git a/NEWS b/NEWS
index ae80642..20a80e8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,13 +7,16 @@ Noteworthy changes in version 1.11.2 (unreleased)
  * Added context flag "auto-key-locate" to control the
    behavior of GPGME_KEYLIST_MODE_LOCATE.
 
+ * New data function to create a data object from an estream.
+
  * Interface changes relative to the 1.11.1 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gpgme_data_new_from_estream                NEW.
  gpgme_decrypt_result_t           EXTENDED: New field legacy_cipher_nomdc.
  gpgme_set_ctx_flag               EXTENDED: New flag 'ignore-mdc-error'.
  GPGME_AUDITLOG_DEFAULT                     NEW.
  GPGME_AUDITLOG_DIAG                        NEW.
- gpgme_set_ctx_flag          EXTENDED: New flag 'auto-key-locate'.
+ gpgme_set_ctx_flag               EXTENDED: New flag 'auto-key-locate'.
  cpp: DecryptionResult::sessionKey          NEW.
  cpp: DecryptionResult::symkeyAlgo          NEW.
  cpp: DecryptionResult::isLegacyCipherNoMDC New.
index 38d3480..aff7240 100644 (file)
@@ -1909,6 +1909,25 @@ data object was successfully created, and @code{GPG_ERR_ENOMEM} if not
 enough memory is available.
 @end deftypefun
 
+@deftypefun gpgme_error_t gpgme_data_new_from_estream (@w{gpgme_data_t *@var{dh}}, @w{gpgrt_stream_t @var{stream}})
+The function @code{gpgme_data_new_from_estream} creates a new
+@code{gpgme_data_t} object and uses the gpgrt stream @var{stream} to read
+from (if used as an input data object) and write to (if used as an
+output data object).
+
+When using the data object as an input buffer, the function might read
+a bit more from the stream than is actually needed by the crypto
+engine in the desired operation because of internal buffering.
+
+Note that GPGME assumes that the stream is in blocking mode.  Errors
+during I/O operations, except for EINTR, are usually fatal for crypto
+operations.
+
+The function returns the error code @code{GPG_ERR_NO_ERROR} if the
+data object was successfully created, and @code{GPG_ERR_ENOMEM} if not
+enough memory is available.
+@end deftypefun
+
 
 @node Callback Based Data Buffers
 @subsection Callback Based Data Buffers
index 0a196e0..1394c02 100644 (file)
@@ -70,6 +70,7 @@ main_sources =                                                                \
        parsetlv.c parsetlv.h                                           \
        mbox-util.c mbox-util.h                                         \
        data.h data.c data-fd.c data-stream.c data-mem.c data-user.c    \
+       data-estream.c                                                  \
        data-compat.c data-identify.c                                   \
        signers.c sig-notation.c                                        \
        wait.c wait-global.c wait-private.c wait-user.c wait.h          \
diff --git a/src/data-estream.c b/src/data-estream.c
new file mode 100644 (file)
index 0000000..34f88a7
--- /dev/null
@@ -0,0 +1,99 @@
+/* data-stream.c - A stream based data object.
+ * Copyright (C) 2002, 2004, 2018 g10 Code GmbH
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME 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 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GPGME 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 program; if not, see <http://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include "debug.h"
+#include "data.h"
+
+\f
+static gpgme_ssize_t
+stream_es_read (gpgme_data_t dh, void *buffer, size_t size)
+{
+  size_t amt = gpgrt_fread (buffer, 1, size, dh->data.e_stream);
+  if (amt > 0)
+    return amt;
+  return gpgrt_ferror (dh->data.e_stream) ? -1 : 0;
+}
+
+
+static gpgme_ssize_t
+stream_es_write (gpgme_data_t dh, const void *buffer, size_t size)
+{
+  size_t amt = gpgrt_fwrite (buffer, 1, size, dh->data.e_stream);
+  if (amt > 0)
+    return amt;
+  return gpgrt_ferror (dh->data.e_stream) ? -1 : 0;
+}
+
+
+static gpgme_off_t
+stream_es_seek (gpgme_data_t dh, gpgme_off_t offset, int whence)
+{
+  int err;
+
+  err = gpgrt_fseeko (dh->data.e_stream, offset, whence);
+  if (err)
+    return -1;
+
+  return gpgrt_ftello (dh->data.e_stream);
+}
+
+
+static int
+stream_es_get_fd (gpgme_data_t dh)
+{
+  gpgrt_fflush (dh->data.e_stream);
+  return gpgrt_fileno (dh->data.e_stream);
+}
+
+
+static struct _gpgme_data_cbs stream_es_cbs =
+  {
+    stream_es_read,
+    stream_es_write,
+    stream_es_seek,
+    NULL,
+    stream_es_get_fd
+  };
+
+
+\f
+gpgme_error_t
+gpgme_data_new_from_estream (gpgme_data_t *r_dh, gpgrt_stream_t stream)
+{
+  gpgme_error_t err;
+  TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_estream", r_dh, "estream=%p",
+             stream);
+
+  err = _gpgme_data_new (r_dh, &stream_es_cbs);
+  if (err)
+    return TRACE_ERR (err);
+
+  (*r_dh)->data.e_stream = stream;
+  return TRACE_SUC1 ("dh=%p", *r_dh);
+}
index 0a15b61..f12508b 100644 (file)
@@ -100,6 +100,9 @@ struct gpgme_data
     /* For gpgme_data_new_from_stream.  */
     FILE *stream;
 
+    /* For gpgme_data_new_from_estream.  */
+    gpgrt_stream_t e_stream;
+
     /* For gpgme_data_new_from_cbs.  */
     struct
     {
index 421199a..3596801 100644 (file)
@@ -1180,6 +1180,8 @@ gpgme_error_t gpgme_data_new_from_cbs (gpgme_data_t *dh,
 gpgme_error_t gpgme_data_new_from_fd (gpgme_data_t *dh, int fd);
 
 gpgme_error_t gpgme_data_new_from_stream (gpgme_data_t *dh, FILE *stream);
+gpgme_error_t gpgme_data_new_from_estream (gpgme_data_t *r_dh,
+                                           gpgrt_stream_t stream);
 
 /* Return the encoding attribute of the data buffer DH */
 gpgme_data_encoding_t gpgme_data_get_encoding (gpgme_data_t dh);