[libgsf] GsfInfileMSOle: add modtime support.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] GsfInfileMSOle: add modtime support.
- Date: Thu, 7 Mar 2013 21:55:36 +0000 (UTC)
commit bc5d228beb311f0bad8330aa29ef8f1aa4043b89
Author: Morten Welinder <terra gnome org>
Date: Thu Mar 7 16:55:07 2013 -0500
GsfInfileMSOle: add modtime support.
NEWS | 2 +-
gsf/gsf-infile-msole.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 46 insertions(+), 3 deletions(-)
---
diff --git a/NEWS b/NEWS
index 0051763..fba5e32 100644
--- a/NEWS
+++ b/NEWS
@@ -6,7 +6,7 @@ Morten:
* I18n fixes for property strings.
* Fix uncompress problem with bzip'd files.
* Add modtime support for GsfInput, GsfInputStdio, GsfInputGzip.
- * Add modtime support for GsfInfileZip, GsfInfileTar.
+ * Add modtime support for GsfInfileZip, GsfInfileTar, GsfInfileMSOle.
* Add modtime support for GsfOutput, GsfOutputStdio, GsfOutputGzip.
* Enhance gsf tool to print modtime and create archives with modtime.
diff --git a/gsf/gsf-infile-msole.c b/gsf/gsf-infile-msole.c
index a6bb268..0a55230 100644
--- a/gsf/gsf-infile-msole.c
+++ b/gsf/gsf-infile-msole.c
@@ -52,6 +52,7 @@ typedef struct {
gboolean is_directory;
GList *children;
unsigned char clsid[16]; /* 16 byte GUID used by some apps */
+ GDateTime *modtime;
} MSOleDirent;
typedef struct {
@@ -277,6 +278,22 @@ ole_dirent_cmp (MSOleDirent const *a, MSOleDirent const *b)
return gsf_msole_sorting_key_cmp (a->key, b->key);
}
+static GDateTime *
+datetime_from_filetime (guint64 ft)
+{
+ static const guint64 epoch = G_GINT64_CONSTANT (11644473600);
+ GTimeVal tv;
+ if (!ft)
+ return NULL;
+
+ /* ft is number of 100ns since Jan 1 1601 */
+
+ tv.tv_usec = (ft % 10000000u) / 10;
+ tv.tv_sec = (ft / 10000000u) - epoch;
+ return g_date_time_new_from_timeval_local (&tv);
+}
+
+
/* Parse dirent number @entry and recursively handle its siblings and children.
* parent is optional. */
static MSOleDirent *
@@ -288,6 +305,7 @@ ole_dirent_new (GsfInfileMSOle *ole, guint32 entry, MSOleDirent *parent,
guint8 const *data;
guint8 type;
guint16 name_len;
+ guint64 ft;
if (entry >= DIRENT_MAGIC_END)
return NULL;
@@ -323,9 +341,12 @@ ole_dirent_new (GsfInfileMSOle *ole, guint32 entry, MSOleDirent *parent,
g_return_val_if_fail (type == DIRENT_TYPE_DIR || type == DIRENT_TYPE_ROOTDIR ||
size <= (guint32)ole->input->size, NULL);
+ ft = GSF_LE_GET_GUINT64 (data + DIRENT_MODIFY_TIME);
+
dirent = g_new0 (MSOleDirent, 1);
dirent->index = entry;
dirent->size = size;
+ dirent->modtime = datetime_from_filetime (ft);
/* Store the class id which is 16 byte identifier used by some apps */
memcpy(dirent->clsid, data + DIRENT_CLSID, sizeof(dirent->clsid));
@@ -395,9 +416,15 @@ ole_dirent_free (MSOleDirent *dirent)
g_free (dirent->name);
gsf_msole_sorting_key_free (dirent->key);
- for (tmp = dirent->children; tmp; tmp = tmp->next)
- ole_dirent_free ((MSOleDirent *)tmp->data);
+ for (tmp = dirent->children; tmp; tmp = tmp->next) {
+ MSOleDirent *child = tmp->data;
+ ole_dirent_free (child);
+ }
g_list_free (dirent->children);
+
+ if (dirent->modtime)
+ g_date_time_unref (dirent->modtime);
+
g_free (dirent);
}
@@ -616,6 +643,17 @@ ole_init_info (GsfInfileMSOle *ole, GError **err)
return TRUE;
}
+ /*
+ * The spec says to ignore modtime for root object. That doesn't
+ * keep files from actually have a modtime there.
+ */
+ if (ole->dirent->modtime) {
+ /* Copy */
+ gsf_input_set_modtime (GSF_INPUT (ole),
+ g_date_time_add (ole->dirent->modtime, 0));
+ }
+
+
return FALSE;
}
@@ -740,6 +778,11 @@ gsf_infile_msole_new_child (GsfInfileMSOle *parent,
child->dirent = dirent;
gsf_input_set_size (GSF_INPUT (child), (gsf_off_t) dirent->size);
+ if (dirent->modtime) {
+ /* Copy */
+ gsf_input_set_modtime (GSF_INPUT (child),
+ g_date_time_add (dirent->modtime, 0));
+ }
/* The root dirent defines the small block file */
if (dirent->index != 0) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]