[libgsf] GsfInput: Add modtime support.



commit 13bf341e8e8f499ff866ee00cdfba14c9de87921
Author: Morten Welinder <terra gnome org>
Date:   Mon Mar 4 11:09:54 2013 -0500

    GsfInput: Add modtime support.

 ChangeLog            |    5 ++
 NEWS                 |    1 +
 gsf/gsf-input-gzip.c |    7 +++
 gsf/gsf-input-impl.h |    1 +
 gsf/gsf-input.c      |  100 ++++++++++++++++++++++++++++++++++++++------------
 gsf/gsf-input.h      |    2 +
 6 files changed, 92 insertions(+), 24 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 53e8999..356df53 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2013-03-04  Morten Welinder  <terra gnome org>
 
+       * gsf/gsf-input.c (gsf_input_get_property): Add new modtime
+       property.
+
+       * gsf/gsf-input-gzip.c (check_header): Set modtime when available.
+
        * gsf/gsf-input.c (gsf_input_uncompress): Fix potential failure
        with bzip'd input.
 
diff --git a/NEWS b/NEWS
index 6fc7259..6561512 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ Morten:
        * Property documentation fixes.
        * I18n fixes for property strings.
        * Fix uncompress problem with bzip'd files.
+       * Add modtime support for GsfInput.
 
 --------------------------------------------------------------------------
 libgsf 1.14.26
diff --git a/gsf/gsf-input-gzip.c b/gsf/gsf-input-gzip.c
index d113bca..403be96 100644
--- a/gsf/gsf-input-gzip.c
+++ b/gsf/gsf-input-gzip.c
@@ -81,6 +81,7 @@ check_header (GsfInputGZip *input)
                static guint8 const signature[2] = {0x1f, 0x8b};
                guint8 const *data;
                unsigned flags, len;
+               guint32 modtime;
 
                /* Check signature */
                if (NULL == (data = gsf_input_read (input->source, 2 + 1 + 1 + 6, NULL)) ||
@@ -92,6 +93,12 @@ check_header (GsfInputGZip *input)
                if (data[2] != Z_DEFLATED || (flags & ~GZIP_HEADER_FLAGS) != 0)
                        return TRUE;
 
+               modtime = GSF_LE_GET_GUINT32 (data + 4);
+               if (modtime != 0)
+                       gsf_input_set_modtime
+                               (GSF_INPUT (input),
+                                g_date_time_new_from_unix_utc (modtime));
+
                /* If we have the size, don't bother seeking to the end.  */
                if (input->uncompressed_size < 0) {
                        /* Get the uncompressed size */
diff --git a/gsf/gsf-input-impl.h b/gsf/gsf-input-impl.h
index 36ce3ba..35a7473 100644
--- a/gsf/gsf-input-impl.h
+++ b/gsf/gsf-input-impl.h
@@ -60,6 +60,7 @@ gboolean gsf_input_set_name    (GsfInput *input, char const *name);
 gboolean gsf_input_set_name_from_filename (GsfInput *input, char const *filename);
 gboolean gsf_input_set_container (GsfInput *input, GsfInfile *container);
 gboolean gsf_input_set_size     (GsfInput *input, gsf_off_t size);
+gboolean gsf_input_set_modtime   (GsfInput *input, GDateTime *modtime);
 gboolean gsf_input_seek_emulate  (GsfInput *input, gsf_off_t pos);
 
 G_END_DECLS
diff --git a/gsf/gsf-input.c b/gsf/gsf-input.c
index 2b160de..bacfc5b 100644
--- a/gsf/gsf-input.c
+++ b/gsf/gsf-input.c
@@ -26,6 +26,17 @@
 
 #include <string.h>
 
+
+/*
+ * FIXME!
+ *
+ * We cannot extend GsfInput, so for now we hang this on the object as
+ * an attribute.
+ */
+#define MODTIME_ATTR "GsfInput::modtime"
+
+
+
 #define GET_CLASS(instance) G_TYPE_INSTANCE_GET_CLASS (instance, GSF_INPUT_TYPE, GsfInputClass)
 
 static GObjectClass *parent_class;
@@ -36,47 +47,38 @@ enum {
        PROP_SIZE,
        PROP_EOF,
        PROP_REMAINING,
-       PROP_POS
+       PROP_POS,
+       PROP_MODTIME
 };
 
-#if 0
-static void
-gsf_input_set_property (GObject      *object,
-                       guint         property_id,
-                       GValue const *value,
-                       GParamSpec   *pspec)
-{
-       switch (property_id)
-               {
-               default:
-                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-                       break;
-               }
-}
-#endif
-
 static void
 gsf_input_get_property (GObject     *object,
                        guint        property_id,
                        GValue      *value,
                        GParamSpec  *pspec)
 {
+       GsfInput *input = GSF_INPUT (object);
+
        /* gsf_off_t is typedef'd to gint64 */
+
        switch (property_id) {
        case PROP_NAME:
-               g_value_set_string (value, gsf_input_name (GSF_INPUT (object)));
+               g_value_set_string (value, gsf_input_name (input));
                break;
        case PROP_SIZE:
-               g_value_set_int64 (value, gsf_input_size (GSF_INPUT (object)));
+               g_value_set_int64 (value, gsf_input_size (input));
                break;
        case PROP_EOF:
-               g_value_set_boolean (value, gsf_input_eof (GSF_INPUT (object)));
+               g_value_set_boolean (value, gsf_input_eof (input));
                break;
        case PROP_REMAINING:
-               g_value_set_int64 (value, gsf_input_remaining (GSF_INPUT (object)));
+               g_value_set_int64 (value, gsf_input_remaining (input));
                break;
        case PROP_POS:
-               g_value_set_int64 (value, gsf_input_tell (GSF_INPUT (object)));
+               g_value_set_int64 (value, gsf_input_tell (input));
+               break;
+       case PROP_MODTIME:
+               g_value_set_boxed (value, gsf_input_get_modtime (input));
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -91,6 +93,7 @@ gsf_input_dispose (GObject *obj)
 
        gsf_input_set_container (input, NULL);
        gsf_input_set_name (input, NULL);
+       gsf_input_set_modtime (input, NULL);
 
        parent_class->dispose (obj);
 }
@@ -112,7 +115,6 @@ gsf_input_class_init (GObjectClass *gobject_class)
        parent_class = g_type_class_peek_parent (gobject_class);
 
        gobject_class->dispose = gsf_input_dispose;
-       /* gobject_class->set_property = gsf_input_set_property; */
        gobject_class->get_property = gsf_input_get_property;
 
        g_object_class_install_property
@@ -169,6 +171,17 @@ gsf_input_class_init (GObjectClass *gobject_class)
                                     0, G_MAXINT64, 0,
                                     GSF_PARAM_STATIC |
                                     G_PARAM_READABLE));
+
+       g_object_class_install_property
+               (gobject_class,
+                PROP_MODTIME,
+                g_param_spec_boxed
+                ("modtime",
+                 _("Modification time"),
+                 _("An optional GDateTime representing the time the input was last changed"),
+                 G_TYPE_DATE_TIME,
+                 GSF_PARAM_STATIC |
+                 G_PARAM_READABLE));
 }
 
 GSF_CLASS_ABSTRACT (GsfInput, gsf_input,
@@ -286,7 +299,7 @@ gsf_input_size (GsfInput *input)
  * gsf_input_eof:
  * @input: the input
  *
- * Are we at the end of the file ?
+ * Are we at the end of the file?
  *
  * Returns: %TRUE if the input is at the eof.
  **/
@@ -539,6 +552,45 @@ gsf_input_seek_emulate (GsfInput *input, gsf_off_t pos)
        return FALSE;
 }
 
