From 74804a1eadd91cc5b1f5672bc6d5fe78929f8060 Mon Sep 17 00:00:00 2001 From: Phuntsok Drak-pa Date: Fri, 25 May 2018 13:28:37 +0200 Subject: [PATCH] Bugfixes and additional changes --- src/compress.cc | 32 +++----------- src/io.cc | 2 +- src/io.hh | 2 +- src/main.cc | 113 ++++++++++++------------------------------------ 4 files changed, 37 insertions(+), 112 deletions(-) diff --git a/src/compress.cc b/src/compress.cc index 0fb11a1..db3b0bf 100644 --- a/src/compress.cc +++ b/src/compress.cc @@ -42,11 +42,10 @@ constexpr size_t DICT_MAX = ipow(2, 13) - 256; /* 12 bits */ * La chaîne de caractère \p t_text est lue caractère par caractère, et est et * selon la valeur de retour de la fonction \ref dico (permettant dans le même * temps la création du dictionnaire), on rajoute un mot ou pas dans le vecteur - * de caractères UTF-8 représentant des mots de chars compressés. La fonction - * renvoie ledit vecteur de uint32_t via le paramètre \p t_res. + * de caractères UTF-8 représentant des mots de chars compressés. * - * \param[in] t_text Chaîne de caractères uint8_t représentant le fichier d'entrée - * \param[out] t_res Chaîne de caractères de sortie + * \param t_text Chaîne de caractères uint8_t représentant le fichier d'entrée + * \return Vecteur de chunks (vecteurs de uint32_t) */ vvuint32 lzw_compress(string &&t_text) { std::puts("Compressing..."); @@ -88,33 +87,16 @@ vvuint32 lzw_compress(string &&t_text) { * \param[in] t_out_file Chemin vers le fichier de sortie */ void compress(const std::string &t_in_file, const char *t_out_file) { - // Fichier d’entrée std::ifstream input_file{t_in_file}; - if (!input_file.is_open()) { - std::cerr << "Error at " << __FILE__ << ":" << __LINE__ - 2 - << ": could not open output file \"" << t_in_file - << "\". Aborting...\n"; - exit(1); - } - - // Fichier de sortie - FILE *const out = - (t_out_file != nullptr) ? fopen(t_out_file, "wb") : fopen("output.lzw", "wb"); - // std::ofstream out{(t_out_file != nullptr) ? t_out_file : "output.lzw", - // std::ios::binary}; + assert(input_file.is_open()); + FILE *const out = (t_out_file != nullptr) ? fopen(t_out_file, "wb") : fopen("output.lzw", "wb"); if (out == nullptr) { - std::cerr << "Error at " << __FILE__ << ":" << __LINE__ - 4 - << ": could not open output file. Aborting...\n"; + std::cerr << "Error at " << __FILE__ << ":" << __LINE__ - 4 << ": could not open output file. Aborting...\n"; input_file.close(); exit(1); } - - const auto compressed_text{ - lzw_compress(std::string{std::istreambuf_iterator(input_file), - std::istreambuf_iterator()})}; - + const auto compressed_text{lzw_compress(std::string{std::istreambuf_iterator(input_file), std::istreambuf_iterator()})}; write_file(out, compressed_text); - fclose(out); input_file.close(); } diff --git a/src/io.cc b/src/io.cc index 7b99eb1..967c6ec 100644 --- a/src/io.cc +++ b/src/io.cc @@ -75,7 +75,7 @@ void write_chunk(FILE *const t_out, const vuint32 &t_chunk) { data[0] = static_cast(t_chunk[i] >> 4); data[1] = static_cast(t_chunk[i] << 4); } else { - data[1] |= static_cast(t_chunk[i] >> 8) & 0x0F; + data[1] |= static_cast(t_chunk[i] >> 8) & 0xC; data[2] = static_cast(t_chunk[i]); fwrite(data.data(), sizeof(data[0]), 3, t_out); } diff --git a/src/io.hh b/src/io.hh index 78b15fa..0eb3f7d 100644 --- a/src/io.hh +++ b/src/io.hh @@ -1,5 +1,5 @@ /** - * \file io.h + * \file io.hh * \brief Header for file reading and writing */ diff --git a/src/main.cc b/src/main.cc index 46c21cf..a182a42 100644 --- a/src/main.cc +++ b/src/main.cc @@ -6,17 +6,15 @@ * */ -#ifdef Debug -constexpr bool debug_mode = true; -#else -constexpr bool debug_mode = false; -#endif - #include "compress.hh" #include "getopt.h" +#include +#include using std::printf; using std::puts; +using std::string; +using std::tuple; // custom types /////////////////////////////////////////////////////////////// @@ -53,16 +51,8 @@ void help() { puts("\t\textension \".uncompresed\" will be added"); } -int main(int argc, char *argv[]) { - if constexpr (debug_mode) { - for (int i = 0; i < argc; ++i) - printf("argv[%d] = %s\n", i, argv[i]); - } - - std::string input_path{}; - std::string output_path{}; - bool compressing = true; - +std::tuple process_args(int t_argc, char *t_argv[]) { + auto ret = std::make_tuple(string{}, string{}, false); while (true) { int option_index = 0; static struct option long_options[] = { @@ -72,84 +62,41 @@ int main(int argc, char *argv[]) { {"compress", no_argument, nullptr, 'c'}, {"uncompress", no_argument, nullptr, 'u'}, {nullptr, 0, nullptr, 0}}; - int c = getopt_long(argc, argv, "hi:o:cu", long_options, &option_index); - if (c == -1) - break; + int c = getopt_long(t_argc, t_argv, "hi:o:cu", long_options, &option_index); + if (c == -1) break; switch (c) { - case 0: { - if constexpr (debug_mode) { - printf("\noption %s", long_options[option_index].name); - if (optarg) { - printf(" with arg %s\n", optarg); - } - } + case 0: break; - } - case 'h': { - if constexpr (debug_mode) { - printf("From main - option --help passed\n"); - } + case 'h': help(); - return 0; - } - case 'i': { - if constexpr (debug_mode) { - printf("From main - option --input with value '%s'\n", optarg); - } - input_path = optarg; + exit(0); + case 'i': + std::get<0>(ret) = optarg; break; - } - case 'o': { - if constexpr (debug_mode) { - printf("From main - option --output with value '%s'\n", optarg); - } - output_path = optarg; + case 'o': + std::get<1>(ret) = optarg; break; - } - case 'c': { - if constexpr (debug_mode) { - printf("From main - option --compress\n"); - } - compressing = true; + case 'c': + std::get<2>(ret) = true; break; - } - case 'u': { - if constexpr (debug_mode) { - printf("From main - option --uncompress\n"); - } - compressing = false; + case 'u': + std::get<2>(ret) = false; break; - } case '?': - default: { + default: puts("Error: unknown parameter."); - if constexpr (debug_mode) { - printf("From main - option -?\n"); - } help(); - return 1; - } + exit(1); } } + return ret; +} - if (input_path.empty()) { - puts("Error: no input file specified"); - return 2; - } - +/* TODO: compression multiple : nombre de compressions puis fichier compressé */ +int main(int argc, char *argv[]) { + const auto [input_path, output_path, compressing] = process_args(argc, argv); + assert(!input_path.empty()); if (compressing) { - /* - TODO: - - compresser le fichier d’entrée morceaux par morceaux, 16Ko à la fois - - écrire la taille du segment compressé, puis le segment compressé - - multithreading - - compression multiple : nombre de compressions puis fichier compressé - - bit-packing, limiter la taille du dictionnaire pour un certain nombre de - bits. - */ - if constexpr (debug_mode) { - puts("Beginning compression"); - } if (output_path.empty()) { compress(input_path, nullptr); } else { @@ -157,11 +104,7 @@ int main(int argc, char *argv[]) { } } else { puts("Not yet implemented :("); - /* - Inversion des types du dictionnaire pour retrouver les chaînes plus - aisément - */ + /* Inversion des types du dictionnaire pour retrouver les chaînes plus aisément */ } - return 0; }