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:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user