compression_wrapper: Add cr_ContentStat object.
authorTomas Mlcoch <tmlcoch@redhat.com>
Wed, 5 Jun 2013 12:57:18 +0000 (14:57 +0200)
committerTomas Mlcoch <tmlcoch@redhat.com>
Wed, 5 Jun 2013 12:57:18 +0000 (14:57 +0200)
src/compression_wrapper.c
src/compression_wrapper.h
tests/test_compression_wrapper.c

index 8285cde..b5962f4 100644 (file)
@@ -84,6 +84,51 @@ LZMA_CHECK_SHA256
 #define gzbuffer(a,b) 0
 #endif
 
+cr_ContentStat *
+cr_contentstat_new(cr_ChecksumType type, GError **err)
+{
+    cr_ContentStat *cstat;
+    cr_ChecksumCtx *checksum;
+    GError *tmp_err = NULL;
+
+    assert(!err || *err == NULL);
+
+    if (type == CR_CHECKSUM_UNKNOWN) {
+        checksum = NULL;
+    } else {
+        checksum = cr_checksum_new(type, &tmp_err);
+        if (tmp_err) {
+            g_propagate_error(err, tmp_err);
+            return NULL;
+        }
+    }
+
+    cstat = g_malloc0(sizeof(cr_ContentStat));
+    cstat->checksum = checksum;
+
+    return cstat;
+}
+
+char *
+cr_contentstat_free(cr_ContentStat *cstat, GError **err)
+{
+    char *checksum_str = NULL;
+    GError *tmp_err = NULL;
+
+    assert(!err || *err == NULL);
+
+    if (!cstat)
+        return NULL;
+
+    if (cstat->checksum) {
+        checksum_str = cr_checksum_final(cstat->checksum, &tmp_err);
+        if (tmp_err)
+            g_propagate_error(err, tmp_err);
+    }
+
+    g_free(cstat);
+    return checksum_str;
+}
 
 typedef struct {
     lzma_stream stream;
@@ -91,8 +136,6 @@ typedef struct {
     unsigned char buffer[XZ_BUFFER_SIZE];
 } XzFile;
 
-
-
 cr_CompressionType
 cr_detect_compression(const char *filename, GError **err)
 {
@@ -242,10 +285,11 @@ cr_gz_strerror(gzFile f)
 
 
 CR_FILE *
-cr_open(const char *filename,
-        cr_OpenMode mode,
-        cr_CompressionType comtype,
-        GError **err)
+cr_open_with_stats(const char *filename,
+                   cr_OpenMode mode,
+                   cr_CompressionType comtype,
+                   cr_ContentStat *stat,
+                   GError **err)
 {
     CR_FILE *file = NULL;
     cr_CompressionType type = comtype;
@@ -470,7 +514,7 @@ cr_open(const char *filename,
 int
 cr_close(CR_FILE *cr_file, GError **err)
 {
-    int ret = CR_CW_ERR;
+    int ret = CRE_ERROR;
     int rc;
 
     assert(!err || *err == NULL);
@@ -481,17 +525,19 @@ cr_close(CR_FILE *cr_file, GError **err)
     switch (cr_file->type) {
 
         case (CR_CW_NO_COMPRESSION): // ---------------------------------------
-            if (fclose((FILE *) cr_file->FILE) == 0)
-                ret = CR_CW_OK;
-            else
+            if (fclose((FILE *) cr_file->FILE) == 0) {
+                ret = CRE_OK;
+            } else {
+                ret = CRE_IO;
                 g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_IO,
                             "fclose(): %s", strerror(errno));
+            }
             break;
 
         case (CR_CW_GZ_COMPRESSION): // ---------------------------------------
             rc = gzclose((gzFile) cr_file->FILE);
             if (rc == Z_OK)
-                ret = CR_CW_OK;
+                ret = CRE_OK;
             else {
                 const char *err_msg;
                 switch (rc) {
@@ -510,6 +556,8 @@ cr_close(CR_FILE *cr_file, GError **err)
                     default:
                         err_msg = "error";
                 }
+
+                ret = CRE_GZ;
                 g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_GZ,
                     "gzclose(): %s", err_msg);
             }
@@ -523,7 +571,7 @@ cr_close(CR_FILE *cr_file, GError **err)
                                  BZ2_SKIP_FFLUSH, NULL, NULL);
 
             if (rc == BZ_OK) {
-                ret = CR_CW_OK;
+                ret = CRE_OK;
             } else {
                 const char *err_msg;
 
@@ -539,6 +587,7 @@ cr_close(CR_FILE *cr_file, GError **err)
                         err_msg = "other error";
                 }
 
+                ret = CRE_BZ2;
                 g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_BZ2,
                             "Bz2 error: %s", err_msg);
             }
@@ -585,6 +634,7 @@ cr_close(CR_FILE *cr_file, GError **err)
                                 break;
                         }
 
