From d85de0124c4e1ef794d394f7140f303c3277aec9 Mon Sep 17 00:00:00 2001 From: Geert Janssens Date: Tue, 7 Jun 2016 10:33:38 +0200 Subject: [PATCH] C++ - use std::pair to store tokenized line together with its error message Also drop a few variables that carry superfluous data and add more c++11 semantics --- .../csv-imp/gnc-csv-imp-trans.cpp | 51 ++++++++----------- .../csv-imp/gnc-csv-imp-trans.hpp | 10 ++-- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/import-export/csv-imp/gnc-csv-imp-trans.cpp b/src/import-export/csv-imp/gnc-csv-imp-trans.cpp index f4891fd554..5b28577177 100644 --- a/src/import-export/csv-imp/gnc-csv-imp-trans.cpp +++ b/src/import-export/csv-imp/gnc-csv-imp-trans.cpp @@ -335,9 +335,16 @@ int GncCsvParseData::load_file (const char* filename, */ int GncCsvParseData::parse (gboolean guessColTypes, GError** error) { + uint max_cols = 0; tokenizer->tokenize(); orig_lines.clear(); - orig_lines = tokenizer->get_tokens(); + for (auto tokenized_line : tokenizer->get_tokens()) + { + orig_lines.push_back (std::make_pair (tokenized_line, std::string())); + auto length = tokenized_line.size(); + if (length > max_cols) + max_cols = length; + } /* If it failed, generate an error. */ if (orig_lines.size() == 0) @@ -346,26 +353,12 @@ int GncCsvParseData::parse (gboolean guessColTypes, GError** error) return 1; } - - /* Record the original row lengths of orig_lines. */ - orig_row_lengths.clear(); - - orig_row_lengths.reserve(orig_lines.size()); - orig_max_row = 0; - for(std::vector::iterator it = orig_lines.begin(); it != orig_lines.end(); ++it) - { - std::vector::size_type length = it->size(); - orig_row_lengths.push_back(length); - if (length > orig_max_row) - orig_max_row = length; - } - if (guessColTypes) { /* Free column_types if it's already been created. */ column_types.clear(); } - column_types.resize(orig_max_row, GncTransPropType::NONE); + column_types.resize(max_cols, GncTransPropType::NONE); if (guessColTypes) { @@ -871,8 +864,8 @@ int GncCsvParseData::parse_to_trans (Account* account, * already exist. */ if (!redo_errors) /* If we're redoing errors, we save freeing until the end. */ { - line_errors.clear(); - line_errors.resize(orig_lines.size()); + for (auto orig_line : orig_lines) + orig_line.second.clear(); if (transactions != NULL) g_list_free (transactions); @@ -898,21 +891,19 @@ int GncCsvParseData::parse_to_trans (Account* account, } /* compute start and end iterators based on user-set restrictions */ - auto line_errs_it = line_errors.begin(); - std::advance(line_errs_it, start_row); - auto orig_lines_it = orig_lines.cbegin(); + auto orig_lines_it = orig_lines.begin(); std::advance(orig_lines_it, start_row); - auto orig_lines_max = orig_lines.cbegin(); + auto orig_lines_max = orig_lines.begin(); if (end_row > orig_lines.size()) - orig_lines_max = orig_lines.cend(); + orig_lines_max = orig_lines.end(); else std::advance(orig_lines_max, end_row); bool odd_line = false; - for (orig_lines_it, line_errs_it, odd_line; + for (orig_lines_it, odd_line; orig_lines_it != orig_lines_max; - ++orig_lines_it, ++line_errs_it, odd_line = !odd_line) + ++orig_lines_it, odd_line = !odd_line) { /* Skip current line if: 1. only looking for lines with error AND no error on current line @@ -920,11 +911,11 @@ int GncCsvParseData::parse_to_trans (Account* account, 2. looking for all lines AND skip_rows is enabled AND current line is an odd line */ - if ((redo_errors && line_errs_it->empty()) || + if ((redo_errors && orig_lines_it->second.empty()) || (!redo_errors && skip_rows && odd_line)) continue; - std::vector line = *orig_lines_it; + auto line = orig_lines_it->first; GncCsvTransLine* trans_line = NULL; home_account = account; @@ -942,7 +933,7 @@ int GncCsvParseData::parse_to_trans (Account* account, if (home_account == NULL) { - *line_errs_it = _("Account column could not be understood."); + orig_lines_it->second = _("Account column could not be understood."); continue; } @@ -966,7 +957,7 @@ int GncCsvParseData::parse_to_trans (Account* account, loop_err = true; gchar *error_message = g_strdup_printf (_("%s column could not be understood."), _(gnc_csv_col_type_strs[property->type])); - *line_errs_it = error_message; + orig_lines_it->second = error_message; g_free (error_message); trans_property_free (property); @@ -983,7 +974,7 @@ int GncCsvParseData::parse_to_trans (Account* account, trans_line = trans_property_list_to_trans (list, &error_message); if (trans_line == NULL) { - *line_errs_it = error_message; + orig_lines_it->second = error_message; g_free (error_message); trans_property_list_free (list); continue; diff --git a/src/import-export/csv-imp/gnc-csv-imp-trans.hpp b/src/import-export/csv-imp/gnc-csv-imp-trans.hpp index 1d983ec698..ac6fc0d42c 100644 --- a/src/import-export/csv-imp/gnc-csv-imp-trans.hpp +++ b/src/import-export/csv-imp/gnc-csv-imp-trans.hpp @@ -105,7 +105,8 @@ extern const gchar* date_format_user[]; /* This array contains all of the different strings for different column types. */ extern const gchar* gnc_csv_col_type_strs[]; -using str_vec_t = std::vector ; +/** Pair to hold a tokenized line of input and an optional error string */ +using parse_line_t = std::pair; /** Struct containing data for parsing a CSV/Fixed-Width file. */ class GncCsvParseData @@ -126,8 +127,7 @@ public: bool check_for_column_type (GncTransPropType type); std::unique_ptr tokenizer; /**< Will handle file loading/encoding conversion/splitting into fields */ - std::vector orig_lines; /**< file_str parsed into a two-dimensional array of strings */ - std::vector::size_type orig_max_row; /**< Holds the maximum value in orig_row_lengths */ + std::vector orig_lines; /**< file_str parsed into a two-dimensional array of strings */ std::vector column_types; /**< Vector of values from the GncCsvColumnType enumeration */ GList* transactions; /**< List of GncCsvTransLine*s created using orig_lines and column_types */ int date_format; /**< The format of the text in the date columns from date_format_internal. */ @@ -137,10 +137,6 @@ public: int currency_format; /**< The currency format, 0 for locale, 1 for comma dec and 2 for period */ private: - std::vector::size_type> - orig_row_lengths; /**< The lengths of rows in orig_lines - before error messages are appended */ - std::vector line_errors; GncImpFileFormat file_fmt = GncImpFileFormat::UNKNOWN; };