Save

NotPike 2022-02-01 16:22:01 -08:00
parent 36589a8491
commit 3e31a4a3fd

@ -120,69 +120,369 @@ if(check_sd_card()) { // Check to see if SD Card is mounted
} }
``` ```
### Delete Directory
### Create File ### Create File
To create a file we can use the `create()` function from [File](https://github.com/eried/portapack-mayhem/blob/next/firmware/application/file.cpp) class. The helper function below will return true if `create()` succeeds (Success from `create()` returns a 0, other values means failure) and takes two variable inputs for file path and directory name. Again the input for the file path is a `std::filesystem::path` which can be `UTF-16 string literal`. The root of the SD Card is `u""` and any directory beyond that is `u"DIRECTORY/SUB_DIRECTORY"`.
#### ui_newapp.cpp
```
bool NewAppView::create_file(const std::filesystem::path& path, std::string name) {
File file = { }; // Create File object
Optional<File::Error> sucess = file.create(path.string() + "/" + name); // Create File
return !(sucess.is_valid()); // 0 is success
}
```
Below is an example on how the `create_file()` function can be used with basic error handling.
#### ui_newapp.cpp
```
// New file
if(check_sd_card()) { // Check to see if SD Card is mounted
if(create_file(u"", "NEW_FILE.txt")) { // New file in root of SD Card, returns true if successful
// Logic if new file succeeded
} else {
// Logic else new file failed
}
} else { // Else, check_sd_card() returned false
// Logic else SD Card is NOT mounted
}
```
### Read File ### Read File
### Write File ### Write File
### Delete File ### Delete File or Directory
**NOTE: Code below reflects future update, current implementation of delete_file() dose not return a value.**
To delete a file or directory the `delete_file()` function from [File](https://github.com/eried/portapack-mayhem/blob/next/firmware/application/file.cpp) can be used. The helper function below will return true if `delete_file()` succeeds (Success from `make_new_directory()` returns a 0, other values means failure) and takes two variable inputs for file path and directory name. Again the input for the file path is a `std::filesystem::path` which can be `UTF-16 string literal`. The root of the SD Card is `u""` and any directory beyond that is `u"DIRECTORY/SUB_DIRECTORY"`
#### ui_newapp.cpp
```
bool NewAppView::delete_dir_or_file(const std::filesystem::path& path, std::string name) {
return !(delete_file(path.string() + "/" + name));
}
```
Below is an example on how the `delete_dir_or_file()` function can be used with basic error handling.
#### ui_newapp.cpp
```
if(check_sd_card()) { // Check to see if SD Card is mounted
if(delete_dir_or_file(u"", "NEW_DIR")) { // New dir in root of SD Card
// Logic if file/dir delete was successful
} else {
// Logic if file/dir delete was NOT successful
}
} else { // Else, check_sd_card() returned false
// Logic else SD Card is NOT mounted
}
```
## Wrap Up ## Wrap Up
Below is example demo of all basic CRUD functions for files and directorys.
### ui_newapp.hpp ### ui_newapp.hpp
```
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "string_format.hpp"
#include "ui.hpp" // Add these to include File Class and SD Card helper functions.
#include "ui_widget.hpp" #include "file.hpp"
#include "ui_navigation.hpp" #include "sd_card.hpp"
#include "string_format.hpp"
// Add this to include the File Class. namespace ui
#include "file.hpp" {
// Struct that outlines file information
struct file_entry {
std::filesystem::path entry_path { };
uint32_t size { };
bool is_directory { };
};
namespace ui
{
class NewAppView : public View // App class declaration class NewAppView : public View // App class declaration
{ {
public: public:
// Public declarations
void focus() override; // ui::View function override
NewAppView(NavigationView &nav); // App class init function declaration NewAppView(NavigationView &nav); // App class init function declaration
std::string title() const override { return "New App"; }; // App title std::string title() const override { return "New App"; }; // App title
private: private:
void update(); // Function declaration
MessageHandlerRegistration message_handler_update{ // Example, not required: MessageHandlerRegistration class // Function declarations
Message::ID::DisplayFrameSync, // relays messages to your app code from baseband. Every time you
[this](const Message *const) { // get a DisplayFrameSync message the update() function will // Error check
this->update(); // be triggered. bool check_sd_card();
}};
// DIR CRUD
bool create_dir(const std::filesystem::path& path, std::string name);
std::vector<file_entry> list_dir(const std::filesystem::path& path);
// File CRUD
bool create_file(const std::filesystem::path& path, std::string name);
bool rename_dir_or_file(const std::filesystem::path& path, std::string old_name, std::string new_name);
std::string read_file(const std::filesystem::path& path, std::string name);
bool write_file(const std::filesystem::path& path, std::string name, std::string data);
bool delete_dir_or_file(const std::filesystem::path& path, std::string name);
// Widgets
Console my_console {
{ 1*8, 1*8, 224, 296 }, // Coordinates are: int:x (px), int:y (px), int:width (px), int:height (px)
}; };
} };
}
```
### ui_newapp.cpp ### ui_newapp.cpp
```
#include "ui_newapp.hpp"
#include "portapack.hpp"
#include <cstring>
#include "ui_newapp.hpp" using namespace portapack;
#include "portapack.hpp"
#include <cstring>
using namespace portapack; namespace ui
{
void NewAppView::focus() { // Default selection to my_console when app starts
my_console.focus();
}
// Checks SD Card, returns true if Mounted, false if otherwise
bool NewAppView::check_sd_card() {
//return (sd_card::status() == sd_card::Status::Mounted) ? true : false;
return true;
}
// Lists all files and directorys in path
std::vector<file_entry> NewAppView::list_dir(const std::filesystem::path& path) {
// Files and directories list
std::vector<file_entry> entry_list { };
// For each entry in the file system's directory
// Adds files in directorys into entry_list{}
// Directorys are inserted infront of files
for (const auto& entry : std::filesystem::directory_iterator(path, u"*")) {
// Dose not add directorys or files starting with '.' (hidden / tmp)
if (entry.path().string().length() && entry.path().filename().string()[0] != '.') {
// If file
if (std::filesystem::is_regular_file(entry.status())) {
entry_list.push_back({ entry.path(), (uint32_t)entry.size(), false });
// Else If directory
} else if (std::filesystem::is_directory(entry.status())) {
entry_list.insert(entry_list.begin(), { entry.path(), 0, true });
// Other
} else {
continue;
}
}
}
return entry_list;
}
// Creates dir, returns true if sucessfull
bool NewAppView::create_dir(const std::filesystem::path& path, std::string name) { // make_new_directory() returns 0 for sucess
return !(make_new_directory(path.string() + "/" + name)); // and other values means failure. Not operation
} // will return true only when 0 is returned.
bool NewAppView::delete_dir_or_file(const std::filesystem::path& path, std::string name) { // Deletes file or dir.
return !(delete_file(path.string() + "/" + name)); // 0 is sucess.
}
bool NewAppView::create_file(const std::filesystem::path& path, std::string name) {
File file = { }; // Create File object
Optional<File::Error> sucess = file.create(path.string() + "/" + name); // Create File
return !(sucess.is_valid()); // 0 is sucess
}
bool NewAppView::rename_dir_or_file(const std::filesystem::path& path, std::string old_name, std::string new_name) {
return !(rename_file(path.string() + "/" + old_name, new_name)); // 0 is sucess
}
std::string NewAppView::read_file(const std::filesystem::path& path, std::string name) { // Read file
std::string return_string = ""; // String to be returned
File file; // Create File object
auto sucess = file.open(path.string() + "/" + name); // Open file to write
if(!sucess.is_valid()) { // 0 is sucess
char one_char[1]; // Read file char by char
for(size_t pointer = 0; pointer < file.size() ; pointer++) { // Example won't work for large files
file.seek(pointer); // Sets file to next pointer
file.read(one_char, 1); // sets char to one_char[]
return_string += one_char[0]; // Add it to the return_string
}
} else {
return "0"; // Basic error handling
}
return return_string;
}
bool NewAppView::write_file(const std::filesystem::path& path, std::string name, std::string data) {
File file; // Create File object
auto sucess = file.append(path.string() + "/" + name); // Open file
if(!sucess.is_valid()) { // 0 is sucess
file.write_line(data);
return true;
} else {
return false;
}
}
namespace ui
{
NewAppView::NewAppView(NavigationView &nav) // Application Main NewAppView::NewAppView(NavigationView &nav) // Application Main
{ {
// App code add_children({
&my_console, // Add pointers for widgets
});
// Enable scrolling
my_console.enable_scrolling(true);
// Check SD Card
if(check_sd_card()) { // Check to see if SD Card is mounted
my_console.writeln("+ SD Card is Mounted");
} else { // Else, check_sd_card() returned false
my_console.writeln("- SD Card is NOT Mounted");
} }
void NewAppView::update() // Every time you get a DisplayFrameSync message this function will be ran // New directory
{ if(check_sd_card()) { // Check to see if SD Card is mounted
// Message code if(create_dir(u"", "NEW_DIR")) { // New dir in root of SD Card, returns true if sucessfull
my_console.writeln("+ New directory created"); // If new dir succeeded
} else {
my_console.writeln("- New directory FAILED"); // Else new dir failed
} }
} else { // Else, check_sd_card() returned false
my_console.writeln("- New directory FAILED");
} }
// List Directory
std::string dir_contents = ""; // String var that displays the dir contents
std::vector<file_entry> files = { }; // file_entry Vector
if(check_sd_card()) { // Check to see if SD Card is mounted
files = list_dir(u""); // dir of SD Card, u"" is root, u"DIRECTORY_NAME" for other directorys
// Vector has a capacity of 64 objects
if(files.size()) { // If files are not empty
dir_contents += "+ dir SD Card: ";
for (const auto& f : files) { // For each f of files
dir_contents += f.entry_path.string() + ", "; // Copy name to dir_contents
}
} else { // Else, files are empty
my_console.writeln("- dir SD Card FAILED");
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- dir SD Card FAILED");
}
//my_console.writeln(dir_contents); // Write results to my_console
// Write total count to my_console
my_console.writeln("+ dir SD Card: " + std::to_string(files.size()) + " items");
// Rename directory
if(check_sd_card()) { // Check to see if SD Card is mounted
if(rename_dir_or_file(u"", "NEW_DIR", "NEWER_DIR")) { // Renames dir in root of SD Card, returns true if sucessfull
my_console.writeln("+ Directory renamed"); // If dir renamed succeeded
} else {
my_console.writeln("- Directory renamed FAILED"); // Else new dir renamed failed
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- Directory renamed FAILED");
}
// Delete file or directory
if(check_sd_card()) { // Check to see if SD Card is mounted
if(delete_dir_or_file(u"", "NEWER_DIR")) { // New dir in root of SD Card
my_console.writeln("+ New directory deleted");
} else {
my_console.writeln("- New directory deleted FAILED");
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- New directory deleted FAILED");
}
// New file
if(check_sd_card()) { // Check to see if SD Card is mounted
if(create_file(u"", "NEW_FILE.txt")) { // New dir in root of SD Card, returns true if sucessfull
my_console.writeln("+ New file created"); // If new file succeeded
} else {
my_console.writeln("- New file FAILED"); // Else new file failed
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- New file FAILED");
}
// Rename file
if(check_sd_card()) { // Check to see if SD Card is mounted
if(rename_dir_or_file(u"", "NEW_FILE.txt", "NEWER_FILE.TXT")) { // Renames file, returns true if sucessfull
my_console.writeln("+ File renamed"); // If file renamed succeeded
} else {
my_console.writeln("- File renamed FAILED"); // Else new file renamed failed
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- File renamed FAILED");
}
// Write file
if(check_sd_card()) { // Check to see if SD Card is mounted
std::string data = "Your mother was a hamster!";
if(write_file(u"", "NEWER_FILE.TXT", data)) { // Sucess is anything but 0
my_console.writeln("+ Write File"); // Write data to my_console
} else {
my_console.writeln("- Write file FAILED");
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- Write file FAILED");
}
// Read file
if(check_sd_card()) { // Check to see if SD Card is mounted
std::string data = ""; // Create output string
data = read_file(u"", "NEWER_FILE.TXT"); // read_file()
if(data != "0") { // Sucess is anything but 0
my_console.writeln("+ Read file: " + data); // Write data to my_console
} else {
my_console.writeln("- Read file FAILED");
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- Read file FAILED");
}
// Delete file or directory
if(check_sd_card()) { // Check to see if SD Card is mounted
if(delete_dir_or_file(u"", "NEWER_FILE.TXT")) { // New dir in root of SD Card
my_console.writeln("+ New file deleted");
} else {
my_console.writeln("- New file deleted FAILED");
}
} else { // Else, check_sd_card() returned false
my_console.writeln("- New file deleted FAILED");
}
// Done
my_console.writeln("+ Demo Complete");
}
}
```