+                        ret = CRE_XZ;
                         g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_XZ,
                                     "XZ: lzma_code() error (%d): %s",
                                     rc, err_msg);
@@ -594,6 +644,7 @@ cr_close(CR_FILE *cr_file, GError **err)
                     size_t olen = XZ_BUFFER_SIZE - stream->avail_out;
                     if (fwrite(xz_file->buffer, 1, olen, xz_file->file) != olen) {
                         // Error while writing
+                        ret = CRE_XZ;
                         g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_XZ,
                                     "XZ: fwrite() error: %s", strerror(errno));
                         break;
@@ -601,12 +652,12 @@ cr_close(CR_FILE *cr_file, GError **err)
 
                     if(rc == LZMA_STREAM_END) {
                         // Everything all right
-                        ret = CR_CW_OK;
+                        ret = CRE_OK;
                         break;
                     }
                 }
             } else {
-                ret = CR_CW_OK;
+                ret = CRE_OK;
             }
 
             fclose(xz_file->file);
@@ -616,6 +667,7 @@ cr_close(CR_FILE *cr_file, GError **err)
         }
 
         default: // -----------------------------------------------------------
+            ret = CRE_BADARG;
             g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_BADARG,
                         "Bad compressed file type");
             break;
@@ -623,8 +675,8 @@ cr_close(CR_FILE *cr_file, GError **err)
 
     g_free(cr_file);
 
-    assert(!err || (ret == CR_CW_ERR && *err != NULL)
-           || (ret != CR_CW_ERR && *err == NULL));
+    assert(!err || (ret != CRE_OK && *err != NULL)
+           || (ret == CRE_OK && *err == NULL));
 
     return ret;
 }
@@ -972,7 +1024,7 @@ cr_puts(CR_FILE *cr_file, const char *str, GError **err)
     assert(!err || *err == NULL);
 
     if (!str)