+/**
+ * gsf_input_get_modtime:
+ * @input: the input stream
+ *
+ * Returns: (transfer none): A #GDateTime representing when the input
+ * was last modified, or %NULL if not known.
+ */
+GDateTime *
+gsf_input_get_modtime (GsfInput *input)
+{
+       g_return_val_if_fail (GSF_IS_INPUT (input), NULL);
+
+       return g_object_get_data (G_OBJECT (input), MODTIME_ATTR);
+}
+
+/**
+ * gsf_input_set_modtime:
+ * @input: the input stream
+ * @modtime: (transfer full) (allow-none): the new modification time.
+ *
+ * protected.
+ *
+ * Returns: %TRUE if the assignment was ok.
+ */
+gboolean
+gsf_input_set_modtime (GsfInput *input, GDateTime *modtime)
+{
+       g_return_val_if_fail (GSF_IS_INPUT (input), FALSE);
+
+       /* This actually also works for null modtime.  */
+       g_object_set_data_full (G_OBJECT (input),
+                               MODTIME_ATTR, modtime,
+                               (GDestroyNotify)g_date_time_unref);
+
+       return TRUE;
+}
+
+
+
 /****************************************************************************/
 
 /**
diff --git a/gsf/gsf-input.h b/gsf/gsf-input.h
index 969dc3c..c388454 100644
--- a/gsf/gsf-input.h
+++ b/gsf/gsf-input.h
@@ -52,6 +52,8 @@ gsf_off_t     gsf_input_tell    (GsfInput *input);
 gboolean      gsf_input_seek     (GsfInput *input,
                                   gsf_off_t offset, GSeekType whence);
 
+GDateTime *   gsf_input_get_modtime (GsfInput *input);
+
 /* Utilities */
 gboolean  gsf_input_copy       (GsfInput *input, GsfOutput *output);
 GsfInput *gsf_input_uncompress (GsfInput *src);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]