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