M*LIB: non-inlined strings, FuriString primitive (#1795)

* Quicksave 1
* Header stage complete
* Source stage complete
* Lint & merge fixes
* Includes
* Documentation step 1
* FBT: output free size considering BT STACK
* Documentation step 2
* py lint
* Fix music player plugin
* unit test stage 1: string allocator, mem, getters, setters, appends, compare, search.
* unit test: string equality
* unit test: string replace
* unit test: string start_with, end_with
* unit test: string trim
* unit test: utf-8
* Rename
* Revert fw_size changes
* Simplify CLI backspace handling
* Simplify CLI character insert
* Merge fixes
* Furi: correct filenaming and spelling
* Bt: remove furi string include

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Sergey Gavrilov
2022-10-06 01:15:23 +10:00
committed by GitHub
parent 0f9ea925d3
commit 4bf29827f8
370 changed files with 5597 additions and 3963 deletions

View File

@@ -18,7 +18,7 @@ PicopassDevice* picopass_device_alloc() {
picopass_dev->dev_data.pacs.pin_length = 0;
picopass_dev->storage = furi_record_open(RECORD_STORAGE);
picopass_dev->dialogs = furi_record_open(RECORD_DIALOGS);
string_init(picopass_dev->load_path);
picopass_dev->load_path = furi_string_alloc();
return picopass_dev;
}
@@ -40,25 +40,25 @@ static bool picopass_device_save_file(
FlipperFormat* file = flipper_format_file_alloc(dev->storage);
PicopassPacs* pacs = &dev->dev_data.pacs;
PicopassBlock* AA1 = dev->dev_data.AA1;
string_t temp_str;
string_init(temp_str);
FuriString* temp_str;
temp_str = furi_string_alloc();
do {
if(use_load_path && !string_empty_p(dev->load_path)) {
if(use_load_path && !furi_string_empty(dev->load_path)) {
// Get directory name
path_extract_dirname(string_get_cstr(dev->load_path), temp_str);
path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str);
// Create picopass directory if necessary
if(!storage_simply_mkdir(dev->storage, string_get_cstr(temp_str))) break;
if(!storage_simply_mkdir(dev->storage, furi_string_get_cstr(temp_str))) break;
// Make path to file to save
string_cat_printf(temp_str, "/%s%s", dev_name, extension);
furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension);
} else {
// Create picopass directory if necessary
if(!storage_simply_mkdir(dev->storage, PICOPASS_APP_FOLDER)) break;
// First remove picopass device file if it was saved
string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
}
// Open file
if(!flipper_format_file_open_always(file, string_get_cstr(temp_str))) break;
if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;
if(dev->format == PicopassDeviceSaveFormatHF) {
uint32_t fc = pacs->record.FacilityCode;
@@ -87,9 +87,9 @@ static bool picopass_device_save_file(
AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0] :
PICOPASS_MAX_APP_LIMIT;
for(size_t i = 0; i < app_limit; i++) {
string_printf(temp_str, "Block %d", i);
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_write_hex(
file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
block_saved = false;
break;
}
@@ -117,7 +117,7 @@ static bool picopass_device_save_file(
if(!saved) {
dialog_message_show_storage_error(dev->dialogs, "Can not save\nfile");
}
string_clear(temp_str);
furi_string_free(temp_str);
flipper_format_free(file);
return saved;
}
@@ -132,13 +132,13 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) {
return false;
}
static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool show_dialog) {
static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, bool show_dialog) {
bool parsed = false;
FlipperFormat* file = flipper_format_file_alloc(dev->storage);
PicopassBlock* AA1 = dev->dev_data.AA1;
PicopassPacs* pacs = &dev->dev_data.pacs;
string_t temp_str;
string_init(temp_str);
FuriString* temp_str;
temp_str = furi_string_alloc();
bool deprecated_version = false;
if(dev->loading_cb) {
@@ -146,12 +146,13 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s
}
do {
if(!flipper_format_file_open_existing(file, string_get_cstr(path))) break;
if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break;
// Read and verify file header
uint32_t version = 0;
if(!flipper_format_read_header(file, temp_str, &version)) break;
if(string_cmp_str(temp_str, picopass_file_header) || (version != picopass_file_version)) {
if(furi_string_cmp_str(temp_str, picopass_file_header) ||
(version != picopass_file_version)) {
deprecated_version = true;
break;
}
@@ -159,9 +160,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s
// Parse header blocks
bool block_read = true;
for(size_t i = 0; i < 6; i++) {
string_printf(temp_str, "Block %d", i);
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_read_hex(
file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
block_read = false;
break;
}
@@ -169,9 +170,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s
size_t app_limit = AA1[PICOPASS_CONFIG_BLOCK_INDEX].data[0];
for(size_t i = 6; i < app_limit; i++) {
string_printf(temp_str, "Block %d", i);
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_read_hex(
file, string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
file, furi_string_get_cstr(temp_str), AA1[i].data, PICOPASS_BLOCK_LEN)) {
block_read = false;
break;
}
@@ -196,7 +197,7 @@ static bool picopass_device_load_data(PicopassDevice* dev, string_t path, bool s
}
}
string_clear(temp_str);
furi_string_free(temp_str);
flipper_format_free(file);
return parsed;
@@ -208,7 +209,7 @@ void picopass_device_clear(PicopassDevice* dev) {
picopass_device_data_clear(&dev->dev_data);
memset(&dev->dev_data, 0, sizeof(dev->dev_data));
dev->format = PicopassDeviceSaveFormatHF;
string_reset(dev->load_path);
furi_string_reset(dev->load_path);
}
void picopass_device_free(PicopassDevice* picopass_dev) {
@@ -216,7 +217,7 @@ void picopass_device_free(PicopassDevice* picopass_dev) {
picopass_device_clear(picopass_dev);
furi_record_close(RECORD_STORAGE);
furi_record_close(RECORD_DIALOGS);
string_clear(picopass_dev->load_path);
furi_string_free(picopass_dev->load_path);
free(picopass_dev);
}
@@ -224,8 +225,8 @@ bool picopass_file_select(PicopassDevice* dev) {
furi_assert(dev);
// Input events and views are managed by file_browser
string_t picopass_app_folder;
string_init_set_str(picopass_app_folder, PICOPASS_APP_FOLDER);
FuriString* picopass_app_folder;
picopass_app_folder = furi_string_alloc_set(PICOPASS_APP_FOLDER);
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(&browser_options, PICOPASS_APP_EXTENSION, &I_Nfc_10px);
@@ -233,17 +234,17 @@ bool picopass_file_select(PicopassDevice* dev) {
bool res = dialog_file_browser_show(
dev->dialogs, dev->load_path, picopass_app_folder, &browser_options);
string_clear(picopass_app_folder);
furi_string_free(picopass_app_folder);
if(res) {
string_t filename;
string_init(filename);
FuriString* filename;
filename = furi_string_alloc();
path_extract_filename(dev->load_path, filename, true);
strncpy(dev->dev_name, string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN);
strncpy(dev->dev_name, furi_string_get_cstr(filename), PICOPASS_DEV_NAME_MAX_LEN);
res = picopass_device_load_data(dev, dev->load_path, true);
if(res) {
picopass_device_set_name(dev, dev->dev_name);
}
string_clear(filename);
furi_string_free(filename);
}
return res;
@@ -262,18 +263,18 @@ bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) {
furi_assert(dev);
bool deleted = false;
string_t file_path;
string_init(file_path);
FuriString* file_path;
file_path = furi_string_alloc();
do {
// Delete original file
if(use_load_path && !string_empty_p(dev->load_path)) {
string_set(file_path, dev->load_path);
if(use_load_path && !furi_string_empty(dev->load_path)) {
furi_string_set(file_path, dev->load_path);
} else {
string_printf(
furi_string_printf(
file_path, "%s/%s%s", PICOPASS_APP_FOLDER, dev->dev_name, PICOPASS_APP_EXTENSION);
}
if(!storage_simply_remove(dev->storage, string_get_cstr(file_path))) break;
if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break;
deleted = true;
} while(0);
@@ -281,7 +282,7 @@ bool picopass_device_delete(PicopassDevice* dev, bool use_load_path) {
dialog_message_show_storage_error(dev->dialogs, "Can not remove file");
}
string_clear(file_path);
furi_string_free(file_path);
return deleted;
}

View File

@@ -71,7 +71,7 @@ typedef struct {
DialogsApp* dialogs;
PicopassDeviceData dev_data;
char dev_name[PICOPASS_DEV_NAME_MAX_LEN + 1];
string_t load_path;
FuriString* load_path;
PicopassDeviceSaveFormat format;
PicopassLoadingCallback loading_cb;
void* loading_cb_ctx;

View File

@@ -51,7 +51,7 @@ struct Picopass {
PicopassDevice* dev;
char text_store[PICOPASS_TEXT_STORE_SIZE + 1];
string_t text_box_store;
FuriString* text_box_store;
// Common Views
Submenu* submenu;

View File

@@ -14,10 +14,10 @@ void picopass_scene_device_info_widget_callback(
void picopass_scene_device_info_on_enter(void* context) {
Picopass* picopass = context;
string_t credential_str;
string_t wiegand_str;
string_init(credential_str);
string_init(wiegand_str);
FuriString* credential_str;
FuriString* wiegand_str;
credential_str = furi_string_alloc();
wiegand_str = furi_string_alloc();
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
@@ -26,25 +26,31 @@ void picopass_scene_device_info_on_enter(void* context) {
Widget* widget = picopass->widget;
size_t bytesLength = 1 + pacs->record.bitLength / 8;
string_set_str(credential_str, "");
furi_string_set(credential_str, "");
for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) {
string_cat_printf(credential_str, " %02X", pacs->credential[i]);
furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]);
}
if(pacs->record.valid) {
string_cat_printf(
furi_string_cat_printf(
wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber);
} else {
string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength);
furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength);
}
widget_add_string_element(
widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str));
widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str));
widget_add_string_element(
widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str));
widget,
64,
32,
AlignCenter,
AlignCenter,
FontSecondary,
furi_string_get_cstr(credential_str));
string_clear(credential_str);
string_clear(wiegand_str);
furi_string_free(credential_str);
furi_string_free(wiegand_str);
widget_add_button_element(
picopass->widget,

View File

@@ -15,12 +15,12 @@ void picopass_scene_read_card_success_widget_callback(
void picopass_scene_read_card_success_on_enter(void* context) {
Picopass* picopass = context;
string_t credential_str;
string_t wiegand_str;
string_t sio_str;
string_init(credential_str);
string_init(wiegand_str);
string_init(sio_str);
FuriString* credential_str;
FuriString* wiegand_str;
FuriString* sio_str;
credential_str = furi_string_alloc();
wiegand_str = furi_string_alloc();
sio_str = furi_string_alloc();
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
@@ -32,10 +32,10 @@ void picopass_scene_read_card_success_on_enter(void* context) {
Widget* widget = picopass->widget;
if(pacs->record.bitLength == 0) {
string_cat_printf(wiegand_str, "Read Failed");
furi_string_cat_printf(wiegand_str, "Read Failed");
if(pacs->se_enabled) {
string_cat_printf(credential_str, "SE enabled");
furi_string_cat_printf(credential_str, "SE enabled");
}
widget_add_button_element(
@@ -47,20 +47,20 @@ void picopass_scene_read_card_success_on_enter(void* context) {
} else {
size_t bytesLength = 1 + pacs->record.bitLength / 8;
string_set_str(credential_str, "");
furi_string_set(credential_str, "");
for(uint8_t i = PICOPASS_BLOCK_LEN - bytesLength; i < PICOPASS_BLOCK_LEN; i++) {
string_cat_printf(credential_str, " %02X", pacs->credential[i]);
furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]);
}
if(pacs->record.valid) {
string_cat_printf(
furi_string_cat_printf(
wiegand_str, "FC: %u CN: %u", pacs->record.FacilityCode, pacs->record.CardNumber);
} else {
string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength);
furi_string_cat_printf(wiegand_str, "%d bits", pacs->record.bitLength);
}
if(pacs->sio) {
string_cat_printf(sio_str, "+SIO");
furi_string_cat_printf(sio_str, "+SIO");
}
widget_add_button_element(
@@ -79,15 +79,21 @@ void picopass_scene_read_card_success_on_enter(void* context) {
}
widget_add_string_element(
widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, string_get_cstr(wiegand_str));
widget, 64, 12, AlignCenter, AlignCenter, FontPrimary, furi_string_get_cstr(wiegand_str));
widget_add_string_element(
widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(credential_str));
widget,
64,
32,
AlignCenter,
AlignCenter,
FontSecondary,
furi_string_get_cstr(credential_str));
widget_add_string_element(
widget, 64, 42, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(sio_str));
widget, 64, 42, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str));
string_clear(credential_str);
string_clear(wiegand_str);
string_clear(sio_str);
furi_string_free(credential_str);
furi_string_free(wiegand_str);
furi_string_free(sio_str);
view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget);
}

View File

@@ -1,5 +1,4 @@
#include "../picopass_i.h"
#include "m-string.h"
#include <lib/toolbox/random_name.h>
#include <gui/modules/validators.h>
#include <toolbox/path.h>
@@ -31,22 +30,22 @@ void picopass_scene_save_name_on_enter(void* context) {
PICOPASS_DEV_NAME_MAX_LEN,
dev_name_empty);
string_t folder_path;
string_init(folder_path);
FuriString* folder_path;
folder_path = furi_string_alloc();
if(string_end_with_str_p(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) {
path_extract_dirname(string_get_cstr(picopass->dev->load_path), folder_path);
if(furi_string_end_with(picopass->dev->load_path, PICOPASS_APP_EXTENSION)) {
path_extract_dirname(furi_string_get_cstr(picopass->dev->load_path), folder_path);
} else {
string_set_str(folder_path, PICOPASS_APP_FOLDER);
furi_string_set(folder_path, PICOPASS_APP_FOLDER);
}
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name);
furi_string_get_cstr(folder_path), PICOPASS_APP_EXTENSION, picopass->dev->dev_name);
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewTextInput);
string_clear(folder_path);
furi_string_free(folder_path);
}
bool picopass_scene_save_name_on_event(void* context, SceneManagerEvent event) {