-        return CR_CW_OK;
+        return 0;
 
     if (cr_file->mode != CR_CW_MODE_WRITE) {
         g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_BADARG,
@@ -984,7 +1036,7 @@ cr_puts(CR_FILE *cr_file, const char *str, GError **err)
 
         case (CR_CW_NO_COMPRESSION): // ---------------------------------------
             if (fputs(str, (FILE *) cr_file->FILE) != EOF) {
-                ret = CR_CW_OK;
+                ret = 0;
             } else {
                 g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_IO,
                             "fputs(): %s", strerror(errno));
@@ -993,7 +1045,7 @@ cr_puts(CR_FILE *cr_file, const char *str, GError **err)
 
         case (CR_CW_GZ_COMPRESSION): // ---------------------------------------
             if (gzputs((gzFile) cr_file->FILE, str) != -1) {
-                ret = CR_CW_OK;
+                ret = 0;
             } else {
                 g_set_error(err, CR_COMPRESSION_WRAPPER_ERROR, CRE_GZ,
                     "gzputs(): %s", cr_gz_strerror((gzFile) cr_file->FILE));
@@ -1005,7 +1057,7 @@ cr_puts(CR_FILE *cr_file, const char *str, GError **err)
             len = strlen(str);
             ret = cr_write(cr_file, str, len, err);
             if (ret == (int) len)
-                ret = CR_CW_OK;
+                ret = 0;
             else
                 ret = CR_CW_ERR;
             break;
index 26b1c3a..a574dd5 100644 (file)
@@ -24,6 +24,8 @@
 extern "C" {
 #endif
 
+#include "checksum.h"
+
 /** \defgroup   compression_wrapper     Wrapper for compressed file.
  *  \addtogroup compression_wrapper
  *  @{
@@ -49,17 +51,39 @@ typedef enum {
     CR_CW_MODE_SENTINEL,        /*!< Sentinel of the list */
 } cr_OpenMode;
 
+/** Stat build about open content during compression (writting).
+ */
+typedef struct {
+    gint64          size;       /*!< Size of content */
+    cr_ChecksumCtx  *checksum;  /*!< Checksum context */
+} cr_ContentStat;
+
+/** Creates new cr_ContentStat object
+ * @param type      Type of checksum. (if CR_CHECKSUM_UNKNOWN is used,
+ *                  no checksum calculation will be done)
+ * @param err       GError **
+ * @return          cr_ContentStat object
+ */
+cr_ContentStat *cr_contentstat_new(cr_ChecksumType type, GError **err);
+
+/** Frees cr_ContentStat object.
+ * @param cstat     cr_ContentStat object
+ * @param err       GError **
+ * @return          checksum or NULL on error or if checksum calculation
+ *                  was disabled (CR_CHECKSUM_UNKNOWN was used)
+ */
+char *cr_contentstat_free(cr_ContentStat *cstat, GError **err);
 
 /** Structure represents a compressed file.
  */
 typedef struct {
-    cr_CompressionType type;    /*!< Type of compression */
-    void *FILE;                 /*!< Pointer to gzFile, BZFILE or plain FILE */
-    cr_OpenMode mode;           /*!< Mode */
+    cr_CompressionType  type;   /*!< Type of compression */
+    void                *FILE;  /*!< Pointer to gzFile, BZFILE or plain FILE */
+    cr_OpenMode         mode;   /*!< Mode */
+    cr_ContentStat      *stat;  /*!< Content stats */
 } CR_FILE;
 
-#define CR_CW_OK   0       /*!< Return value - Everything all right */
-#define CR_CW_ERR -1       /*!< Return value - Error */
+#define CR_CW_ERR       -1      /*!< Return value - Error */
 
 /** Returns a common suffix for the specified cr_CompressionType.
  * @param comtype       compression type
@@ -81,10 +105,24 @@ cr_CompressionType cr_detect_compression(const char* filename, GError **err);
  * @param err           GError **
  * @return              pointer to a CR_FILE or NULL
  */
-CR_FILE *cr_open(const char *filename,
-                 cr_OpenMode mode,
-                 cr_CompressionType comtype,
-                 GError **err);
+#define cr_open(FILENAME, MODE, COMPRESSION, ERR) \
+                    cr_open_with_stats(FILENAME, MODE, COMPRESSION, NULL, ERR)
+
+/** Open/Create the specified file. For writting is possible pass
+ * a cr_ContentStat object and after cr_close() get stats of
+ * an open content (stats of uncompressed content).
+ * @param filename      filename
+ * @param mode          open mode
+ * @param comtype       type of compression
+ * @param stat          cr_ContentStat object
+ * @param err           GError **
+ * @return              pointer to a CR_FILE or NULL
+ */
+CR_FILE *cr_open_with_stats(const char *filename,
+                            cr_OpenMode mode,
+                            cr_CompressionType comtype,
+                            cr_ContentStat *stat,
+                            GError **err);
 
 /** Reads an array of len bytes from the CR_FILE.
  * @param cr_file       CR_FILE pointer
@@ -121,14 +159,14 @@ int cr_puts(CR_FILE *cr_file, const char *str, GError **err);
  * @param cr_file       CR_FILE pointer
  * @param format        format string
  * @param ...           list of additional arguments as specified in format
- * @return              CR_CW_OK or CR_CW_ERR
+ * @return              Number of bytes written or CR_CW_ERR (-1)
  */
 int cr_printf(GError **err, CR_FILE *cr_file, const char *format, ...);
 
 /** Closes the CR_FILE.
  * @param cr_file       CR_FILE pointer
  * @param err           GError **
- * @return              CR_CW_OK or CR_CW_ERR
+ * @return              cr_Error code
  */
 int cr_close(CR_FILE *cr_file, GError **err);
 
index 193b036..cdc6dd6 100644 (file)
 #define FILE_COMPRESSED_1_XZ_BAD_SUFFIX         TEST_COMPRESSED_FILES_PATH"/01_plain.foo3"
 
 
+static void
+test_cr_contentstat(void)
+{
+    char *checksum;
+    cr_ContentStat *cs = NULL;
+    GError *tmp_err = NULL;
+
+    cs = cr_contentstat_new(CR_CHECKSUM_UNKNOWN, NULL);
+    g_assert(cs);
+    checksum = cr_contentstat_free(cs, NULL);
+    g_assert(!checksum);
+    cs = NULL;
+
+    cs = cr_contentstat_new(CR_CHECKSUM_UNKNOWN, &tmp_err);
+    g_assert(cs);
+    g_assert(!tmp_err);
+    checksum = cr_contentstat_free(cs, &tmp_err);
+    g_assert(!checksum);
+    g_assert(!tmp_err);
+    cs = NULL;
+
+    cs = cr_contentstat_new(CR_CHECKSUM_SHA256, NULL);
+    g_assert(cs);
+    checksum = cr_contentstat_free(cs, NULL);
+    g_assert(checksum);
+    g_assert_cmpstr(checksum, ==, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649"
+                                  "b934ca495991b7852b855");
+    g_free(checksum);
+    cs = NULL;
+    checksum = NULL;
+
+    cs = cr_contentstat_new(CR_CHECKSUM_SHA256, &tmp_err);
+    g_assert(cs);
+    g_assert(!tmp_err);
+    checksum = cr_contentstat_free(cs, &tmp_err);
+    g_assert(!tmp_err);
+    g_assert(checksum);
+    g_assert_cmpstr(checksum, ==, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649"
+                                  "b934ca495991b7852b855");
+    g_free(checksum);
+    cs = NULL;
+    checksum = NULL;
+}
 
 static void
 test_cr_compression_suffix(void)
@@ -79,7 +122,6 @@ test_cr_compression_suffix(void)
     g_assert_cmpstr(suffix, ==, ".xz");
 }
 
-
 static void
 test_cr_detect_compression(void)
 {
@@ -190,7 +232,7 @@ test_helper_cw_input(const char *filename,
     buffer[ret] = '\0';
     g_assert_cmpstr(buffer, ==, content);
     ret = cr_close(file, &tmp_err);
-    g_assert_cmpint(ret, ==, CR_CW_OK);
+    g_assert_cmpint(ret, ==, CRE_OK);
     g_assert(!tmp_err);
 }
 
@@ -283,7 +325,7 @@ test_helper_cw_output(int type,
 
         case OUTPUT_TYPE_PUTS:
             ret = cr_puts(file, content, &tmp_err);
-            g_assert_cmpint(ret, ==, CR_CW_OK);
+            g_assert_cmpint(ret, ==, CRE_OK);
             g_assert(!tmp_err);
             break;
 
@@ -298,7 +340,7 @@ test_helper_cw_output(int type,
     }
 
     ret = cr_close(file, &tmp_err);
-    g_assert_cmpint(ret, ==, CR_CW_OK);
+    g_assert_cmpint(ret, ==, CRE_OK);
     g_assert(!tmp_err);
 
     // Read and compare
@@ -518,6 +560,8 @@ main(int argc, char *argv[])
 {
     g_test_init(&argc, &argv, NULL);
 
+    g_test_add_func("/compression_wrapper/test_cr_contentstat",
+            test_cr_contentstat);
     g_test_add_func("/compression_wrapper/test_cr_compression_suffix",
             test_cr_compression_suffix);
     g_test_add_func("/compression_wrapper/test_cr_detect_compression",