Index: b/NEWS =================================================================== --- b/NEWS +++ b/NEWS @@ -21,6 +21,8 @@ GPGME_DATA_TYPE_PGP_ENCRYPTED NEW. GPGME_DATA_TYPE_PGP_SIGNATURE NEW. GPGME_DATA_ENCODING_MIME NEW. + gpgme_data_set_file_size NEW. + gpgme_data_get_file_size NEW. Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0] Index: b/doc/gpgme.texi =================================================================== --- b/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -2077,6 +2077,7 @@ @subsection Data Buffer Meta-Data @cindex data buffer, meta-data @cindex data buffer, file name +@cindex data buffer, file size @cindex data buffer, encoding @deftypefun {char *} gpgme_data_get_file_name (@w{gpgme_data_t @var{dh}}) @@ -2103,6 +2104,26 @@ @end deftypefun +@deftypefun {unsigned long long} gpgme_data_get_file_size (@w{gpgme_data_t @var{dh}}) +The function @code{gpgme_data_get_file_size} returns the manually +set file size associated with the data object. +It does not return the actual size of file based data types but +instead only what has been set with @code{gpgme_data_set_file_size} + +If no error occurs, the set file size value is returned. +Otherwise, or if it was not set @code{0} will be returned. +@end deftypefun + + +@deftypefun gpgme_error_t gpgme_data_set_file_size (@w{gpgme_data_t @var{dh}}, @w{unsigned long long@var{file_size}}) +The function @code{gpgme_data_set_file_size} sets the file size +associated with the data object. The +file size will be passed to gpg and can be used for progress calculations. + +The function returns the error code @code{GPG_ERR_INV_VALUE} if +@var{dh} is not a valid pointer. +@end deftypefun + @deftp {Data type} {enum gpgme_data_encoding_t} @tindex gpgme_data_encoding_t The @code{gpgme_data_encoding_t} type specifies the encoding of a Index: b/lang/cpp/src/data.cpp =================================================================== --- b/lang/cpp/src/data.cpp +++ b/lang/cpp/src/data.cpp @@ -125,6 +125,11 @@ if (e) { d->data = 0; } + if (dp->isSupported(DataProvider::Seek)) { + off_t size = seek(0, SEEK_END); + seek(0, SEEK_SET); + gpgme_data_set_file_size(d->data, static_cast(size)); + } #ifndef NDEBUG //std::cerr << "GpgME::Data(): DataProvider supports: " // << ( d->cbs.read ? "read" : "no read" ) << ", " Index: b/src/data.h =================================================================== --- b/src/data.h +++ b/src/data.h @@ -89,6 +89,9 @@ /* File name of the data object. */ char *file_name; + /* File size of the data object. */ + unsigned long long file_size; + union { /* For gpgme_data_new_from_fd. */ @@ -121,6 +124,7 @@ int (*cb) (void *, char *, size_t, size_t *); void *handle; } old_user; + } data; }; Index: b/src/data.c =================================================================== --- b/src/data.c +++ b/src/data.c @@ -243,6 +243,39 @@ return dh->file_name; } +/* Set the file size associated with the data object with handle DH to + FILE_SIZE. */ +gpgme_error_t +gpgme_data_set_file_size (gpgme_data_t dh, unsigned long long file_size) +{ + TRACE_BEG1 (DEBUG_DATA, "gpgme_data_set_file_size", dh, + "file_size=%llu", file_size); + + if (!dh) + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + + dh->file_size = file_size; + + return TRACE_ERR (0); +} + + +/* Get the file size associated with the data object with handle DH, + or 0 if there is none. */ +unsigned long long +gpgme_data_get_file_size (gpgme_data_t dh) +{ + if (!dh) + { + TRACE (DEBUG_DATA, "gpgme_data_get_file_size", dh); + return 0; + } + + TRACE1 (DEBUG_DATA, "gpgme_data_get_file_size", dh, + "dh->file_size=%llu", dh->file_size); + return dh->file_size; +} + /* Functions to support the wait interface. */ Index: b/src/engine-gpg.c =================================================================== --- b/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1713,6 +1713,27 @@ static gpgme_error_t +append_size_arg (engine_gpg_t gpg, gpgme_data_t data) +{ + gpgme_error_t err = 0; + if (gpgme_data_get_file_size (data)) + { + err = add_arg (gpg, "--set-filesize"); + if (!err) + { + char *size_str; + if (asprintf (&size_str, "%llu", + gpgme_data_get_file_size (data)) < 0) + return gpg_error_from_syserror (); + err = add_arg (gpg, size_str); + free (size_str); + } + } + return err; +} + + +static gpgme_error_t gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t ciph, int use_armor) { @@ -1761,6 +1782,8 @@ err = add_arg (gpg, gpgme_data_get_file_name (plain)); } if (!err) + err = append_size_arg (gpg, plain); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, plain, -1, 0); @@ -1831,6 +1854,8 @@ err = add_arg (gpg, gpgme_data_get_file_name (plain)); } if (!err) + err = append_size_arg (gpg, plain); + if (!err) err = add_arg (gpg, "--"); if (!err) err = add_data (gpg, plain, -1, 0); @@ -2420,6 +2445,8 @@ if (!err) err = add_arg (gpg, gpgme_data_get_file_name (in)); } + if (!err) + err = append_size_arg (gpg, in); /* Tell the gpg object about the data. */ if (!err) Index: b/src/gpgme.h.in =================================================================== --- b/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1279,6 +1279,19 @@ gpgme_error_t gpgme_data_set_file_name (gpgme_data_t dh, const char *file_name); +/* Get the file size associated with the data object with handle DH, or + 0 if there is none set. This only returns file_size explicitly set by + gpgme_data_set_file_size and not the actual file size for file based + data types. */ +unsigned long long gpgme_data_get_file_size (gpgme_data_t dh); + +/* Set the file size associated with the data object with handle DH to + FILE_SIZE. The file size is mainly useful for callback based data + types where it can be used to give a filesize indication that will + be used e.g. for progress calculation. */ +gpgme_error_t gpgme_data_set_file_size (gpgme_data_t dh, + unsigned long long file_size); + /* Try to identify the type of the data in DH. */ gpgme_data_type_t gpgme_data_identify (gpgme_data_t dh, int reserved); Index: b/src/gpgme.def =================================================================== --- b/src/gpgme.def +++ b/src/gpgme.def @@ -226,5 +226,8 @@ gpgme_pubkey_algo_string @169 gpgme_set_ctx_flag @170 + + gpgme_data_set_file_size @171 + gpgme_data_get_file_size @172 ; END Index: b/src/libgpgme.vers =================================================================== --- b/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -29,6 +29,8 @@ gpgme_data_set_file_name; gpgme_data_get_file_name; + gpgme_data_set_file_size; + gpgme_data_get_file_size; gpgme_data_identify; gpgme_sig_notation_clear;