gpg: New option --input-size-hint.
authorWerner Koch <wk@gnupg.org>
Thu, 11 Aug 2016 19:31:12 +0000 (21:31 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 11 Aug 2016 19:32:55 +0000 (21:32 +0200)
* g10/options.h: Include stdint.h.
(struct opt): Add field 'input_size_hint'.
* g10/gpg.c (oInputSizeHint): New.
(opts): Add --input-size-hint.
(main): Set opt.input_size_hint.
* g10/progress.c (write_status_progress): Use the hint.
--

This is a prerequisite to fix
GnuPG-bug-id: 2368

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/gpg.texi
g10/gpg.c
g10/options.h
g10/progress.c

index 944734b..894d384 100644 (file)
@@ -2155,6 +2155,15 @@ works properly with such messages, there is often a desire to set a
 maximum file size that will be generated before processing is forced to
 stop by the OS limits. Defaults to 0, which means "no limit".
 
+@item --input-size-hint @var{n}
+@opindex input-size-hint
+This option can be used to tell GPG the size of the input data in
+bytes.  @var{n} must be a positive base-10 number.  This option is
+only useful if the input is not taken from a file.  GPG may use thos
+hint to optimize its buffer allocation strategy.  It is also used by
+the @option{--status-fd} line ``PROGRESS'' to provide a value for
+``total'' if that is not available by other means.
+
 @item --import-options @code{parameters}
 @opindex import-options
 This is a space or comma delimited string that gives options for
index adc32f0..fd21fde 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -99,6 +99,7 @@ enum cmd_and_opt_values
     aListSecretKeys = 'K',
     oBatch       = 500,
     oMaxOutput,
+    oInputSizeHint,
     oSigNotation,
     oCertNotation,
     oShowNotation,
@@ -554,6 +555,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
   ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
+  ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"),
 
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
@@ -2459,7 +2461,13 @@ main (int argc, char **argv)
 
          case oArmor: opt.armor = 1; opt.no_armor=0; break;
          case oOutput: opt.outfile = pargs.r.ret_str; break;
+
          case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
+
+          case oInputSizeHint:
+            opt.input_size_hint = string_to_u64 (pargs.r.ret_str);
+            break;
+
          case oQuiet: opt.quiet = 1; break;
          case oNoTTY: tty_no_terminal(1); break;
          case oDryRun: opt.dry_run = 1; break;
index d1c3634..230c96a 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <sys/types.h>
 #include <types.h>
+#include <stdint.h>
 #include "main.h"
 #include "packet.h"
 #include "tofu.h"
@@ -54,6 +55,12 @@ struct
   char *outfile;
   estream_t outfp;  /* Hack, sometimes used in place of outfile.  */
   off_t max_output;
+
+  /* If > 0 a hint with the expected number of input data bytes.  This
+   * is not necessary an exact number but intended to be used for
+   * progress info and to decide on how to allocate buffers.  */
+  uint64_t input_size_hint;
+
   int dry_run;
   int autostart;
   int list_only;
index efc3b3a..f151657 100644 (file)
@@ -73,11 +73,12 @@ release_progress_context (progress_filter_context_t *pfx)
 
 static void
 write_status_progress (const char *what,
-                       unsigned long current, unsigned long total)
+                       unsigned long current, unsigned long total_arg)
 {
   char buffer[60];
   char units[] = "BKMGTPEZY?";
   int unitidx = 0;
+  uint64_t total = total_arg;
 
   /* Although we use an unsigned long for the values, 32 bit
    * applications using GPGME will use an "int" and thus are limited
@@ -91,6 +92,10 @@ write_status_progress (const char *what,
    * thus scaling CURRENT and TOTAL down before they get to large,
    * should not have a noticeable effect except for rounding
    * imprecision. */
+
+  if (!total && opt.input_size_hint)
+    total = opt.input_size_hint;
+
   if (total)
     {
       if (current > total)
@@ -116,7 +121,7 @@ write_status_progress (const char *what,
     unitidx = 9;
 
   snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu %c%s",
-            what? what : "?", current, total,
+            what? what : "?", current, (unsigned long)total,
             units[unitidx],
             unitidx? "iB" : "");
   write_status_text (STATUS_PROGRESS, buffer);