From: Tomas Mlcoch Date: Wed, 5 Jun 2013 12:57:18 +0000 (+0200) Subject: compression_wrapper: Add cr_ContentStat object. X-Git-Tag: upstream/0.2.1~108 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1668ae615755a726e1a24ed2717446eca700567b;p=services%2Fcreaterepo_c.git compression_wrapper: Add cr_ContentStat object. --- diff --git a/src/compression_wrapper.c b/src/compression_wrapper.c index 8285cde..b5962f4 100644 --- a/src/compression_wrapper.c +++ b/src/compression_wrapper.c @@ -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; diff --git a/src/compression_wrapper.h b/src/compression_wrapper.h index 26b1c3a..a574dd5 100644 --- a/src/compression_wrapper.h +++ b/src/compression_wrapper.h @@ -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); diff --git a/tests/test_compression_wrapper.c b/tests/test_compression_wrapper.c index 193b036..cdc6dd6 100644 --- a/tests/test_compression_wrapper.c +++ b/tests/test_compression_wrapper.c @@ -54,6 +54,49 @@ #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",