diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-10-19 20:03:22 +0200 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2025-10-19 20:03:22 +0200 |
| commit | 3e85a8e6db1a9c9a7fcf7974a1a0307b2cb145bd (patch) | |
| tree | 16d611d9190bcf4939dd054909cb3a41a6d20fb7 | |
| parent | 7aea21f2a30e0aa3bc75a579bd01ff9746470c05 (diff) | |
strops and memops refactor
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | include/memops.hpp | 1 | ||||
| -rw-r--r-- | include/strops.hpp | 3 | ||||
| -rw-r--r-- | src/administration.cpp | 46 | ||||
| -rw-r--r-- | src/administration_reader.cpp | 4 | ||||
| -rw-r--r-- | src/administration_writer.cpp | 26 | ||||
| -rw-r--r-- | src/ai_providers/DeepSeek.cpp | 6 | ||||
| -rw-r--r-- | src/ai_providers/openAI.cpp | 9 | ||||
| -rw-r--r-- | src/importer.cpp | 8 | ||||
| -rw-r--r-- | src/memops.cpp | 5 | ||||
| -rw-r--r-- | src/strops.cpp | 18 | ||||
| -rw-r--r-- | src/ui/imgui_extensions.cpp | 8 |
12 files changed, 77 insertions, 60 deletions
@@ -2,10 +2,7 @@ TODO: Refactor: - refactor _add functions to use _import functions -- replace strncpy and similar with strops functions - There is alot of memory leakage -- replace strlen with strops function -- strlen == 0 with strops::empty Testing: - write tests for all NL tax categories diff --git a/include/memops.hpp b/include/memops.hpp index 9901d0c..178b966 100644 --- a/include/memops.hpp +++ b/include/memops.hpp @@ -25,5 +25,6 @@ namespace memops { void unalloc(void *ptr); void* copy(void* destination, const void* source, size_t num); void zero(void* destination, size_t num); + bool equals(void* m1, void* m2, size_t size); }
\ No newline at end of file diff --git a/include/strops.hpp b/include/strops.hpp index 537e058..dd01b80 100644 --- a/include/strops.hpp +++ b/include/strops.hpp @@ -32,6 +32,9 @@ namespace strops { /// @brief Check if `a` matches string `b`. /// @return `true` when strings match, else `false`. bool equals(const char* a, const char* b); + + size_t length(const char* str); + bool empty(const char* str); char* tokenize(char* a, const char* find); diff --git a/src/administration.cpp b/src/administration.cpp index 724f25f..8af6e86 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -542,7 +542,7 @@ void administration::create_income_statement(income_statement* statement) report->expenses_total += inv->total; quarter->profit -= inv->total; - if (strops::equals(inv->cost_center_id, "") != 0) { + if (!strops::equals(inv->cost_center_id, "")) { int expense_report_index = -1; for (u32 x = 0; x < report->expense_count; x++) { @@ -599,7 +599,7 @@ void administration::set_file_path(char* path) char* administration::get_file_path() { - return strlen(g_administration.path) == 0 ? NULL : g_administration.path; + return strops::empty(g_administration.path) ? NULL : g_administration.path; } contact administration::company_info_get() @@ -813,11 +813,11 @@ int administration::contact_get_autocompletions(contact* buffer, int buf_size, c a_err administration::addressee_is_valid(delivery_info data) { a_err result = A_ERR_SUCCESS; - if (strlen(data.name) == 0) result |= A_ERR_MISSING_NAME; - if (strlen(data.address.city) == 0) result |= A_ERR_MISSING_CITY; - if (strlen(data.address.postal) == 0) result |= A_ERR_MISSING_POSTAL; - if (strlen(data.address.address1) == 0) result |= A_ERR_MISSING_ADDRESS1; - if (strlen(data.address.country_code) == 0) result |= A_ERR_MISSING_COUNTRYCODE; + if (strops::empty(data.name)) result |= A_ERR_MISSING_NAME; + if (strops::empty(data.address.city)) result |= A_ERR_MISSING_CITY; + if (strops::empty(data.address.postal)) result |= A_ERR_MISSING_POSTAL; + if (strops::empty(data.address.address1)) result |= A_ERR_MISSING_ADDRESS1; + if (strops::empty(data.address.country_code)) result |= A_ERR_MISSING_COUNTRYCODE; return result; } @@ -825,17 +825,17 @@ a_err administration::addressee_is_valid(delivery_info data) a_err administration::contact_is_valid(contact data) { a_err result = A_ERR_SUCCESS; - if (strlen(data.name) == 0) result |= A_ERR_MISSING_NAME; - if (strlen(data.email) == 0) result |= A_ERR_MISSING_EMAIL; - if (strlen(data.address.city) == 0) result |= A_ERR_MISSING_CITY; - if (strlen(data.address.postal) == 0) result |= A_ERR_MISSING_POSTAL; - if (strlen(data.address.address1) == 0) result |= A_ERR_MISSING_ADDRESS1; - if (strlen(data.address.country_code) == 0) result |= A_ERR_MISSING_COUNTRYCODE; + if (strops::empty(data.name)) result |= A_ERR_MISSING_NAME; + if (strops::empty(data.email)) result |= A_ERR_MISSING_EMAIL; + if (strops::empty(data.address.city)) result |= A_ERR_MISSING_CITY; + if (strops::empty(data.address.postal)) result |= A_ERR_MISSING_POSTAL; + if (strops::empty(data.address.address1)) result |= A_ERR_MISSING_ADDRESS1; + if (strops::empty(data.address.country_code)) result |= A_ERR_MISSING_COUNTRYCODE; if (data.type == contact_type::CONTACT_BUSINESS) { - if (strlen(data.taxid) == 0) result |= A_ERR_MISSING_TAXID; - if (strlen(data.businessid) == 0) result |= A_ERR_MISSING_BUSINESSID; + if (strops::empty(data.taxid)) result |= A_ERR_MISSING_TAXID; + if (strops::empty(data.businessid)) result |= A_ERR_MISSING_BUSINESSID; } return result; @@ -851,7 +851,7 @@ contact administration::contact_create_empty() bool administration::contact_equals(contact c1, contact c2) { - return memcmp(&c1, &c2, sizeof(contact)) == 0; + return memops::equals(&c1, &c2, sizeof(contact)); } // Project functions. @@ -925,7 +925,7 @@ void administration::project_cancel(project data) a_err administration::project_is_valid(project data) { - if (strlen(data.description) == 0) return A_ERR_MISSING_DESCRIPTION; + if (strops::empty(data.description)) return A_ERR_MISSING_DESCRIPTION; return A_ERR_SUCCESS; } @@ -1225,8 +1225,8 @@ a_err administration::cost_center_is_valid(cost_center data) cost_center lookup; a_err result = A_ERR_SUCCESS; - if (strlen(data.code) == 0) result |= A_ERR_MISSING_CODE; - if (strlen(data.description) == 0) result |= A_ERR_MISSING_DESCRIPTION; + if (strops::empty(data.code)) result |= A_ERR_MISSING_CODE; + if (strops::empty(data.description)) result |= A_ERR_MISSING_DESCRIPTION; if (get_cost_center_by_code(data.code, &lookup)) result |= A_ERR_CODE_EXISTS; return result; @@ -1293,7 +1293,7 @@ a_err administration::cost_center_update(cost_center data) // ======================= static char* get_default_currency_for_country(char* country_code) { - if (country_code == NULL || strlen(country_code) != 2) + if (country_code == NULL || strops::length(country_code) != 2) return "EUR"; // default // Non-euro EU currencies @@ -1477,7 +1477,7 @@ a_err administration::invoice_update(invoice* inv) a_err administration::invoice_import(invoice* inv) { - inv->is_triangulation = !(memcmp(&inv->addressee.address, &inv->customer.address, sizeof(address)) == 0); + inv->is_triangulation = !memops::equals(&inv->addressee.address, &inv->customer.address, sizeof(address)); inv->issued_at -= (inv->issued_at % 86400); inv->delivered_at -= (inv->delivered_at % 86400); @@ -1833,8 +1833,8 @@ tax_subtotal administration::billing_item_convert_to_default_currency(invoice* i a_err administration::billing_item_is_valid(billing_item item) { a_err result = A_ERR_SUCCESS; - if (strlen(item.description) == 0) result |= A_ERR_MISSING_DESCRIPTION; - if (strlen(item.tax_internal_code) == 0) result |= A_ERR_MISSING_TAX_RATE; + if (strops::empty(item.description)) result |= A_ERR_MISSING_DESCRIPTION; + if (strops::empty(item.tax_internal_code)) result |= A_ERR_MISSING_TAX_RATE; return result; } diff --git a/src/administration_reader.cpp b/src/administration_reader.cpp index 4e375c5..fdbe8b6 100644 --- a/src/administration_reader.cpp +++ b/src/administration_reader.cpp @@ -81,7 +81,7 @@ bool administration_reader::open_existing(char* file_path) memops::zero(buffer, size+1); zip_entry_read(zip, (void**)&buffer, (size_t*)&size); - if (strlen(name) == 0) continue; + if (strops::empty(name)) continue; if (strops::equals(name, ADMIN_FILE_INFO)) { @@ -376,7 +376,7 @@ bool administration_reader::import_tax_rate(char* buffer, size_t buffer_size) for (char *p = strops::tokenize(tsb,"##"); p != NULL; p = strtok(NULL, "##")) { - if (strlen(p) > 0) + if (strops::length(p) > 0) strops::copy(data.tax_sections[data.tax_section_count++], p, MAX_LEN_SHORT_DESC); } diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index f3f090f..b6428f4 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -90,7 +90,7 @@ void administration_writer::destroy() static char* copy_template(const char* template_str, int* buf_size) { - size_t template_size = strlen(template_str); + size_t template_size = strops::length(template_str); size_t buf_length = template_size*5; // Ballpark file content size. char* file_content = (char*)memops::alloc(buf_length); memops::zero(file_content, buf_length); @@ -294,7 +294,7 @@ static void _add_document_to_zip(invoice* inv) { document* doc = &inv->document; - if (strlen(doc->copy_path) == 0 && strlen(doc->original_path) != 0) + if (strops::empty(doc->copy_path) && !strops::empty(doc->original_path)) { char copy_path[MAX_LEN_PATH]; strops::format(copy_path, MAX_LEN_PATH, "documents/%s%s", inv->sequential_number, _get_file_extension(doc->original_path)); @@ -335,7 +335,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) int buf_length = 150000; // Ballpark file content size. char* file_content = (char*)memops::alloc(buf_length); memops::zero(file_content, buf_length); - memops::copy(file_content, file_template::peppol_invoice_template, strlen(file_template::peppol_invoice_template)); + memops::copy(file_content, file_template::peppol_invoice_template, strops::length(file_template::peppol_invoice_template)); struct tm *tm_info = 0; char date_buffer[11]; // "YYYY-MM-DD" + null terminator @@ -410,7 +410,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) tax_rate* tax_rate_buffer = (tax_rate*)memops::alloc(sizeof(tax_rate)*administration::billing_item_count(&inv)); u32 tax_rate_count = administration::invoice_get_tax_rates(&inv, tax_rate_buffer); - u32 tax_subtotal_list_buffer_size = (u32)strlen(file_template::peppol_invoice_tax_subtotal_template) * 2 * tax_rate_count; // Ballpark list size. + u32 tax_subtotal_list_buffer_size = (u32)strops::length(file_template::peppol_invoice_tax_subtotal_template) * 2 * tax_rate_count; // Ballpark list size. char* tax_subtotal_list_buffer = (char*)memops::alloc(tax_subtotal_list_buffer_size); memops::zero(tax_subtotal_list_buffer, tax_subtotal_list_buffer_size); u32 tax_subtotal_list_buffer_cursor = 0; @@ -430,7 +430,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) strops::replace(tax_entry_file_content, tax_entry_buf_length, "{{TAX_CATEGORY}}", tax_rate_buffer[i].category_code); strops::replace_float(tax_entry_file_content, tax_entry_buf_length, "{{TAX_PERCENT}}", tax_rate_buffer[i].rate, 2); - u32 content_len = (u32)strlen(tax_entry_file_content); + u32 content_len = (u32)strops::length(tax_entry_file_content); memops::copy(tax_subtotal_list_buffer+tax_subtotal_list_buffer_cursor, tax_entry_file_content, content_len); tax_subtotal_list_buffer_cursor += content_len; @@ -454,7 +454,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) billing_item* billing_item_buffer = (billing_item*)memops::alloc(sizeof(billing_item) * administration::billing_item_count(&inv)); u32 billing_item_count = administration::billing_item_get_all_for_invoice(&inv, billing_item_buffer); - u32 billing_item_list_buffer_size = (u32)strlen(file_template::peppol_invoice_line_template) * 2 * billing_item_count; // Ballpark list size. + u32 billing_item_list_buffer_size = (u32)strops::length(file_template::peppol_invoice_line_template) * 2 * billing_item_count; // Ballpark list size. char* billing_item_list_buffer = (char*)memops::alloc(billing_item_list_buffer_size); memops::zero(billing_item_list_buffer, billing_item_list_buffer_size); u32 billing_item_list_buffer_cursor = 0; @@ -490,7 +490,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) strops::replace_float(billing_item_file_content, billing_item_buf_length, "{{DISCOUNT_TOTAL}}", bi.allowance, 2); - u32 content_len = (u32)strlen(billing_item_file_content); + u32 content_len = (u32)strops::length(billing_item_file_content); memops::copy(billing_item_list_buffer+billing_item_list_buffer_cursor, billing_item_file_content, content_len); billing_item_list_buffer_cursor += content_len; @@ -518,7 +518,7 @@ bool administration_writer::save_invoice_blocking(invoice inv) char final_path[50]; strops::format(final_path, 50, "%s.xml", inv.id); - int final_length = (int)strlen(file_content); + int final_length = (int)strops::length(file_content); if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; else if (!write_to_zip(final_path, file_content, final_length)) result = 0; @@ -577,7 +577,7 @@ bool administration_writer::save_project_blocking(project project) char final_path[50]; strops::format(final_path, 50, "%s.xml", project.id); - int final_length = (int)strlen(file_content); + int final_length = (int)strops::length(file_content); if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; else if (!write_to_zip(final_path, file_content, final_length)) result = 0; @@ -625,7 +625,7 @@ bool administration_writer::save_cost_center_blocking(cost_center cost) char final_path[50]; strops::format(final_path, 50, "%s.xml", cost.id); - int final_length = (int)strlen(file_content); + int final_length = (int)strops::length(file_content); if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; else if (!write_to_zip(final_path, file_content, final_length)) result = 0; @@ -682,7 +682,7 @@ bool administration_writer::save_tax_rate_blocking(tax_rate rate) char final_path[50]; strops::format(final_path, 50, "T/%s.xml", rate.internal_code); - int final_length = (int)strlen(file_content); + int final_length = (int)strops::length(file_content); if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; else if (!write_to_zip(final_path, file_content, final_length)) result = 0; @@ -745,7 +745,7 @@ bool administration_writer::save_contact_blocking(contact c) char final_path[50]; strops::format(final_path, 50, "%s.xml", c.id); - int final_length = (int)strlen(file_content); + int final_length = (int)strops::length(file_content); if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; else if (!write_to_zip(final_path, file_content, final_length)) result = 0; @@ -801,7 +801,7 @@ bool administration_writer::save_all_administration_info_blocking() strops::replace(file_content, buf_length, "{{AI_SERVICE_MODEL}}", ai_service.model_name); //// Write to Disk. - int final_length = (int)strlen(file_content); + int final_length = (int)strops::length(file_content); if (!xml_parse_document((uint8_t*)file_content, final_length)) result = 0; else if (!write_to_zip(ADMIN_FILE_INFO, file_content, final_length)) result = 0; diff --git a/src/ai_providers/DeepSeek.cpp b/src/ai_providers/DeepSeek.cpp index 0a7dbbd..ede31f8 100644 --- a/src/ai_providers/DeepSeek.cpp +++ b/src/ai_providers/DeepSeek.cpp @@ -38,10 +38,10 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi //char* query_escaped = strops::prep_str_for_json(query, query_length); //memops::unalloc(query); // TODO why?? - size_t file_size = strlen(query_buffer); + size_t file_size = strops::length(query_buffer); sprintf(query_buffer + file_size, "%s", query); - char* query_escaped = strops::prep_str_for_json(query_buffer, strlen(query_buffer)); + char* query_escaped = strops::prep_str_for_json(query_buffer, strops::length(query_buffer)); size_t body_size = file_size + QUERY_BUFFER_SIZE; char* body = (char*)memops::alloc(body_size); @@ -65,7 +65,7 @@ static bool _DeepSeek_query_with_file(char* query, size_t query_length, char* fi char* response_body = (char*)res->body.c_str(); *response = (char*)memops::alloc(100000); memops::zero(*response, 100000); - strncpy(*response, response_body, 100000); + strops::copy(*response, response_body, 100000); strops::get_json_value(*response, "content", *response, 100000); *response = strops::unprep_str_from_json(*response); diff --git a/src/ai_providers/openAI.cpp b/src/ai_providers/openAI.cpp index 0afd2e7..fa2cc05 100644 --- a/src/ai_providers/openAI.cpp +++ b/src/ai_providers/openAI.cpp @@ -16,6 +16,7 @@ #define CPPHTTPLIB_OPENSSL_SUPPORT #include "httplib.h" + #include "memops.hpp" #include "strops.hpp" #include "logger.hpp" @@ -53,7 +54,7 @@ static bool _openAI_query_with_file(char* query, size_t query_length, char* file char* response_body = (char*)res->body.c_str(); *response = (char*)memops::alloc(100000); memops::zero(*response, 100000); - strncpy(*response, response_body, 100000); + strops::copy(*response, response_body, 100000); strops::get_json_value(*response, "text", *response, 100000); *response = strops::unprep_str_from_json(*response); @@ -137,15 +138,15 @@ static bool _openAI_upload_file(char* file_path, char* file_id, size_t file_id_l else { char part_id[128]; strops::get_json_value(part_res->body.c_str(), "id", part_id, sizeof(part_id)); - if (part_number == 0) strops::format(completion_body+strlen(completion_body), sizeof(completion_body)-strlen(completion_body), "\"%s\"", part_id); - if (part_number != 0) strops::format(completion_body+strlen(completion_body), sizeof(completion_body)-strlen(completion_body), ", \"%s\"", part_id); + if (part_number == 0) strops::format(completion_body+strops::length(completion_body), sizeof(completion_body)-strops::length(completion_body), "\"%s\"", part_id); + if (part_number != 0) strops::format(completion_body+strops::length(completion_body), sizeof(completion_body)-strops::length(completion_body), ", \"%s\"", part_id); } logger::info("Uploaded part %d\n", part_number); part_number++; } - strops::format(completion_body+strlen(completion_body), sizeof(completion_body)-strlen(completion_body), "]}"); + strops::format(completion_body+strops::length(completion_body), sizeof(completion_body)-strops::length(completion_body), "]}"); memops::unalloc(buffer); fclose(orig_file); diff --git a/src/importer.cpp b/src/importer.cpp index ae8bada..194913a 100644 --- a/src/importer.cpp +++ b/src/importer.cpp @@ -61,7 +61,7 @@ static int _ai_document_to_invoice_t(void *arg) { char* template_buffer = (char*)memops::alloc(query_buffer_len); memops::zero(template_buffer, query_buffer_len); - strncpy(template_buffer, file_template::peppol_invoice_template, query_buffer_len); + strops::copy(template_buffer, file_template::peppol_invoice_template, query_buffer_len); strops::replace(template_buffer, 50000, "{{INVOICE_LINE_LIST}}", file_template::peppol_invoice_line_template); char* ai_query = @@ -93,8 +93,8 @@ static int _ai_document_to_invoice_t(void *arg) { "cac:Delivery contains the delivery address for physical goods. This information might be under the section 'Shipping address', 'Shipped to' or something similar. If this is not explicitly set, leave this section empty.\n" ; - size_t query_len = strlen(template_buffer); - strncpy(template_buffer + query_len, ai_query, query_buffer_len - query_len); + size_t query_len = strops::length(template_buffer); + strops::copy(template_buffer + query_len, ai_query, query_buffer_len - query_len); request->status = importer::status::IMPORT_WAITING_FOR_RESPONSE; @@ -106,7 +106,7 @@ static int _ai_document_to_invoice_t(void *arg) { } invoice inv; - if (!administration_reader::read_invoice_from_xml(&inv, response, strlen(response))) { + if (!administration_reader::read_invoice_from_xml(&inv, response, strops::length(response))) { request->status = importer::status::IMPORT_DONE; request->error = I_ERR_FAILED_IMPORT; return 0; diff --git a/src/memops.cpp b/src/memops.cpp index a05644a..0e0889a 100644 --- a/src/memops.cpp +++ b/src/memops.cpp @@ -42,4 +42,9 @@ void* memops::copy(void* destination, const void* source, size_t num) void memops::zero(void* destination, size_t num) { memset(destination, 0, num); +} + +bool memops::equals(void* m1, void* m2, size_t size) +{ + return memcmp(m1, m2, size) == 0; }
\ No newline at end of file diff --git a/src/strops.cpp b/src/strops.cpp index efa91e6..2dfbf16 100644 --- a/src/strops.cpp +++ b/src/strops.cpp @@ -24,14 +24,14 @@ namespace strops { bool is_prefixed(const char *pre, const char *str) { - return strncmp(pre, str, strlen(pre)) == 0; + return strncmp(pre, str, strops::length(pre)) == 0; } size_t copy(char *dst, const char *src, size_t size) { size_t srclen; size --; - srclen = strlen(src); + srclen = strops::length(src); if (srclen > size) srclen = size; @@ -47,6 +47,16 @@ namespace strops { return strcmp(a, b) == 0; } + size_t length(const char* str) + { + return strlen(str); + } + + bool empty(const char* str) + { + return strlen(str) == 0; + } + char* contains(char* haystack, char* needle) { do { @@ -85,8 +95,8 @@ namespace strops { void replace(char *buf, size_t buf_size, const char *search, const char *replace) { - size_t search_len = strlen(search); - size_t replace_len = strlen(replace); + size_t search_len = strops::length(search); + size_t replace_len = strops::length(replace); char *r = buf; // read pointer char *w = buf; // write pointer diff --git a/src/ui/imgui_extensions.cpp b/src/ui/imgui_extensions.cpp index 66160ae..b59c13f 100644 --- a/src/ui/imgui_extensions.cpp +++ b/src/ui/imgui_extensions.cpp @@ -252,7 +252,7 @@ namespace ImGui costcenter_count = administration::cost_center_get_all(buffer); // Select cost center by given id. - if (strlen(costcenter_id) > 0) + if (!strops::empty(costcenter_id)) { for (u32 i = 0; i < costcenter_count; i++) { @@ -293,7 +293,7 @@ namespace ImGui project_count = administration::project_get_all(buffer); // Select project by given id. - if (strlen(project_id) > 0) + if (!strops::empty(project_id)) { for (u32 i = 0; i < project_count; i++) { @@ -334,7 +334,7 @@ namespace ImGui tax_rate_count = administration::tax_rate_get_all(buffer, outgoing ? tax_rate_type::TAX_RATE_OUTGOING_INVOICE : tax_rate_type::TAX_RATE_INCOMMING_INVOICE); // Select tax rate by given id. - if (strlen(tax_internal_code) > 0) + if (!strops::empty(tax_internal_code)) { for (u32 i = 0; i < tax_rate_count; i++) { @@ -411,7 +411,7 @@ namespace ImGui }; int currency_count = sizeof(currencies) / sizeof(char*); - if (strlen(currency) > 0) + if (!strops::empty(currency)) { for (int i = 0; i < currency_count; i++) { |
