mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-02 02:40:07 +02:00
Merge branch 'wip/otte/zlib-os' into 'main'
gio: Add GZlibCompressor:os property Closes #3663 See merge request GNOME/glib!4597
This commit is contained in:
commit
997c41b648
@ -39,7 +39,8 @@ enum {
|
||||
PROP_0,
|
||||
PROP_FORMAT,
|
||||
PROP_LEVEL,
|
||||
PROP_FILE_INFO
|
||||
PROP_FILE_INFO,
|
||||
PROP_OS
|
||||
};
|
||||
|
||||
/**
|
||||
@ -60,6 +61,7 @@ struct _GZlibCompressor
|
||||
z_stream zstream;
|
||||
gz_header gzheader;
|
||||
GFileInfo *file_info;
|
||||
int os;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -70,19 +72,27 @@ g_zlib_compressor_set_gzheader (GZlibCompressor *compressor)
|
||||
const gchar *filename;
|
||||
|
||||
if (compressor->format != G_ZLIB_COMPRESSOR_FORMAT_GZIP ||
|
||||
compressor->file_info == NULL)
|
||||
(compressor->file_info == NULL &&
|
||||
compressor->os < 0))
|
||||
return;
|
||||
|
||||
memset (&compressor->gzheader, 0, sizeof (gz_header));
|
||||
compressor->gzheader.os = 0x03; /* Unix */
|
||||
|
||||
filename = g_file_info_get_name (compressor->file_info);
|
||||
compressor->gzheader.name = (Bytef *) filename;
|
||||
compressor->gzheader.name_max = filename ? strlen (filename) + 1 : 0;
|
||||
if (compressor->os >= 0)
|
||||
compressor->gzheader.os = compressor->os;
|
||||
else
|
||||
compressor->gzheader.os = 0x03; /* Unix */
|
||||
|
||||
compressor->gzheader.time =
|
||||
(uLong) g_file_info_get_attribute_uint64 (compressor->file_info,
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||
if (compressor->file_info)
|
||||
{
|
||||
filename = g_file_info_get_name (compressor->file_info);
|
||||
compressor->gzheader.name = (Bytef *) filename;
|
||||
compressor->gzheader.name_max = filename ? strlen (filename) + 1 : 0;
|
||||
|
||||
compressor->gzheader.time =
|
||||
(uLong) g_file_info_get_attribute_uint64 (compressor->file_info,
|
||||
G_FILE_ATTRIBUTE_TIME_MODIFIED);
|
||||
}
|
||||
|
||||
if (deflateSetHeader (&compressor->zstream, &compressor->gzheader) != Z_OK)
|
||||
g_warning ("unexpected zlib error: %s", compressor->zstream.msg);
|
||||
@ -133,6 +143,10 @@ g_zlib_compressor_set_property (GObject *object,
|
||||
g_zlib_compressor_set_file_info (compressor, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_OS:
|
||||
g_zlib_compressor_set_os (compressor, g_value_get_int (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -164,6 +178,10 @@ g_zlib_compressor_get_property (GObject *object,
|
||||
g_value_set_object (value, compressor->file_info);
|
||||
break;
|
||||
|
||||
case PROP_OS:
|
||||
g_value_set_int (value, compressor->os);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -173,6 +191,7 @@ g_zlib_compressor_get_property (GObject *object,
|
||||
static void
|
||||
g_zlib_compressor_init (GZlibCompressor *compressor)
|
||||
{
|
||||
compressor->os = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -268,6 +287,31 @@ g_zlib_compressor_class_init (GZlibCompressorClass *klass)
|
||||
G_TYPE_FILE_INFO,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GZlibCompressor:os:
|
||||
*
|
||||
* The OS code of the gzip header.
|
||||
*
|
||||
* This will be used if set to a non-negative value, and if
|
||||
* [property@Gio.ZlibCompressor:format] is
|
||||
* [enum@Gio.ZlibCompressorFormat.GZIP], the compressor will set the OS code of
|
||||
* the gzip header to this value.
|
||||
*
|
||||
* If the value is unset, zlib will set the OS code depending on the platform.
|
||||
* This may be undesirable when reproducible output is desired. In that case setting
|
||||
* the OS code to `3` (for Unix) is recommended.
|
||||
*
|
||||
* Since: 2.86
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_OS,
|
||||
g_param_spec_int ("os", NULL, NULL,
|
||||
-1, 255,
|
||||
-1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_EXPLICIT_NOTIFY));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,6 +392,53 @@ g_zlib_compressor_set_file_info (GZlibCompressor *compressor,
|
||||
g_zlib_compressor_set_gzheader (compressor);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_zlib_compressor_get_os:
|
||||
* @compressor: a compressor
|
||||
*
|
||||
* Gets the [property@Gio.ZlibCompressor:os] property.
|
||||
*
|
||||
* Returns: the previously set OS value, or `-1` if unset
|
||||
* Since: 2.86
|
||||
*/
|
||||
int
|
||||
g_zlib_compressor_get_os (GZlibCompressor *compressor)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_ZLIB_COMPRESSOR (compressor), -1);
|
||||
|
||||
return compressor->os;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_zlib_compressor_set_os:
|
||||
* @compressor: a compressor
|
||||
* @os: the OS code to use, or `-1` to unset
|
||||
*
|
||||
* Sets the [property@Gio.ZlibCompressor:os] property.
|
||||
*
|
||||
* Note: it is an error to call this function while a compression is in
|
||||
* progress; it may only be called immediately after creation of @compressor,
|
||||
* or after resetting it with [method@Gio.Converter.reset].
|
||||
*
|
||||
* Since: 2.86
|
||||
*/
|
||||
void
|
||||
g_zlib_compressor_set_os (GZlibCompressor *compressor,
|
||||
int os)
|
||||
{
|
||||
g_return_if_fail (G_IS_ZLIB_COMPRESSOR (compressor));
|
||||
g_return_if_fail (os >= -1 && os < 256);
|
||||
|
||||
if (os == compressor->os)
|
||||
return;
|
||||
|
||||
compressor->os = os;
|
||||
|
||||
g_object_notify (G_OBJECT (compressor), "os");
|
||||
|
||||
g_zlib_compressor_set_gzheader (compressor);
|
||||
}
|
||||
|
||||
static void
|
||||
g_zlib_compressor_reset (GConverter *converter)
|
||||
{
|
||||
|
@ -59,6 +59,12 @@ GIO_AVAILABLE_IN_ALL
|
||||
void g_zlib_compressor_set_file_info (GZlibCompressor *compressor,
|
||||
GFileInfo *file_info);
|
||||
|
||||
GIO_AVAILABLE_IN_2_86
|
||||
int g_zlib_compressor_get_os (GZlibCompressor *compressor);
|
||||
GIO_AVAILABLE_IN_2_86
|
||||
void g_zlib_compressor_set_os (GZlibCompressor *compressor,
|
||||
int os);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_ZLIB_COMPRESSOR_H__ */
|
||||
|
@ -96,6 +96,41 @@ test_convert_bytes (void)
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
static void
|
||||
test_gzip_os_property (void)
|
||||
{
|
||||
const int os_testvalue = 42;
|
||||
const char *data = "Hello World";
|
||||
GBytes *bytes;
|
||||
GZlibCompressor *compressor;
|
||||
GError *error = NULL;
|
||||
GBytes *result;
|
||||
int os;
|
||||
const char *encoded;
|
||||
|
||||
bytes = g_bytes_new_static (data, sizeof (data));
|
||||
|
||||
compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, 9);
|
||||
g_zlib_compressor_set_os (compressor, os_testvalue);
|
||||
g_assert_cmpint (g_zlib_compressor_get_os (compressor), ==, os_testvalue);
|
||||
|
||||
g_object_get (compressor, "os", &os, NULL);
|
||||
g_assert_cmpint (os, ==, os_testvalue);
|
||||
|
||||
result = g_converter_convert_bytes (G_CONVERTER (compressor), bytes, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (result);
|
||||
|
||||
/* The OS is stored in the 10th byte of the header, see RFC 1952 */
|
||||
g_assert_cmpint (g_bytes_get_size (result), >, 10);
|
||||
encoded = g_bytes_get_data (result, NULL);
|
||||
g_assert_cmpint (encoded[9], ==, os_testvalue);
|
||||
|
||||
g_bytes_unref (result);
|
||||
g_object_unref (compressor);
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
@ -104,6 +139,7 @@ main (int argc,
|
||||
|
||||
g_test_add_func ("/converter/bytes", test_convert_bytes);
|
||||
g_test_add_func ("/converter/extra-bytes-at-end", test_extra_bytes_at_end);
|
||||
g_test_add_func ("/converter/gzip-os-property", test_gzip_os_property);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user