X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgzlibcompressor.c;h=68445d05afa6687f58e8a95fa2f6f00c59566f65;hb=7fd6f07d498063470903a886b4805a13bd333908;hp=fa657facaea2a02ed5259c87108009a039159a5a;hpb=69801f8dc84c0c9403df6802eccc5d03328cd3ae;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gzlibcompressor.c b/gio/gzlibcompressor.c index fa657fa..68445d0 100644 --- a/gio/gzlibcompressor.c +++ b/gio/gzlibcompressor.c @@ -13,32 +13,31 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: Alexander Larsson */ #include "config.h" +#include "gzlibcompressor.h" + #include #include #include -#include "gzlibcompressor.h" -#include "glib.h" +#include "gfileinfo.h" #include "gioerror.h" -#include "glibintl.h" #include "gioenums.h" #include "gioenumtypes.h" +#include "glibintl.h" -#include "gioalias.h" enum { PROP_0, PROP_FORMAT, - PROP_LEVEL + PROP_LEVEL, + PROP_FILE_INFO }; /** @@ -64,8 +63,37 @@ struct _GZlibCompressor GZlibCompressorFormat format; int level; z_stream zstream; + gz_header gzheader; + GFileInfo *file_info; }; +static void +g_zlib_compressor_set_gzheader (GZlibCompressor *compressor) +{ + /* On win32, these functions were not exported before 1.2.4 */ +#if !defined (G_OS_WIN32) || ZLIB_VERNUM >= 0x1240 + const gchar *filename; + + if (compressor->format != G_ZLIB_COMPRESSOR_FORMAT_GZIP || + compressor->file_info == NULL) + 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; + + 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\n", compressor->zstream.msg); +#endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */ +} + G_DEFINE_TYPE_WITH_CODE (GZlibCompressor, g_zlib_compressor, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER, g_zlib_compressor_iface_init)) @@ -79,6 +107,9 @@ g_zlib_compressor_finalize (GObject *object) deflateEnd (&compressor->zstream); + if (compressor->file_info) + g_object_unref (compressor->file_info); + G_OBJECT_CLASS (g_zlib_compressor_parent_class)->finalize (object); } @@ -103,6 +134,10 @@ g_zlib_compressor_set_property (GObject *object, compressor->level = g_value_get_int (value); break; + case PROP_FILE_INFO: + g_zlib_compressor_set_file_info (compressor, g_value_get_object (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -130,6 +165,10 @@ g_zlib_compressor_get_property (GObject *object, g_value_set_int (value, compressor->level); break; + case PROP_FILE_INFO: + g_value_set_object (value, compressor->file_info); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -173,6 +212,8 @@ g_zlib_compressor_constructed (GObject *object) if (res != Z_OK) g_warning ("unexpected zlib error: %s\n", compressor->zstream.msg); + + g_zlib_compressor_set_gzheader (compressor); } static void @@ -204,6 +245,24 @@ g_zlib_compressor_class_init (GZlibCompressorClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + + /** + * GZlibCompressor:file-info: + * + * If set to a non-%NULL #GFileInfo object, and #GZlibCompressor:format is + * %G_ZLIB_COMPRESSOR_FORMAT_GZIP, the compressor will write the file name + * and modification time from the file info to the GZIP header. + * + * Since: 2.26 + */ + g_object_class_install_property (gobject_class, + PROP_FILE_INFO, + g_param_spec_object ("file-info", + P_("file info"), + P_("File info"), + G_TYPE_FILE_INFO, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); } /** @@ -231,6 +290,59 @@ g_zlib_compressor_new (GZlibCompressorFormat format, return compressor; } +/** + * g_zlib_compressor_get_file_info: + * @compressor: a #GZlibCompressor + * + * Returns the #GZlibCompressor:file-info property. + * + * Returns: (transfer none): a #GFileInfo, or %NULL + * + * Since: 2.26 + */ +GFileInfo * +g_zlib_compressor_get_file_info (GZlibCompressor *compressor) +{ + g_return_val_if_fail (G_IS_ZLIB_COMPRESSOR (compressor), NULL); + + return compressor->file_info; +} + +/** + * g_zlib_compressor_set_file_info: + * @compressor: a #GZlibCompressor + * @file_info: (allow-none): a #GFileInfo + * + * Sets @file_info in @compressor. If non-%NULL, and @compressor's + * #GZlibCompressor:format property is %G_ZLIB_COMPRESSOR_FORMAT_GZIP, + * it will be used to set the file name and modification time in + * the GZIP header of the compressed data. + * + * 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 g_converter_reset(). + * + * Since: 2.26 + */ +void +g_zlib_compressor_set_file_info (GZlibCompressor *compressor, + GFileInfo *file_info) +{ + g_return_if_fail (G_IS_ZLIB_COMPRESSOR (compressor)); + + if (file_info == compressor->file_info) + return; + + if (compressor->file_info) + g_object_unref (compressor->file_info); + if (file_info) + g_object_ref (file_info); + compressor->file_info = file_info; + g_object_notify (G_OBJECT (compressor), "file-info"); + + g_zlib_compressor_set_gzheader (compressor); +} + static void g_zlib_compressor_reset (GConverter *converter) { @@ -240,6 +352,9 @@ g_zlib_compressor_reset (GConverter *converter) res = deflateReset (&compressor->zstream); if (res != Z_OK) g_warning ("unexpected zlib error: %s\n", compressor->zstream.msg); + + /* deflateReset reset the header too, so re-set it */ + g_zlib_compressor_set_gzheader (compressor); } static GConverterResult @@ -319,6 +434,3 @@ g_zlib_compressor_iface_init (GConverterIface *iface) iface->convert = g_zlib_compressor_convert; iface->reset = g_zlib_compressor_reset; } - -#define __G_ZLIB_COMPRESSOR_C__ -#include "gioaliasdef.c"