I'd like to propose two small tweaks for libgsf that I think could be
quite useful for third-party users of the library in general.
(Certainly they'd be helpful to me, for use with gretl.)

1) gsf-output-memory: it would be nice to be able to "steal" a
buffer created in this way. At present if you want to make further use
of it after closing and unref'ing the GsfOutput you have to copy the
buffer. Proposal: add a function gsf_output_memory_steal_bytes().

2) gsf-output-gzip: in some contexts it would be useful to be able to
control the zlib compression level in the interest of maximum speed or
maximal compression. Proposal: add a compression-level property, plus
a function gsf_output_gzip_new_full() which allows you to set this
property at construction.

I'm attaching two little patches against git (also 1.14.46, since the
relevant source files haven't changed recently) which do what I'm
talking about.

-- 
Allin Cottrell
Department of Economics
Wake Forest University, NC
--- gsf-output-memory.c.orig    2019-10-14 10:28:11.549673629 -0400
+++ gsf-output-memory.c 2019-10-14 13:19:51.103063501 -0400
@@ -197,6 +197,26 @@
        return mem->buffer;
 }
 
+/**
+ * gsf_output_memory_steal_bytes:
+ * @mem: the output device.
+ *
+ * Returns: (array) (nullable): The data that has been written to @mem.
+ * The caller takes ownership and the buffer belonging to @mem is set
+ * to %NULL.
+ **/
+guint8 *
+gsf_output_memory_steal_bytes (GsfOutputMemory * mem)
+{
+       guint8 *bytes;
+       
+       g_return_val_if_fail (mem != NULL, NULL);
+       bytes = mem->buffer;
+       mem->buffer = NULL;
+       mem->capacity = 0;
+       return bytes;
+}
+
 GSF_CLASS (GsfOutputMemory, gsf_output_memory,
           gsf_output_memory_class_init, gsf_output_memory_init,
           GSF_OUTPUT_TYPE)
--- gsf-output-memory.h.orig    2019-10-14 10:28:11.549673629 -0400
+++ gsf-output-memory.h 2019-10-14 10:30:49.919674526 -0400
@@ -38,6 +38,7 @@
 
 GsfOutput *gsf_output_memory_new      (void);
 const guint8* gsf_output_memory_get_bytes (GsfOutputMemory * mem);
+guint8* gsf_output_memory_steal_bytes (GsfOutputMemory * mem);
 
 G_END_DECLS
 
--- gsf-output-gzip.c.orig      2019-10-14 10:28:11.549673629 -0400
+++ gsf-output-gzip.c   2019-10-14 13:09:36.813060057 -0400
@@ -35,6 +35,7 @@
 
        GsfOutput *sink; /* compressed data */
        gboolean raw; /* No header and no trailer.  */
+       gint complev; /* zlib compression level */
 
        z_stream  stream;
        uLong     crc;     /* crc32 of uncompressed data */
@@ -51,7 +52,8 @@
 enum {
        PROP_0,
        PROP_RAW,
-       PROP_SINK
+       PROP_SINK,
+       PROP_COMPLEV
 };
 
 
@@ -63,7 +65,7 @@
 {
        int ret;
 
-       ret = deflateInit2 (&gzip->stream, Z_DEFAULT_COMPRESSION,
+       ret = deflateInit2 (&gzip->stream, gzip->complev,
                            Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL,
                            Z_DEFAULT_STRATEGY);
        if (ret != Z_OK)
@@ -105,6 +107,39 @@
 }
 
 /**
+ * gsf_output_gzip_new_full:
+ * @sink: The underlying data source.
+ * @compress_level: The zlib compression level (0 to 9).
+ * @err: optionally %NULL.
+ *
+ * Adds a reference to @sink.
+ *
+ * Returns: a new file or %NULL.
+ **/
+GsfOutput *
+gsf_output_gzip_new_full (GsfOutput *sink, gint compress_level, GError **err)
+{
+       GsfOutput *output;
+       GError const *con_err;
+
+       g_return_val_if_fail (GSF_IS_OUTPUT (sink), NULL);
+
+       output = g_object_new (GSF_OUTPUT_GZIP_TYPE, "sink", sink,
+                              "complev", compress_level, NULL);
+
+       con_err = gsf_output_error (output);
+
+       if (con_err) {
+               if (err)
+                       *err = g_error_copy (con_err);
+               g_object_unref (output);
+               return NULL;
+       }
+
+       return output;
+}
+
+/**
  * gsf_output_gzip_new:
  * @sink: The underlying data source.
  * @err: optionally %NULL.
@@ -281,6 +316,7 @@
        gzip->isize             = 0;
        gzip->buf               = NULL;
        gzip->buf_size          = 0;
+       gzip->complev           = Z_DEFAULT_COMPRESSION;
 }
 
 static void
@@ -298,6 +334,9 @@
        case PROP_SINK:
                g_value_set_object (value, gzip->sink);
                break;
+       case PROP_COMPLEV:
+               g_value_set_int (value, gzip->complev);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -329,6 +368,9 @@
        case PROP_SINK:
                gsf_output_gzip_set_sink (gzip, g_value_get_object (value));
                break;
+       case PROP_COMPLEV:
+               gzip->complev = g_value_get_int (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -393,6 +435,16 @@
                                      GSF_PARAM_STATIC |
                                      G_PARAM_READWRITE |
                                      G_PARAM_CONSTRUCT_ONLY));
+       g_object_class_install_property
+               (gobject_class,
+                PROP_COMPLEV,
+                g_param_spec_int ("complev", "Complev",
+                                  "zlib compression level.",
+                                  -1, 9, -1,
+                                  GSF_PARAM_STATIC |
+                                  G_PARAM_READWRITE |
+                                  G_PARAM_CONSTRUCT_ONLY));
+       
 
        parent_class = g_type_class_peek_parent (gobject_class);
 }
--- gsf-output-gzip.h.orig      2019-10-14 10:28:11.549673629 -0400
+++ gsf-output-gzip.h   2019-10-14 10:30:49.916341194 -0400
@@ -36,6 +36,8 @@
 GType gsf_output_gzip_get_type      (void);
 /* void  gsf_output_gzip_register_type (GTypeModule *module); glib dynamic 
types are not thread safe */
 
+GsfOutput *gsf_output_gzip_new_full (GsfOutput *sink, gint compress_level, 
GError **err);
+
 GsfOutput *gsf_output_gzip_new     (GsfOutput *sink, GError **err);
 
 G_END_DECLS
_______________________________________________
gnumeric-list mailing list
gnumeric-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gnumeric-list

Reply via email to