json: Add guard in create_keylist_patterns
[gpgme.git] / src / data.c
index 18d9c71..7ae5b32 100644 (file)
@@ -2,17 +2,17 @@
    Copyright (C) 2002, 2003, 2004, 2005, 2007 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -23,7 +23,9 @@
 #endif
 
 #include <stdlib.h>
-#include <unistd.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 #include <errno.h>
 #include <string.h>
 
@@ -44,9 +46,13 @@ _gpgme_data_new (gpgme_data_t *r_dh, struct _gpgme_data_cbs *cbs)
     return gpg_error (GPG_ERR_INV_VALUE);
 
   *r_dh = NULL;
+
+  if (_gpgme_selftest)
+    return _gpgme_selftest;
+
   dh = calloc (1, sizeof (*dh));
   if (!dh)
-    return gpg_error_from_errno (errno);
+    return gpg_error_from_syserror ();
 
   dh->cbs = cbs;
 
@@ -70,21 +76,21 @@ _gpgme_data_release (gpgme_data_t dh)
 /* Read up to SIZE bytes into buffer BUFFER from the data object with
    the handle DH.  Return the number of characters read, 0 on EOF and
    -1 on error.  If an error occurs, errno is set.  */
-ssize_t
+gpgme_ssize_t
 gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size)
 {
-  ssize_t res;
+  gpgme_ssize_t res;
   TRACE_BEG2 (DEBUG_DATA, "gpgme_data_read", dh,
              "buffer=%p, size=%u", buffer, size);
 
   if (!dh)
     {
-      errno = EINVAL;
+      gpg_err_set_errno (EINVAL);
       return TRACE_SYSRES (-1);
     }
   if (!dh->cbs->read)
     {
-      errno = ENOSYS;
+      gpg_err_set_errno (ENOSYS);
       return TRACE_SYSRES (-1);
     }
   do
@@ -98,21 +104,21 @@ gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size)
 /* Write up to SIZE bytes from buffer BUFFER to the data object with
    the handle DH.  Return the number of characters written, or -1 on
    error.  If an error occurs, errno is set.  */
-ssize_t
+gpgme_ssize_t
 gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size)
 {
-  ssize_t res;
+  gpgme_ssize_t res;
   TRACE_BEG2 (DEBUG_DATA, "gpgme_data_write", dh,
              "buffer=%p, size=%u", buffer, size);
 
   if (!dh)
     {
-      errno = EINVAL;
+      gpg_err_set_errno (EINVAL);
       return TRACE_SYSRES (-1);
     }
   if (!dh->cbs->write)
     {
-      errno = ENOSYS;
+      gpg_err_set_errno (ENOSYS);
       return TRACE_SYSRES (-1);
     }
   do
@@ -126,20 +132,20 @@ gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size)
 /* Set the current position from where the next read or write starts
    in the data object with the handle DH to OFFSET, relativ to
    WHENCE.  */
-off_t
-gpgme_data_seek (gpgme_data_t dh, off_t offset, int whence)
+gpgme_off_t
+gpgme_data_seek (gpgme_data_t dh, gpgme_off_t offset, int whence)
 {
   TRACE_BEG2 (DEBUG_DATA, "gpgme_data_seek", dh,
              "offset=%lli, whence=%i", offset, whence);
 
   if (!dh)
     {
-      errno = EINVAL;
+      gpg_err_set_errno (EINVAL);
       return TRACE_SYSRES (-1);
     }
   if (!dh->cbs->seek)
     {
-      errno = ENOSYS;
+      gpg_err_set_errno (ENOSYS);
       return TRACE_SYSRES (-1);
     }
 
@@ -156,6 +162,20 @@ gpgme_data_seek (gpgme_data_t dh, off_t offset, int whence)
 }
 
 
+/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET).  */
+gpgme_error_t
+gpgme_data_rewind (gpgme_data_t dh)
+{
+  gpgme_error_t err;
+  TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh);
+
+  err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1)
+         ? gpg_error_from_syserror () : 0);
+
+  return TRACE_ERR (err);
+}
+
+
 /* Release the data object with the handle DH.  */
 void
 gpgme_data_release (gpgme_data_t dh)
@@ -191,7 +211,7 @@ gpgme_data_set_encoding (gpgme_data_t dh, gpgme_data_encoding_t enc)
              "encoding=%i", enc);
   if (!dh)
     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
-  if (enc < 0 || enc > GPGME_DATA_ENCODING_ARMOR)
+  if (enc < 0 || enc > GPGME_DATA_ENCODING_MIME)
     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
   dh->encoding = enc;
   return TRACE_ERR (0);
