[gcab] Add gcab_cabinet_get_size()



commit b413983953087bf4b63b00bdccd24790cc4bc753
Author: Richard Hughes <richard hughsie com>
Date:   Fri Dec 29 19:07:58 2017 +0000

    Add gcab_cabinet_get_size()
    
    This allows us to get the compressed archive size.

 libgcab/gcab-cabinet.c |   58 +++++++++++++++++++++++++++++++++--------------
 libgcab/gcab-cabinet.h |    1 +
 libgcab/libgcab.syms   |    1 +
 tests/gcab-self-test.c |   23 +++++++++++++-----
 4 files changed, 59 insertions(+), 24 deletions(-)
---
diff --git a/libgcab/gcab-cabinet.c b/libgcab/gcab-cabinet.c
index b5e2c04..b9866ed 100644
--- a/libgcab/gcab-cabinet.c
+++ b/libgcab/gcab-cabinet.c
@@ -201,6 +201,24 @@ gcab_cabinet_get_folders (GCabCabinet *self)
 }
 
 /**
+ * gcab_cabinet_get_size:
+ * @cabinet:a #GCabCabinet
+ *
+ * Get the size of the compressed cabinet file.
+ *
+ * Returns: size in bytes
+ *
+ * Since: 1.0
+ **/
+guint32
+gcab_cabinet_get_size (GCabCabinet *self)
+{
+    if (self->cheader == NULL)
+        return 0;
+    return self->cheader->size;
+}
+
+/**
  * gcab_cabinet_write:
  * @cabinet: a #GCabCabinet
  * @stream: a #GOutputStream also #GSeekable
@@ -224,10 +242,7 @@ gcab_cabinet_write (GCabCabinet *self,
                     GCancellable *cancellable,
                     GError **error)
 {
-    cheader_t header = {
-        .offsetfiles = CFI_START, // CFHEADER + 1 * CFFOLDER
-        .nfolders = 1, // a single CAB folder is enough
-    };
+    g_autoptr(cheader_t) cheader = g_new0 (cheader_t, 1);
     cfolder_t folder = { 0, };
 
     g_return_val_if_fail (GCAB_IS_CABINET (self), FALSE);
@@ -236,6 +251,10 @@ gcab_cabinet_write (GCabCabinet *self,
     g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
     g_return_val_if_fail (!error || *error == NULL, FALSE);
 
+    /* FIXME: support more than one folder */
+    cheader->offsetfiles = CFI_START; // CFHEADER + 1 * CFFOLDER
+    cheader->nfolders = 1; // a single CAB folder is enough
+
     /* nothing to do */
     if (self->folders->len == 0) {
         g_set_error_literal (error, GCAB_ERROR, GCAB_ERROR_FAILED,
@@ -265,12 +284,12 @@ gcab_cabinet_write (GCabCabinet *self,
     g_data_output_stream_set_byte_order (dstream, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
 
     if (self->reserved) {
-        header.offsetfiles += self->reserved->len + 4;
-        header.flags = CABINET_HEADER_RESERVE;
-        header.res_header = self->reserved->len;
-        header.res_folder = 0;
-        header.res_data = 0;
-        header.reserved = self->reserved->data;
+        cheader->offsetfiles += self->reserved->len + 4;
+        cheader->flags = CABINET_HEADER_RESERVE;
+        cheader->res_header = self->reserved->len;
+        cheader->res_folder = 0;
+        cheader->res_data = 0;
+        cheader->reserved = self->reserved->data;
     }
 
     files = gcab_folder_get_files (cabfolder);
@@ -280,7 +299,7 @@ gcab_cabinet_write (GCabCabinet *self,
     }
 
     folder.typecomp = gcab_folder_get_comptype (cabfolder);
-    folder.offsetdata = header.offsetfiles + nfiles * 16 + sumstr;
+    folder.offsetdata = cheader->offsetfiles + nfiles * 16 + sumstr;
     folder.ndatab = gcab_folder_get_ndatablocks (cabfolder);
 
     /* avoid seeking to allow growing output streams */
@@ -304,7 +323,7 @@ gcab_cabinet_write (GCabCabinet *self,
                                            cancellable, error)) == (DATABLOCKSIZE - offset)) {
             if (!cdata_write (&block, dstream, folder.typecomp, data, DATABLOCKSIZE, &written, cancellable, 
error))
                 return FALSE;
-            header.size += written;
+            cheader->size += written;
             offset = 0;
         }
 
@@ -316,18 +335,18 @@ gcab_cabinet_write (GCabCabinet *self,
     if (offset != 0) {
         if (!cdata_write (&block, dstream, folder.typecomp, data, offset, &written, cancellable, error))
             return FALSE;
-        header.size += written;
+        cheader->size += written;
     }
 
     if (!g_seekable_seek (G_SEEKABLE (out), 0,
                           G_SEEK_SET, cancellable, error))
         return FALSE;
 
-    header.nfiles = nfiles;
-    header.size += header.offsetfiles + nfiles * 16; /* 1st part cfile struct = 16 bytes */
-    header.size += sumstr;
+    cheader->nfiles = nfiles;
+    cheader->size += cheader->offsetfiles + nfiles * 16; /* 1st part cfile struct = 16 bytes */
+    cheader->size += sumstr;
 
-    if (!cheader_write (&header, dstream, cancellable, error))
+    if (!cheader_write (cheader, dstream, cancellable, error))
         return FALSE;
 
     if (!cfolder_write (&folder, dstream, cancellable, error))
@@ -346,6 +365,11 @@ gcab_cabinet_write (GCabCabinet *self,
             return FALSE;
     }
 
+    /* replace the cached copy */
+    if (self->cheader != NULL)
+        cheader_free (self->cheader);
+    self->cheader = g_steal_pointer (&cheader);
+
     return TRUE;
 }
 
diff --git a/libgcab/gcab-cabinet.h b/libgcab/gcab-cabinet.h
index 57893ee..36d13b1 100644
--- a/libgcab/gcab-cabinet.h
+++ b/libgcab/gcab-cabinet.h
@@ -70,6 +70,7 @@ gboolean           gcab_cabinet_load          (GCabCabinet *cabinet,
                                                GError **error);
 
 GPtrArray *        gcab_cabinet_get_folders   (GCabCabinet *cabinet);
+guint32            gcab_cabinet_get_size      (GCabCabinet *cabinet);
 
 gboolean           gcab_cabinet_add_folder    (GCabCabinet *cabinet,
                                                GCabFolder *folder,
diff --git a/libgcab/libgcab.syms b/libgcab/libgcab.syms
index 5bff171..c0ad194 100644
--- a/libgcab/libgcab.syms
+++ b/libgcab/libgcab.syms
@@ -43,6 +43,7 @@ LIBGCAB1_0.6 {
 } LIBGCAB1_0.5;
 
 LIBGCAB1_1.0 {
+        gcab_cabinet_get_size;
         gcab_file_get_bytes;
         gcab_file_new_with_bytes;
         gcab_file_set_attributes;
diff --git a/tests/gcab-self-test.c b/tests/gcab-self-test.c
index bfe3199..aee690b 100644
--- a/tests/gcab-self-test.c
+++ b/tests/gcab-self-test.c
@@ -217,6 +217,7 @@ gcab_test_cabinet_func (void)
 
     /* create cabinet */
     cabinet = gcab_cabinet_new ();
+    g_assert_cmpint (gcab_cabinet_get_size (cabinet), ==, 0);
 
     /* add folder */
     folder = gcab_folder_new (GCAB_COMPRESSION_NONE);
@@ -335,12 +336,13 @@ gcab_test_cabinet_load_func (void)
 {
     struct {
         const gchar *fn;
+        guint32 size;
         GCabCompression comptype;
     } tests[] = {
-        { "test-none.cab",          GCAB_COMPRESSION_NONE },
-        { "test-mszip.cab",         GCAB_COMPRESSION_MSZIP },
-        { "test-signed.cab",        GCAB_COMPRESSION_NONE },
-        { NULL,                     0 }
+        { "test-none.cab",          115,    GCAB_COMPRESSION_NONE },
+        { "test-mszip.cab",         119,    GCAB_COMPRESSION_MSZIP },
+        { "test-signed.cab",        139,    GCAB_COMPRESSION_NONE },
+        { NULL,                     0,      0 }
     };
 
     for (guint i = 0; tests[i].fn != NULL; i++) {
@@ -375,6 +377,9 @@ gcab_test_cabinet_load_func (void)
         g_assert_no_error (error);
         g_assert (ret);
 
+        /* check size */
+        g_assert_cmpint (gcab_cabinet_get_size (cabinet), ==, tests[i].size);
+
         cabfolders = gcab_cabinet_get_folders (cabinet);
         g_assert (cabfolders != NULL);
         g_assert_cmpint (cabfolders->len, ==, 1);
@@ -495,11 +500,12 @@ gcab_test_cabinet_write_func (void)
 {
     struct {
         const gchar *fn;
+        guint32 size;
         GCabCompression comptype;
     } tests[] = {
-        { "test-none.cab",          GCAB_COMPRESSION_NONE },
-        { "test-mszip.cab",         GCAB_COMPRESSION_MSZIP },
-        { NULL,                     0 }
+        { "test-none.cab",          115,    GCAB_COMPRESSION_NONE },
+        { "test-mszip.cab",         119,    GCAB_COMPRESSION_MSZIP },
+        { NULL,                     0,      0 }
     };
 
     for (guint i = 0; tests[i].fn != NULL; i++) {
@@ -561,6 +567,9 @@ gcab_test_cabinet_write_func (void)
         g_assert_no_error (error);
         g_assert (ret);
 
+        /* check size */
+        g_assert_cmpint (gcab_cabinet_get_size (cabinet), ==, tests[i].size);
+
         /* compare checksums */
         fn_in = gcab_test_get_filename (tests[i].fn);
         g_assert (fn_in != NULL);


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