core: New interface gpgme_data_new_from_estream.

* 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>
This commit is contained in:
Werner Koch 2018-07-19 09:50:30 +02:00
parent 98a75a16cc
commit f42cd70f18
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 128 additions and 1 deletions

3
NEWS
View File

@ -7,8 +7,11 @@ 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.

View 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

View 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 \

99
src/data-estream.c Normal file
View File

@ -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"
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
};
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);
}

View 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
{

View 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);