@@ -216,7 +236,7 @@ gpgme_data_set_file_name (gpgme_data_t dh, const char *file_name)
     {
       dh->file_name = strdup (file_name);
       if (!dh->file_name)
-       return TRACE_ERR (gpg_error_from_errno (errno));
+       return TRACE_ERR (gpg_error_from_syserror ());
     }
   else
     dh->file_name = 0;
@@ -241,22 +261,45 @@ gpgme_data_get_file_name (gpgme_data_t dh)
   return dh->file_name;
 }
 
+
+/* Set a flag for the data object DH.  See the manual for details.  */
+gpg_error_t
+gpgme_data_set_flag (gpgme_data_t dh, const char *name, const char *value)
+{
+  TRACE_BEG2 (DEBUG_DATA, "gpgme_data_set_flag", dh,
+             "%s=%s", name, value);
+
+  if (!dh)
+    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+  if (!strcmp (name, "size-hint"))
+    {
+      dh->size_hint= value? _gpgme_string_to_off (value) : 0;
+    }
+  else
+    return gpg_error (GPG_ERR_UNKNOWN_NAME);
+
+  return 0;
+}
+
+
 \f
 /* Functions to support the wait interface.  */
 
 gpgme_error_t
 _gpgme_data_inbound_handler (void *opaque, int fd)
 {
-  gpgme_data_t dh = (gpgme_data_t) opaque;
+  struct io_cb_data *data = (struct io_cb_data *) opaque;
+  gpgme_data_t dh = (gpgme_data_t) data->handler_value;
   char buffer[BUFFER_SIZE];
   char *bufp = buffer;
-  ssize_t buflen;
+  gpgme_ssize_t buflen;
   TRACE_BEG1 (DEBUG_CTX, "_gpgme_data_inbound_handler", dh,
              "fd=0x%x", fd);
 
   buflen = _gpgme_io_read (fd, buffer, BUFFER_SIZE);
   if (buflen < 0)
-    return gpg_error_from_errno (errno);
+    return gpg_error_from_syserror ();
   if (buflen == 0)
     {
       _gpgme_io_close (fd);
@@ -265,9 +308,9 @@ _gpgme_data_inbound_handler (void *opaque, int fd)
 
   do
     {
-      ssize_t amt = gpgme_data_write (dh, bufp, buflen);
+      gpgme_ssize_t amt = gpgme_data_write (dh, bufp, buflen);
       if (amt == 0 || (amt < 0 && errno != EINTR))
-       return TRACE_ERR (gpg_error_from_errno (errno));
+       return TRACE_ERR (gpg_error_from_syserror ());
       bufp += amt;
       buflen -= amt;
     }
@@ -279,16 +322,17 @@ _gpgme_data_inbound_handler (void *opaque, int fd)
 gpgme_error_t
 _gpgme_data_outbound_handler (void *opaque, int fd)
 {
-  gpgme_data_t dh = (gpgme_data_t) opaque;
-  ssize_t nwritten;
+  struct io_cb_data *data = (struct io_cb_data *) opaque;
+  gpgme_data_t dh = (gpgme_data_t) data->handler_value;
+  gpgme_ssize_t nwritten;
   TRACE_BEG1 (DEBUG_CTX, "_gpgme_data_outbound_handler", dh,
              "fd=0x%x", fd);
 
   if (!dh->pending_len)
     {
-      ssize_t amt = gpgme_data_read (dh, dh->pending, BUFFER_SIZE);
+      gpgme_ssize_t amt = gpgme_data_read (dh, dh->pending, BUFFER_SIZE);
       if (amt < 0)
-       return TRACE_ERR (gpg_error_from_errno (errno));
+       return TRACE_ERR (gpg_error_from_syserror ());
       if (amt == 0)
        {
          _gpgme_io_close (fd);
@@ -312,7 +356,7 @@ _gpgme_data_outbound_handler (void *opaque, int fd)
     }
 
   if (nwritten <= 0)
-    return TRACE_ERR (gpg_error_from_errno (errno));
+    return TRACE_ERR (gpg_error_from_syserror ());
 
   if (nwritten < dh->pending_len)
     memmove (dh->pending, dh->pending + nwritten, dh->pending_len - nwritten);
@@ -330,3 +374,11 @@ _gpgme_data_get_fd (gpgme_data_t dh)
     return -1;
   return (*dh->cbs->get_fd) (dh);
 }
+
+
+/* Get the size-hint value for DH or 0 if not available.  */
+gpgme_off_t
+_gpgme_data_get_size_hint (gpgme_data_t dh)
+{
+  return dh ? dh->size_hint : 0;
+}