[libgsf] Modtime improvements.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] Modtime improvements.
- Date: Mon, 4 Mar 2013 18:39:47 +0000 (UTC)
commit 225faeb7d61e7dfe6552544add6ad14a38eabff8
Author: Morten Welinder <terra gnome org>
Date: Mon Mar 4 13:39:08 2013 -0500
Modtime improvements.
Zip files members can support modtime.
ChangeLog | 8 ++++++++
gsf/gsf-infile-zip.c | 28 +++++++++++++++++++++++++++-
gsf/gsf-outfile-zip.c | 32 +++++++++++++++++++++++---------
gsf/gsf-output-impl.h | 1 +
gsf/gsf-output.c | 3 +--
5 files changed, 60 insertions(+), 12 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8a463c0..4b32348 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2013-03-04 Morten Welinder <terra gnome org>
+ * gsf/gsf-infile-zip.c (gsf_infile_zip_new_child): Set modtime of
+ child.
+ (zip_dirent_new_in): Read modtime from file.
+
+ * gsf/gsf-outfile-zip.c (gsf_outfile_zip_new_child): Parent's
+ modtime is child's default.
+ (gsf_outfile_zip_constructor): Default modtime is now.
+
* configure.ac: Check for utime.h and sys/utime.h. Check for
stat.st_mtimensec and stat.st_mtim.tv_nsec.
diff --git a/gsf/gsf-infile-zip.c b/gsf/gsf-infile-zip.c
index 8c8d2a1..d987d89 100644
--- a/gsf/gsf-infile-zip.c
+++ b/gsf/gsf-infile-zip.c
@@ -77,6 +77,26 @@ typedef struct {
#define GSF_INFILE_ZIP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSF_INFILE_ZIP_TYPE, GsfInfileZipClass))
#define GSF_IS_INFILE_ZIP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSF_INFILE_ZIP_TYPE))
+
+static GDateTime *
+zip_make_modtime (guint32 dostime)
+{
+ if (dostime == 0)
+ return NULL;
+ else {
+ gint year = (dostime >> 25) + 1980;
+ gint month = (dostime >> 21) & 0x0f;
+ gint day = (dostime >> 16) & 0x1f;
+ gint hour = (dostime >> 11) & 0x0f;
+ gint minute = (dostime >> 5) & 0x3f;
+ gint second = (dostime & 0x1f) * 2;
+ GDateTime *modtime =
+ g_date_time_new_utc (year, month, day,
+ hour, minute, second);
+ return modtime;
+ }
+}
+
static GsfZipVDir *
vdir_child_by_name (GsfZipVDir *vdir, char const *name)
{
@@ -190,7 +210,7 @@ zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
GsfZipDirent *dirent;
guint8 const *data;
guint16 name_len, extras_len, comment_len, compr_method, flags;
- guint32 crc32, csize, usize, off;
+ guint32 dostime, crc32, csize, usize, off;
gchar *name;
/* Read data and check the header */
@@ -206,6 +226,7 @@ zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
flags = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_FLAGS);
compr_method = GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMPR_METHOD);
+ dostime = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_DOSTIME);
crc32 = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CRC32);
csize = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CSIZE);
usize = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_USIZE);
@@ -227,6 +248,7 @@ zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
dirent->csize = csize;
dirent->usize = usize;
dirent->offset = off;
+ dirent->dostime = dostime;
#if 0
g_print ("%s = 0x%x @ %" GSF_OFF_T_FORMAT "\n", name, off, *offset);
#endif
@@ -614,6 +636,10 @@ gsf_infile_zip_new_child (GsfInfileZip *parent, GsfZipVDir *vdir, GError **err)
if (dirent) {
gsf_input_set_size (GSF_INPUT (child),
(gsf_off_t) dirent->usize);
+ if (dirent->dostime)
+ gsf_input_set_modtime (GSF_INPUT (child),
+ zip_make_modtime (dirent->dostime));
+
if (zip_child_init (child, err) != FALSE) {
g_object_unref (child);
return NULL;
diff --git a/gsf/gsf-outfile-zip.c b/gsf/gsf-outfile-zip.c
index 5d319fb..1067676 100644
--- a/gsf/gsf-outfile-zip.c
+++ b/gsf/gsf-outfile-zip.c
@@ -132,6 +132,10 @@ gsf_outfile_zip_constructor (GType type,
gsf_output_set_container (GSF_OUTPUT (zip), NULL);
}
+ if (!gsf_output_get_modtime (GSF_OUTPUT (zip)))
+ gsf_output_set_modtime (GSF_OUTPUT (zip),
+ g_date_time_new_now_utc ());
+
return (GObject *)zip;
}
@@ -259,17 +263,26 @@ stream_name_build (GsfOutfileZip *zip)
}
static guint32
-zip_time_make (time_t t)
+zip_time_make (GDateTime *modtime)
{
- struct tm *localnow = localtime (&t);
+ gint year, month, day, hour, minute, second;
guint32 ztime;
- ztime = (localnow->tm_year - 80) & 0x7f;
- ztime = (ztime << 4) | ((localnow->tm_mon + 1) & 0x0f);
- ztime = (ztime << 5) | (localnow->tm_mday & 0x1f);
- ztime = (ztime << 5) | (localnow->tm_hour & 0x1f);
- ztime = (ztime << 6) | (localnow->tm_min & 0x3f);
- ztime = (ztime << 5) | ((localnow->tm_sec / 2) & 0x1f);
+ g_return_val_if_fail (modtime != NULL, 0);
+
+ g_date_time_get_ymd (modtime, &year, &month, &day);
+ if (year < 1980 || year > 1980 + 0x7f)
+ return 0;
+ hour = g_date_time_get_hour (modtime);
+ minute = g_date_time_get_minute (modtime);
+ second = g_date_time_get_second (modtime);
+
+ ztime = (year - 1980) & 0x7f;
+ ztime = (ztime << 4) | (month & 0x0f);
+ ztime = (ztime << 5) | (day & 0x1f);
+ ztime = (ztime << 5) | (hour & 0x1f);
+ ztime = (ztime << 6) | (minute & 0x3f);
+ ztime = (ztime << 5) | ((second / 2) & 0x1f);
return ztime;
}
@@ -289,7 +302,7 @@ zip_dirent_new_out (GsfOutfileZip *zip)
GsfZipDirent *dirent = gsf_zip_dirent_new ();
dirent->name = stream_name_build (zip);
dirent->compr_method = zip->compression_method;
- dirent->dostime = zip_time_make (time (NULL));
+ dirent->dostime = zip_time_make (gsf_output_get_modtime (GSF_OUTPUT (zip)));
zip_dirent_update_flags (dirent);
return dirent;
}
@@ -581,6 +594,7 @@ gsf_outfile_zip_new_child (GsfOutfile *parent,
¶ms, &n_params,
"sink", zip_parent->sink,
"entry-name", name,
+ "modtime", gsf_output_get_modtime (GSF_OUTPUT (parent)),
NULL);
gsf_property_settings_collect_valist (GSF_OUTFILE_ZIP_TYPE,
¶ms, &n_params,
diff --git a/gsf/gsf-output-impl.h b/gsf/gsf-output-impl.h
index 7ef99cc..c3ba763 100644
--- a/gsf/gsf-output-impl.h
+++ b/gsf/gsf-output-impl.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
gboolean gsf_output_set_name (GsfOutput *output, char const *name);
gboolean gsf_output_set_name_from_filename (GsfOutput *output, char const *filename);
gboolean gsf_output_set_container (GsfOutput *output, GsfOutfile *container);
+gboolean gsf_output_set_modtime (GsfOutput *output, GDateTime *modtime);
G_END_DECLS
diff --git a/gsf/gsf-output.c b/gsf/gsf-output.c
index a40d7e5..277284c 100644
--- a/gsf/gsf-output.c
+++ b/gsf/gsf-output.c
@@ -37,7 +37,6 @@
static gsf_off_t gsf_output_real_vprintf (GsfOutput *output,
char const* format, va_list args) G_GNUC_PRINTF (2, 0);
-static gboolean gsf_output_set_modtime (GsfOutput *output, GDateTime *modtime);
#define GET_CLASS(instance) G_TYPE_INSTANCE_GET_CLASS (instance, GSF_OUTPUT_TYPE, GsfOutputClass)
@@ -603,7 +602,7 @@ gsf_output_get_modtime (GsfOutput *output)
*
* Returns: %TRUE if the assignment was ok.
*/
-static gboolean
+gboolean
gsf_output_set_modtime (GsfOutput *output, GDateTime *modtime)
{
g_return_val_if_fail (GSF_IS_OUTPUT (output), FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]