Просмотр исходного кода

[FL-2970] Untangle NFC_APP_FOLDER from nfc_device (#2124)

* Untangle NFC_APP_FOLDER from nfc_device
* Make the folder an internal part of the nfc device struct
* Move the NFC folder definition to the nfc allocator
* Move the NFC folder definition to the allocator in the nfc magic FAP
* Replace furi_string_printf with furi_string_set for folder allocation and handle the cases when folder has no slashes
* Build and allocation fixes

Co-authored-by: あく <alleteam@gmail.com>
Astra 3 лет назад
Родитель
Сommit
fa87216a1e

+ 1 - 0
applications/main/nfc/nfc.c

@@ -46,6 +46,7 @@ Nfc* nfc_alloc() {
 
     // Nfc device
     nfc->dev = nfc_device_alloc();
+    furi_string_set(nfc->dev->folder, NFC_APP_FOLDER);
 
     // Open GUI record
     nfc->gui = furi_record_open(RECORD_GUI);

+ 1 - 0
applications/main/nfc/nfc_i.h

@@ -44,6 +44,7 @@
 ARRAY_DEF(MfClassicUserKeys, char*, M_PTR_OPLIST);
 
 #define NFC_TEXT_STORE_SIZE 128
+#define NFC_APP_FOLDER ANY_PATH("nfc")
 
 typedef enum {
     NfcRpcStateIdle,

+ 1 - 0
applications/plugins/nfc_magic/nfc_magic.c

@@ -49,6 +49,7 @@ NfcMagic* nfc_magic_alloc() {
 
     // Nfc device
     nfc_magic->nfc_dev = nfc_device_alloc();
+    furi_string_set(nfc_magic->nfc_dev->folder, NFC_APP_FOLDER);
 
     // Open GUI record
     nfc_magic->gui = furi_record_open(RECORD_GUI);

+ 2 - 0
applications/plugins/nfc_magic/nfc_magic_i.h

@@ -27,6 +27,8 @@
 #include <lib/nfc/nfc_device.h>
 #include "nfc_magic_icons.h"
 
+#define NFC_APP_FOLDER ANY_PATH("nfc")
+
 enum NfcMagicCustomEvent {
     // Reserve first 100 events for button types and indexes, starting from 0
     NfcMagicCustomEventReserved = 100,

+ 47 - 11
lib/nfc/nfc_device.c

@@ -27,6 +27,7 @@ NfcDevice* nfc_device_alloc() {
     nfc_dev->dialogs = furi_record_open(RECORD_DIALOGS);
     nfc_dev->load_path = furi_string_alloc();
     nfc_dev->dev_data.parsed_data = furi_string_alloc();
+    nfc_dev->folder = furi_string_alloc();
 
     // Rename cache folder name for backward compatibility
     if(storage_common_stat(nfc_dev->storage, "/ext/nfc/cache", NULL) == FSE_OK) {
@@ -42,6 +43,7 @@ void nfc_device_free(NfcDevice* nfc_dev) {
     furi_record_close(RECORD_DIALOGS);
     furi_string_free(nfc_dev->load_path);
     furi_string_free(nfc_dev->dev_data.parsed_data);
+    furi_string_free(nfc_dev->folder);
     free(nfc_dev);
 }
 
@@ -1018,6 +1020,16 @@ static void nfc_device_get_shadow_path(FuriString* orig_path, FuriString* shadow
     furi_string_cat_printf(shadow_path, "%s", NFC_APP_SHADOW_EXTENSION);
 }
 
+static void nfc_device_get_folder_from_path(FuriString* path, FuriString* folder) {
+    size_t last_slash = furi_string_search_rchar(path, '/');
+    if(last_slash == FURI_STRING_FAILURE) {
+        // No slashes in the path, treat the whole path as a folder
+        furi_string_set(folder, path);
+    } else {
+        furi_string_set_n(folder, path, 0, last_slash);
+    }
+}
+
 bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
     furi_assert(dev);
 
@@ -1028,10 +1040,19 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
     temp_str = furi_string_alloc();
 
     do {
-        // Create nfc directory if necessary
-        if(!storage_simply_mkdir(dev->storage, NFC_APP_FOLDER)) break;
+        // Create directory if necessary
+        FuriString* folder = furi_string_alloc();
+        // Get folder from filename (filename is in the form of "folder/filename.nfc", so the folder is "folder/")
+        furi_string_set(temp_str, dev_name);
+        // Get folder from filename
+        nfc_device_get_folder_from_path(temp_str, folder);
+        FURI_LOG_I("Nfc", "Saving to folder %s", furi_string_get_cstr(folder));
+        if(!storage_simply_mkdir(dev->storage, furi_string_get_cstr(folder))) {
+            FURI_LOG_E("Nfc", "Failed to create folder %s", furi_string_get_cstr(folder));
+            break;
+        }
+        furi_string_free(folder);
         // First remove nfc device file if it was saved
-        furi_string_printf(temp_str, "%s", dev_name);
         // Open file
         if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;
         // Write header
@@ -1199,10 +1220,9 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog) {
 
 bool nfc_file_select(NfcDevice* dev) {
     furi_assert(dev);
+    const char* folder = furi_string_get_cstr(dev->folder);
 
     // Input events and views are managed by file_browser
-    FuriString* nfc_app_folder;
-    nfc_app_folder = furi_string_alloc_set(NFC_APP_FOLDER);
 
     const DialogsFileBrowserOptions browser_options = {
         .extension = NFC_APP_EXTENSION,
@@ -1212,13 +1232,12 @@ bool nfc_file_select(NfcDevice* dev) {
         .hide_ext = true,
         .item_loader_callback = NULL,
         .item_loader_context = NULL,
-        .base_path = NFC_APP_FOLDER,
+        .base_path = folder,
     };
 
     bool res =
         dialog_file_browser_show(dev->dialogs, dev->load_path, dev->load_path, &browser_options);
 
-    furi_string_free(nfc_app_folder);
     if(res) {
         FuriString* filename;
         filename = furi_string_alloc();
@@ -1271,7 +1290,11 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) {
             furi_string_set(file_path, dev->load_path);
         } else {
             furi_string_printf(
-                file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION);
+                file_path,
+                "%s/%s%s",
+                furi_string_get_cstr(dev->folder),
+                dev->dev_name,
+                NFC_APP_EXTENSION);
         }
         if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break;
         // Delete shadow file if it exists
@@ -1280,7 +1303,11 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) {
                 nfc_device_get_shadow_path(dev->load_path, file_path);
             } else {
                 furi_string_printf(
-                    file_path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION);
+                    file_path,
+                    "%s/%s%s",
+                    furi_string_get_cstr(dev->folder),
+                    dev->dev_name,
+                    NFC_APP_SHADOW_EXTENSION);
             }
             if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break;
         }
@@ -1309,14 +1336,23 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) {
             nfc_device_get_shadow_path(dev->load_path, path);
         } else {
             furi_string_printf(
-                path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_SHADOW_EXTENSION);
+                path,
+                "%s/%s%s",
+                furi_string_get_cstr(dev->folder),
+                dev->dev_name,
+                NFC_APP_SHADOW_EXTENSION);
         }
         if(!storage_simply_remove(dev->storage, furi_string_get_cstr(path))) break;
         dev->shadow_file_exist = false;
         if(use_load_path && !furi_string_empty(dev->load_path)) {
             furi_string_set(path, dev->load_path);
         } else {
-            furi_string_printf(path, "%s/%s%s", NFC_APP_FOLDER, dev->dev_name, NFC_APP_EXTENSION);
+            furi_string_printf(
+                path,
+                "%s/%s%s",
+                furi_string_get_cstr(dev->folder),
+                dev->dev_name,
+                NFC_APP_EXTENSION);
         }
         if(!nfc_device_load_data(dev, path, true)) break;
         restored = true;

+ 1 - 1
lib/nfc/nfc_device.h

@@ -20,7 +20,6 @@ extern "C" {
 #define NFC_READER_DATA_MAX_SIZE 64
 #define NFC_DICT_KEY_BATCH_SIZE 50
 
-#define NFC_APP_FOLDER ANY_PATH("nfc")
 #define NFC_APP_EXTENSION ".nfc"
 #define NFC_APP_SHADOW_EXTENSION ".shd"
 
@@ -84,6 +83,7 @@ typedef struct {
     NfcDeviceData dev_data;
     char dev_name[NFC_DEV_NAME_MAX_LEN + 1];
     FuriString* load_path;
+    FuriString* folder;
     NfcDeviceSaveFormat format;
     bool shadow_file_exist;