[gcab] Keep files sorted in folder



commit 657facb3654d5ff11cf494349b421b697a9b3af3
Author: Marc-Andrà Lureau <marcandre lureau gmail com>
Date:   Mon Jan 14 01:51:44 2013 +0100

    Keep files sorted in folder

 gcab.c                 |    4 ++--
 libgcab/gcab-cabinet.c |   17 +++++++++--------
 libgcab/gcab-file.h    |    2 +-
 libgcab/gcab-folder.c  |   25 +++++++++++++------------
 libgcab/gcab-folder.h  |    2 +-
 libgcab/gcab-priv.h    |    3 ++-
 tests/testsuite.at     |    7 +++++++
 7 files changed, 35 insertions(+), 25 deletions(-)
---
diff --git a/gcab.c b/gcab.c
index b31c8a5..821a509 100644
--- a/gcab.c
+++ b/gcab.c
@@ -129,10 +129,10 @@ individual files from the archive.\
 
         GPtrArray *folders = gcab_cabinet_get_folders (cabinet);
         for (i = 0; i < folders->len; i++) {
-            GList *l, *list = gcab_folder_get_files (g_ptr_array_index (folders, i));
+            GSList *l, *list = gcab_folder_get_files (g_ptr_array_index (folders, i));
             for (l = list; l != NULL; l = l->next)
                 g_print ("%s\n", gcab_file_get_name (GCAB_FILE (l->data)));
-            g_list_free (list);
+            g_slist_free (list);
         }
         g_object_unref (in);
         g_object_unref (file);
