X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgzlibcompressor.c;h=68445d05afa6687f58e8a95fa2f6f00c59566f65;hb=33b9935efc82f8cc4747dfea2743129dfc418d19;hp=20fd8ff0f8abed37ab917088fed7d406352311b7;hpb=92b9218cbf8cbc594c3a067b2dc09730416df85f;p=platform%2Fupstream%2Fglib.git
diff --git a/gio/gzlibcompressor.c b/gio/gzlibcompressor.c
index 20fd8ff..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
};
/**
@@ -46,8 +45,8 @@ enum {
* @short_description: Zlib compressor
* @include: gio/gio.h
*
- * #GZlibCompressor is an implementation of #GCompressor that
- * decompresses data compressed with zlib.
+ * #GZlibCompressor is an implementation of #GConverter that
+ * compresses data using zlib.
*/
static void g_zlib_compressor_iface_init (GConverterIface *iface);
@@ -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;
@@ -157,7 +196,15 @@ g_zlib_compressor_constructed (GObject *object)
MAX_WBITS + 16, 8,
Z_DEFAULT_STRATEGY);
}
- else
+ else if (compressor->format == G_ZLIB_COMPRESSOR_FORMAT_RAW)
+ {
+ /* negative wbits for raw */
+ res = deflateInit2 (&compressor->zstream,
+ compressor->level, Z_DEFLATED,
+ -MAX_WBITS, 8,
+ Z_DEFAULT_STRATEGY);
+ }
+ else /* ZLIB */
res = deflateInit (&compressor->zstream, compressor->level);
if (res == Z_MEM_ERROR )
@@ -165,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
@@ -183,7 +232,7 @@ g_zlib_compressor_class_init (GZlibCompressorClass *klass)
P_("compression format"),
P_("The format of the compressed data"),
G_TYPE_ZLIB_COMPRESSOR_FORMAT,
- G_ZLIB_COMPRESSOR_FORMAT_RAW,
+ G_ZLIB_COMPRESSOR_FORMAT_ZLIB,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
@@ -196,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));
}
/**
@@ -223,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)
{
@@ -232,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
@@ -311,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"