diff --git a/Inc/CSV_Utilities.hpp b/Inc/CSV_Utilities.hpp index 63c81f9..15fa1b6 100644 --- a/Inc/CSV_Utilities.hpp +++ b/Inc/CSV_Utilities.hpp @@ -11,9 +11,11 @@ namespace CSV_Type // 错误类型 typedef enum { - CSV_ERROR_NONE, // None Error - CSV_ERROR_MEM_ALLOCATE_FAILED, // 内存分配失败 - CSV_ERROR_COLUMN_NOT_FOUND, // 未查找到指定列 + CSV_ERROR_NONE, // None Error + CSV_ERROR_MEM_ALLOCATE_FAILED, // 内存分配失败 + CSV_ERROR_COLUMN_NOT_FOUND, // 未查找到指定列 + CSV_ERROR_ILLEGAL_COLUMN_POSITION, // 非法列位置 + CSV_ERROR_ILLEGAL_CELL_POSITION, // 非法单元格位置 } CSV_Err; } @@ -68,27 +70,61 @@ public: /** * @brief 在指定标题的列表后新增列 - * @param target_column_title_str 目标列标题 + * @param target_column_position 目标列位置 * @param title_name_str 插入的列标题 * @return CSV_Err 错误类型 */ CSV_Type::CSV_Err insert_column_after(size_t target_column_position, const char *title_name_str); /** - * @brief 指定列末尾新增单元格 - * @param column_title_str 列标题 - * @param cell_content_str 单元格内容串 - * @return CSV_Err 错误类型 + * @brief 在指定标题的列表前新增列 + * @param target_column_title_str 目标列标题 + * @param title_name_str 插入的列标题 + * @return CSV_Err 错误类型 */ - CSV_Type::CSV_Err append_cell(const char *column_title_str, const char *cell_content_str); + CSV_Type::CSV_Err insert_column_before(const char *target_column_title_str, const char *title_name_str); + + /** + * @brief 在指定标题的列表前新增列 + * @param target_column_position 目标列位置 + * @param title_name_str 插入的列标题 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err insert_column_before(size_t target_column_position, const char *title_name_str); /** * @brief 指定列末尾新增单元格 - * @param column_position 列位置计数 - * @param cell_content_str 单元格内容串 - * @return CSV_Err 错误类型 + * @param target_column_title_str 列标题 + * @param cell_content_str 单元格内容串 + * @return CSV_Err 错误类型 */ - CSV_Type::CSV_Err append_cell(size_t column_position, const char *cell_content_str); + CSV_Type::CSV_Err append_cell(const char *target_column_title_str, const char *cell_content_str); + + /** + * @brief 指定列末尾新增单元格 + * @param target_column_position 列位置计数 + * @param cell_content_str 单元格内容串 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err append_cell(size_t target_column_position, const char *cell_content_str); + + /** + * @brief 在指定标题的列中指定单元格后插入 + * @param target_column_title_str 目标列标题 + * @param target_cell_position 目标列位置 + * @param title_name_str 插入的列标题 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err insert_cell_after(const char *target_column_title_str, size_t target_cell_position, const char *cell_content_str); + + /** + * @brief 在指定标题的列中指定单元格后插入 + * @param target_column_title_str 目标列标题 + * @param target_cell_position 目标列位置 + * @param title_name_str 插入的列标题 + * @return CSV_Err 错误类型 + */ + CSV_Type::CSV_Err insert_cell_after(size_t target_column_position, size_t target_cell_position, const char *cell_content_str); }; #endif \ No newline at end of file diff --git a/Src/CSV_Utilities.cpp b/Src/CSV_Utilities.cpp index 3c7272b..dd2905f 100644 --- a/Src/CSV_Utilities.cpp +++ b/Src/CSV_Utilities.cpp @@ -32,27 +32,27 @@ void CSV_Table::reset() // 释放列 while (this->Column_List_Head != nullptr) { - decltype(this->Column_List_Head) p_column = this->Column_List_Head; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; // 释放单元格列表 - while (p_column->Cell_List_Head != nullptr) + while (p_target_column->Cell_List_Head != nullptr) { - decltype(p_column->Cell_List_Head) p_cell = p_column->Cell_List_Head; + decltype(p_target_column->Cell_List_Head) p_target_cell = p_target_column->Cell_List_Head; // 释放单元格内容 - if (p_cell->content_str != nullptr) - free(p_cell->content_str); + if (p_target_cell->content_str != nullptr) + free(p_target_cell->content_str); - p_column->Cell_List_Head = p_cell->p_next_cell; - free(p_cell->content_str); + p_target_column->Cell_List_Head = p_target_cell->p_next_cell; + free(p_target_cell->content_str); } // 释放标题 - if (p_column->column_title_str != nullptr) - free(p_column->column_title_str); + if (p_target_column->column_title_str != nullptr) + free(p_target_column->column_title_str); - this->Column_List_Head = p_column->p_next_column; - free(p_column); + this->Column_List_Head = p_target_column->p_next_column; + free(p_target_column); } } } @@ -103,13 +103,13 @@ CSV_Type::CSV_Err CSV_Table::append_column(const char *title_name_str) CSV_Type::CSV_Err CSV_Table::insert_column_after(const char *target_column_title_str, const char *title_name_str) { size_t count = 0; - decltype(this->Column_List_Head) p_column = this->Column_List_Head; - while (p_column != nullptr) + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + while (p_target_column != nullptr) { - if (!strcmp(p_column->column_title_str, target_column_title_str)) + if (!strcmp(p_target_column->column_title_str, target_column_title_str)) return this->insert_column_after(count, title_name_str); - p_column = p_column->p_next_column; + p_target_column = p_target_column->p_next_column; count++; } return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; @@ -117,15 +117,89 @@ CSV_Type::CSV_Err CSV_Table::insert_column_after(const char *target_column_title CSV_Type::CSV_Err CSV_Table::insert_column_after(size_t target_column_position, const char *title_name_str) { - if ((target_column_position + 1) > this->column_count) - return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; + if (!(((target_column_position + 1) <= this->column_count) || ((target_column_position == 0) && (this->column_count == 0)))) + return CSV_Type::CSV_ERROR_ILLEGAL_COLUMN_POSITION; - decltype(this->Column_List_Head) p_column = this->Column_List_Head; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; for (size_t count = 0; count < target_column_position; count++) - p_column = p_column->p_next_column; + p_target_column = p_target_column->p_next_column; // 开辟新节点 - decltype(p_column) p_new_column = (decltype(p_column))malloc(sizeof(*(p_column))); + decltype(p_target_column) p_new_column = (decltype(p_target_column))malloc(sizeof(*(p_target_column))); + if (p_new_column == nullptr) + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + this->mem_use += sizeof(*p_new_column); + + // 节点初始化 + p_new_column->Cell_List_Head = p_new_column->Cell_List_End = nullptr; + p_new_column->p_next_column = nullptr; + p_new_column->element_count = 0; + + // 存储列标题名 + if (title_name_str != nullptr) + { + char *p_title = (char *)malloc(strlen(title_name_str) + 1); // +1 for '\0' + if (p_title == nullptr) + { + free(p_new_column); + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + } + + this->mem_use += strlen(title_name_str) + 1; + strcpy(p_title, title_name_str); + p_new_column->column_title_str = p_title; + } + else + p_new_column->column_title_str = nullptr; + + // 内部列表为空 + if (this->column_count == 0) + this->Column_List_Head = this->Column_List_End = p_new_column; + else + { + // 链接节点 + p_new_column->p_next_column = p_target_column->p_next_column; + p_target_column->p_next_column = p_new_column; + + // 目标位置在末尾时 + if (target_column_position == this->column_count - 1) + this->Column_List_End = p_new_column; + } + + this->column_count++; + return CSV_Type::CSV_ERROR_NONE; +} + +CSV_Type::CSV_Err CSV_Table::insert_column_before(const char *target_column_title_str, const char *title_name_str) +{ + size_t count = 0; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + while (p_target_column != nullptr) + { + if (!strcmp(p_target_column->column_title_str, target_column_title_str)) + return this->insert_column_before(count, title_name_str); + + p_target_column = p_target_column->p_next_column; + count++; + } + return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; +} + +CSV_Type::CSV_Err CSV_Table::insert_column_before(size_t target_column_position, const char *title_name_str) +{ + if (!(((target_column_position + 1) <= this->column_count) || ((target_column_position == 0) && (this->column_count == 0)))) + return CSV_Type::CSV_ERROR_ILLEGAL_COLUMN_POSITION; + + decltype(this->Column_List_Head) p_pre_column = this->Column_List_Head; + decltype(this->Column_List_Head) p_target_column = this->column_count > 0 ? this->Column_List_Head->p_next_column : nullptr; + for (size_t count = 1; count < target_column_position; count++) + { + p_pre_column = p_pre_column->p_next_column; + p_target_column = p_target_column->p_next_column; + } + + // 开辟新节点 + decltype(p_target_column) p_new_column = (decltype(p_target_column))malloc(sizeof(*(p_target_column))); if (p_new_column == nullptr) return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; this->mem_use += sizeof(*p_new_column); @@ -153,42 +227,53 @@ CSV_Type::CSV_Err CSV_Table::insert_column_after(size_t target_column_position, p_new_column->column_title_str = nullptr; // 链接节点 - p_new_column->p_next_column = p_column->p_next_column; - p_column->p_next_column = p_new_column; - this->column_count++; + if (this->column_count == 0) + this->Column_List_Head = this->Column_List_End = p_new_column; + else + { + if (target_column_position == 0) + { + // 目标为表头 + p_new_column->p_next_column = this->Column_List_Head; + this->Column_List_Head = p_new_column; + } + else + { + p_new_column->p_next_column = p_target_column; + p_pre_column->p_next_column = p_new_column; + } + } - // 目标位置在末尾时 - if (target_column_position == this->column_count - 1) - this->Column_List_End = p_new_column; + this->column_count++; return CSV_Type::CSV_ERROR_NONE; } -CSV_Type::CSV_Err CSV_Table::append_cell(const char *column_title_str, const char *cell_content_str) +CSV_Type::CSV_Err CSV_Table::append_cell(const char *target_column_title_str, const char *cell_content_str) { size_t count = 0; - decltype(this->Column_List_Head) p_column = this->Column_List_Head; - while (p_column != nullptr) + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + while (p_target_column != nullptr) { - if (!strcmp(p_column->column_title_str, column_title_str)) + if (!strcmp(p_target_column->column_title_str, target_column_title_str)) return this->append_cell(count, cell_content_str); - p_column = p_column->p_next_column; + p_target_column = p_target_column->p_next_column; count++; } return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; } -CSV_Type::CSV_Err CSV_Table::append_cell(size_t column_position, const char *cell_content_str) +CSV_Type::CSV_Err CSV_Table::append_cell(size_t target_column_position, const char *cell_content_str) { - if ((column_position + 1) > this->column_count) + if ((target_column_position + 1) > this->column_count) return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; - decltype(this->Column_List_Head) p_column = this->Column_List_Head; - for (size_t count = 0; count < column_position; count++) - p_column = p_column->p_next_column; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + for (size_t count = 0; count < target_column_position; count++) + p_target_column = p_target_column->p_next_column; - decltype(p_column->Cell_List_Head) p_new_cell = (decltype(p_column->Cell_List_Head))malloc(sizeof(*(p_column->Cell_List_Head))); + decltype(p_target_column->Cell_List_Head) p_new_cell = (decltype(p_target_column->Cell_List_Head))malloc(sizeof(*(p_target_column->Cell_List_Head))); if (p_new_cell == nullptr) return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; this->mem_use += sizeof(*p_new_cell); @@ -210,14 +295,82 @@ CSV_Type::CSV_Err CSV_Table::append_cell(size_t column_position, const char *cel p_new_cell->content_str = nullptr; p_new_cell->p_next_cell = nullptr; - if (p_column->element_count == 0) - p_column->Cell_List_Head = p_column->Cell_List_End = p_new_cell; + if (p_target_column->element_count == 0) + p_target_column->Cell_List_Head = p_target_column->Cell_List_End = p_new_cell; else { - p_column->Cell_List_End->p_next_cell = p_new_cell; - p_column->Cell_List_End = p_new_cell; + p_target_column->Cell_List_End->p_next_cell = p_new_cell; + p_target_column->Cell_List_End = p_new_cell; } - p_column->element_count++; + p_target_column->element_count++; return CSV_Type::CSV_ERROR_NONE; -} \ No newline at end of file +} + +CSV_Type::CSV_Err CSV_Table::insert_cell_after(const char *target_column_title_str, size_t target_cell_position, const char *cell_content_str) +{ + size_t count = 0; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + while (p_target_column != nullptr) + { + if (!strcmp(p_target_column->column_title_str, target_column_title_str)) + return this->insert_cell_after(count, target_cell_position, cell_content_str); + + p_target_column = p_target_column->p_next_column; + count++; + } + return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND; +} + +CSV_Type::CSV_Err CSV_Table::insert_cell_after(size_t target_column_position, size_t target_cell_position, const char *cell_content_str) +{ + if ((target_column_position + 1) > this->column_count) + return CSV_Type::CSV_ERROR_ILLEGAL_COLUMN_POSITION; + decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; + for (size_t count = 0; count < target_column_position; count++) + p_target_column = p_target_column->p_next_column; + + if (!(((target_cell_position + 1) <= p_target_column->element_count) || ((target_cell_position == 0) && (p_target_column->element_count == 0)))) + return CSV_Type::CSV_ERROR_ILLEGAL_CELL_POSITION; + + decltype(p_target_column->Cell_List_Head) p_new_cell = (decltype(p_target_column->Cell_List_Head))malloc(sizeof(*(p_target_column->Cell_List_Head))); + if (p_new_cell == nullptr) + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + this->mem_use += sizeof(*p_new_cell); + + if (cell_content_str != nullptr) + { + char *p_content = (char *)malloc(strlen(cell_content_str) + 1); // +1 for '\0' + if (p_content == nullptr) + { + free(p_new_cell); + return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED; + } + + this->mem_use += strlen(cell_content_str) + 1; + strcpy(p_content, cell_content_str); + p_new_cell->content_str = p_content; + } + else + p_new_cell->content_str = nullptr; + + if (p_target_column->element_count == 0) + { + p_new_cell->p_next_cell = nullptr; + p_target_column->Cell_List_Head = p_target_column->Cell_List_End = p_new_cell; + } + else + { + decltype(p_new_cell) p_target_cell = p_target_column->Cell_List_Head; + for (size_t count = 0; count < target_cell_position; count++) + p_target_cell = p_target_cell->p_next_cell; + + p_new_cell->p_next_cell = p_target_cell->p_next_cell; + p_target_cell->p_next_cell = p_new_cell; + if ((target_cell_position + 1) == p_target_column->element_count) + p_target_column->Cell_List_End = p_new_cell; + } + + p_target_column->element_count++; + return CSV_Type::CSV_ERROR_NONE; +} diff --git a/Src/Command_Solve.cpp b/Src/Command_Solve.cpp index ea35d36..4916d72 100644 --- a/Src/Command_Solve.cpp +++ b/Src/Command_Solve.cpp @@ -13,12 +13,18 @@ DLT_File File; void Pre_Command_Solve(void) { CSV_Table CSV; + CSV.insert_column_before((unsigned)0, "First insert"); CSV.append_column("Test column"); CSV.append_column("Test column 2"); CSV.append_column("Test column 3"); CSV.insert_column_after("Test column 2", "Test insert column"); + CSV.insert_column_after("Test column 3", "Test insert column after End"); + + CSV.insert_column_before("Test column", "Test insert column before Head"); + CSV.insert_column_before("Test column", "Test insert column before Origin"); CSV.append_cell("Test column 2", "1"); + CSV.insert_cell_after("Test column 3", (unsigned)0, "Insert Cell"); CSV.append_cell("Test column 3", "1"); CSV.append_cell("Test column 3", "2"); CSV.append_cell("Test column 3", "3");