diff --git a/libgcab/gcab-cabinet.c b/libgcab/gcab-cabinet.c
index 20c638a..cc9a072 100644
--- a/libgcab/gcab-cabinet.c
+++ b/libgcab/gcab-cabinet.c
@@ -170,7 +170,6 @@ gcab_cabinet_write (GCabCabinet *self,
     /* FIXME: current limitation of 1 folder */
     g_return_val_if_fail (self->folders->len == 1, FALSE);
 
-    GHashTableIter iter;
     GCabFolder *cabfolder = g_ptr_array_index (self->folders, 0);
     GCabFile *file;
     gsize nfiles = gcab_folder_get_nfiles (cabfolder);
@@ -183,9 +182,10 @@ gcab_cabinet_write (GCabCabinet *self,
     g_data_output_stream_set_byte_order (dstream, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
 
     size_t sumstr = 0;
-    g_hash_table_iter_init (&iter, cabfolder->files);
-    while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&file))
-        sumstr += strlen (file->name) + 1;
+    GSList *l, *files = gcab_folder_get_files (cabfolder);
+
+    for (l = files; l != NULL; l = l->next)
+        sumstr += strlen (GCAB_FILE (l->data)->name) + 1;
 
     folder.typecomp = cabfolder->compression;
     folder.offsetdata = CFI_START + nfiles * 16 + sumstr;
@@ -200,8 +200,8 @@ gcab_cabinet_write (GCabCabinet *self,
     cdata_t block = { 0, };
     guint8 data[DATABLOCKSIZE];
     gsize written;
-    g_hash_table_iter_init (&iter, cabfolder->files);
-    while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&file)) {
+    for (l = files; l != NULL; l = l->next) {
+        file = GCAB_FILE (l->data);
         if (file_callback)
             file_callback (file, callback_data);
 
@@ -244,8 +244,8 @@ gcab_cabinet_write (GCabCabinet *self,
         goto end;
 
     cfile_t *prevf = NULL;
-    g_hash_table_iter_init (&iter, cabfolder->files);
-    while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&file)) {
+    for (l = files; l != NULL; l = l->next) {
+        file = GCAB_FILE (l->data);
         file->cfile.uoffset = prevf ? prevf->uoffset + prevf->usize : 0;
         prevf = &file->cfile;
 
@@ -258,6 +258,7 @@ gcab_cabinet_write (GCabCabinet *self,
 end:
     g_clear_object (&dstream);
     g_clear_object (&in);
+    g_slist_free (files);
 
     return success;
 }
diff --git a/libgcab/gcab-file.h b/libgcab/gcab-file.h
index e477824..f6c2562 100644
--- a/libgcab/gcab-file.h
+++ b/libgcab/gcab-file.h
@@ -35,7 +35,7 @@ G_BEGIN_DECLS
 typedef struct _GCabFileClass GCabFileClass;
 typedef struct _GCabFile GCabFile;
 
-typedef void (*GCabFileCallback) (GCabFile *current, gpointer data);
+typedef gboolean (*GCabFileCallback) (GCabFile *current, gpointer data);
 
 GType gcab_file_get_type (void) G_GNUC_CONST;
 
diff --git a/libgcab/gcab-folder.c b/libgcab/gcab-folder.c
index ec3fe47..07f0df1 100644
--- a/libgcab/gcab-folder.c
+++ b/libgcab/gcab-folder.c
@@ -17,7 +17,8 @@ G_DEFINE_TYPE (GCabFolder, gcab_folder, G_TYPE_OBJECT);
 static void
 gcab_folder_init (GCabFolder *self)
 {
-    self->files = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+    self->files = NULL;
+    self->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
 }
 
 static void
@@ -25,7 +26,8 @@ gcab_folder_finalize (GObject *object)
 {
     GCabFolder *self = GCAB_FOLDER (object);
 
-    g_hash_table_unref (self->files);
+    g_slist_free_full (self->files, g_object_unref);
+    g_hash_table_unref (self->hash);
     if (self->reserved)
         g_byte_array_unref (self->reserved);
 
@@ -100,12 +102,10 @@ G_GNUC_INTERNAL gsize
 gcab_folder_get_ndatablocks (GCabFolder *self)
 {
     gsize total_size = 0;
-    GHashTableIter iter;
-    GCabFile *file;
+    GSList *l;
 
-    g_hash_table_iter_init (&iter, self->files);
-    while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&file))
-        total_size += file->cfile.usize;
+    for (l = self->files; l != NULL; l = l->next)
+        total_size += GCAB_FILE (l->data)->cfile.usize;
 
     return total_size / DATABLOCKSIZE + 1 ;
 }
@@ -113,11 +113,12 @@ gcab_folder_get_ndatablocks (GCabFolder *self)
 static gboolean
 add_file (GCabFolder *self, GCabFile *file)
 {
-    if (g_hash_table_lookup (self->files, (gpointer)gcab_file_get_name (file)))
+    if (g_hash_table_lookup (self->hash, (gpointer)gcab_file_get_name (file)))
         return FALSE;
 
-    g_hash_table_insert (self->files,
+    g_hash_table_insert (self->hash,
                          (gpointer)gcab_file_get_name (file), g_object_ref (file));
+    self->files = g_slist_prepend (self->files, g_object_ref (file));
 
     return TRUE;
 }
@@ -228,7 +229,7 @@ gcab_folder_get_nfiles (GCabFolder *self)
 {
     g_return_val_if_fail (GCAB_IS_FOLDER (self), 0);
 
-    return g_hash_table_size (self->files);
+    return g_hash_table_size (self->hash);
 }
 
 /**
@@ -259,10 +260,10 @@ gcab_folder_new_with_cfolder (const cfolder_t *folder)
  *
  * Returns: (element-type GCabFile) (transfer full): list of files
  **/
-GList *
+GSList *
 gcab_folder_get_files (GCabFolder *self)
 {
     g_return_val_if_fail (GCAB_IS_FOLDER (self), 0);
 
-    return g_hash_table_get_values (self->files);
+    return g_slist_reverse (g_slist_copy (self->files));
 }
diff --git a/libgcab/gcab-folder.h b/libgcab/gcab-folder.h
index f8a7ac4..9df90c7 100644
--- a/libgcab/gcab-folder.h
+++ b/libgcab/gcab-folder.h
@@ -51,7 +51,7 @@ gboolean        gcab_folder_add_file          (GCabFolder *cabfolder,
                                                GCancellable *cancellable,
                                                GError **error);
 guint           gcab_folder_get_nfiles        (GCabFolder *cabfolder);
-GList *         gcab_folder_get_files         (GCabFolder *cabfolder);
+GSList *        gcab_folder_get_files         (GCabFolder *cabfolder);
 
 G_END_DECLS
 
diff --git a/libgcab/gcab-priv.h b/libgcab/gcab-priv.h
index 04f798f..5cf8eeb 100644
--- a/libgcab/gcab-priv.h
+++ b/libgcab/gcab-priv.h
@@ -22,7 +22,8 @@ struct _GCabFolder
 {
     GObject parent_instance;
 
-    GHashTable *files;
+    GSList *files;
+    GHashTable *hash;
     GCabCompression compression;
     GByteArray *reserved;
 };
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d317101..0d52d62 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -53,3 +53,10 @@ cp test.txt expout
 AT_CHECK([cabextract -q out.cab], [0])
 AT_CHECK([cat test.txt], [0], [expout])
 AT_CLEANUP
+
+AT_SETUP([Check sorted files])
+m4_define([FILES], [a o b c d q r s e f j l m n p t u v w x y z g h i k])
+touch FILES
+AT_CHECK_GCAB([-cz out.cab FILES], [0], [ignore], [ignore])
+AT_CHECK_GCAB([-t out.cab | tr "\\n" " "], [0], [FILES ], [ignore])
+AT_CLEANUP



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