Skip to content

Commit 8efcdb3

Browse files
fixed mbed_die bug, added overwrite feature, added littleFS, refactoring testing
1 parent c5dd2b2 commit 8efcdb3

18 files changed

+435
-100
lines changed

.vscode/launch.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
8+
9+
]
10+
}

examples/advanced/advanced.ino

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
This example demonstrates the usage of the "Arduino_UnifiedStorage" library with USB storage and internal storage.
3+
The code includes the necessary library and defines instances of the "USBStorage" and "InternalStorage" classes.
4+
5+
In the setup function, the code initializes the serial communication and mounts the USB storage and internal storage.
6+
It also reformats the internal storage to ensure a clean file system.
7+
Then, it creates a root directory in the internal storage and creates a subdirectory and a file inside it
8+
9+
The code writes some data to the file and demonstrates file operations.
10+
It copies the file from internal storage to USB storage and moves the subdirectory from internal storage to USB storage.
11+
12+
After the file operations, the code prints the contents of both the USB storage and the internal storage.
13+
It recursively prints the directories (marked as "[D]") and files (marked as "[F]") using the "printFolderContents" function.
14+
*/
15+
16+
#include "Arduino_UnifiedStorage.h"
17+
18+
19+
USBStorage usbStorage = USBStorage();
20+
InternalStorage internalStorage = InternalStorage();
21+
22+
23+
void printFolderContents(Folder dir, int indentation = 0) {
24+
std::vector<Folder> directories = dir.getFolders();
25+
std::vector<UFile> files = dir.getFiles();
26+
27+
// Print directories
28+
for (Folder subdir : directories) {
29+
for (int i = 0; i < indentation; i++) {
30+
Serial.print(" ");
31+
}
32+
Serial.print("[D] ");
33+
Serial.println(subdir.getPath());
34+
printFolderContents(subdir, indentation + 1);
35+
}
36+
37+
// Print files
38+
for (UFile file : files) {
39+
for (int i = 0; i < indentation; i++) {
40+
Serial.print(" ");
41+
}
42+
Serial.print("[F] ");
43+
Serial.println(file.getPath());
44+
}
45+
}
46+
47+
48+
49+
void setup() {
50+
Serial.begin(115200);
51+
while (!Serial);
52+
53+
// Mount the USB storage
54+
if(usbStorage.begin()){
55+
Serial.println("USB storage mounted.");
56+
} else {
57+
Serial.println(errno);
58+
}
59+
60+
61+
// Mount the internal storage
62+
// Serial.println("Reformatting internal storage to make sure we have a clean FS");
63+
// internalStorage.format();
64+
if(internalStorage.begin()){
65+
Serial.println("Internal storage mounted.");
66+
} else {
67+
Serial.println(errno);
68+
}
69+
70+
71+
// Create a root directory in the internal storage
72+
Folder root = internalStorage.getRootFolder();
73+
74+
// Create a subdirectory and a file inside the root directory
75+
Folder subdir = root.createSubfolder("subdir");
76+
UFile file = root.createFile("file.txt", FileMode::WRITE);
77+
78+
// Write some data to the file
79+
file.write("Hello, world!");
80+
file.close();
81+
82+
// Copy the file from internal storage to USB storage
83+
bool success = file.copyTo(usbStorage.getRootFolder());
84+
if (success) {
85+
Serial.println("File copied successfully from internal storage to USB storage.");
86+
} else {
87+
Serial.println("Failed to copy file from internal storage to USB storage.");
88+
Serial.println(getErrno());
89+
}
90+
91+
// Move the subdirectory from internal storage to USB storage
92+
success = subdir.moveTo(usbStorage.getRootFolder());
93+
if (success) {
94+
Serial.println("Subdirectory moved successfully from internal storage to USB storage.");
95+
} else {
96+
Serial.println("Failed to move subdirectory from internal storage to USB storage.");
97+
Serial.println(getErrno());
98+
}
99+
100+
// Print the content of the USB storage
101+
Serial.println("USB storage contents:");
102+
printFolderContents(usbStorage.getRootFolder());
103+
104+
// Print the content of the internal storage
105+
Serial.println("Internal storage contents:");
106+
printFolderContents(internalStorage.getRootFolder());
107+
}
108+
109+
void loop() {
110+
// Nothing to do here
111+
}

src/Arduino_UnifiedStorage.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ class Arduino_UnifiedStorage {
3535

3636
virtual Folder getRootFolder() = 0;
3737

38-
virtual int format() = 0;
38+
virtual int formatLittleFS() = 0;
39+
40+
virtual int formatFAT() = 0;
3941
};
4042

4143

src/Folder.cpp

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Folder::Folder() {}
88

99
Folder::Folder(const char* path) {
10+
1011
DIR* dir = opendir(path);
1112
if (dir != nullptr) {
1213
this->path = std::string(path);
@@ -15,9 +16,7 @@ Folder::Folder(const char* path) {
1516
int result = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
1617
if (result == 0) {
1718
this->path = std::string(path);
18-
} else {
19-
this->path = "";
20-
}
19+
} // else ...not sure about this one yet
2120
}
2221
}
2322

@@ -104,34 +103,35 @@ String Folder::getPathString() {
104103
return String(this->getPath());
105104
}
106105

107-
Folder Folder::createSubfolder(const char* subfolderName) {
108-
bool alreadyExists = false;
106+
Folder Folder::createSubfolder(const char* subfolderName, bool overwrite) {
109107
std::string subfolderPath = this->path + "/" + subfolderName;
110108

111-
for(Folder d: this->getFolders()){
112-
if(d.getPath() == subfolderPath){
113-
alreadyExists = true;
109+
DIR* dir = opendir(subfolderPath.c_str());
110+
if (dir != nullptr) {
111+
if(!overwrite){
112+
errno = EEXIST;
113+
closedir(dir);
114+
return Folder(subfolderPath.c_str());
115+
116+
} else {
117+
closedir(dir);
118+
Folder(subfolderPath.c_str()).remove();
119+
}
120+
}
114121

115-
}
116-
}
117122

118-
// Construct the full path of the subfolder
119-
120-
if (!alreadyExists){
121123
int result = mkdir(subfolderPath.c_str(), 0777);
122-
if (result == 0) {
123-
return Folder(subfolderPath.c_str());
124-
} else {
125-
return Folder();
126-
}
127-
} else {
124+
if (result == 0) {
128125
return Folder(subfolderPath.c_str());
126+
} else {
127+
return Folder();
129128
}
129+
130130

131131
}
132132

133-
Folder Folder::createSubfolder(String subfolderName) {
134-
return this->createSubfolder(subfolderName.c_str());
133+
Folder Folder::createSubfolder(String subfolderName, bool overwrite) {
134+
return this->createSubfolder(subfolderName.c_str(), overwrite);
135135
}
136136

137137
std::vector<UFile> Folder::getFiles() {
@@ -173,11 +173,13 @@ std::vector<Folder> Folder::getFolders() {
173173
}
174174
}
175175

176-
bool Folder::copyTo(Folder destination) {
177-
return this->copyTo(destination.getPath());
176+
bool Folder::copyTo(Folder destination, bool overwrite) {
177+
return this->copyTo(destination.getPath(), overwrite);
178178
}
179179

180-
bool Folder::copyTo(const char* destinationPath) {
180+
181+
182+
bool Folder::copyTo(const char* destinationPath, bool overwrite) {
181183
std::string source = this->path;
182184
std::string fileName = getLastPathComponent(this->path.c_str());
183185
std::string destination = std::string(destinationPath) + "/" + fileName;
@@ -187,12 +189,21 @@ bool Folder::copyTo(const char* destinationPath) {
187189
return false;
188190
}
189191

190-
// Create destination directory if it doesn't exist
191-
if (mkdir(destination.c_str(), 0777) != 0 && errno != EEXIST) {
192+
193+
if(opendir(destination.c_str())){
194+
if(overwrite){
195+
Folder(destination.c_str()).remove();
196+
} else {
197+
return false;
198+
}
199+
200+
} else if (mkdir(destination.c_str(), 0777) != 0 && errno != EEXIST) {
192201
closedir(dir);
193-
return false;
194202
}
195203

204+
// Create destination directory if it doesn't exist
205+
206+
196207
struct dirent* entry;
197208
while ((entry = readdir(dir)) != nullptr) {
198209
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
@@ -240,29 +251,43 @@ bool Folder::copyTo(const char* destinationPath) {
240251
return true;
241252
}
242253

243-
bool Folder::copyTo(String destination) {
244-
return this->copyTo(destination.c_str());
254+
255+
bool Folder::copyTo(String destination, bool overwrite) {
256+
return this->copyTo(destination.c_str(), overwrite);
245257
}
246258

247-
bool Folder::moveTo(Folder destination) {
248-
return this->moveTo(destination.getPath());
259+
bool Folder::moveTo(Folder destination, bool overwrite) {
260+
return this->moveTo(destination.getPath(), overwrite);
249261
}
250262

251-
bool Folder::moveTo(const char* destination) {
263+
bool Folder::moveTo(const char* destination, bool overwrite) {
252264
std::string newPath = replaceFirstPathComponent(this->path.c_str(), destination);
253265

254-
if (!this->copyTo(destination)) {
255-
return false; // Return false if the copy operation fails
266+
/*
267+
DIR* dir = opendir(newPath.c_str());
268+
if (dir != nullptr) {
269+
if(!overwrite){
270+
errno = EEXIST;
271+
return false;
272+
} else {
273+
closedir(dir);
274+
Folder(newPath.c_str()).remove();
275+
}
256276
}
277+
*/
257278

258-
if (::remove(this->path.c_str()) != 0) {
259-
return false;
279+
if (!this->copyTo(destination, overwrite)) {
280+
return false; // Return false if the copy operation fails
281+
} else {
282+
if (::remove(this->path.c_str()) != 0) {
283+
return false;
284+
}
260285
}
261286

262287
this->path = newPath;
263288
return true;
264289
}
265290

266-
bool Folder::moveTo(String destination) {
267-
return this->moveTo(destination.c_str());
291+
bool Folder::moveTo(String destination, bool overwrite) {
292+
return this->moveTo(destination.c_str(), overwrite);
268293
}

src/Folder.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,18 @@ class Folder {
8787
/*
8888
* @brief Creates a subfolder in the directory.
8989
* @param const char * subfolderName - he name of the subfolder to create.
90+
* @param overwrite - behaviour in case the folder already exists, default is false
9091
* @return The created subfolder.
9192
*/
92-
Folder createSubfolder(const char * subfolderName);
93+
Folder createSubfolder(const char * subfolderName, bool overwrite = false);
9394

9495
/*
9596
* @brief Creates a subfolder in the directory.
9697
* @param String subfolderName - he name of the subfolder to create.
98+
* @param overwrite - behaviour in case the folder already exists, default is false
9799
* @return The created subfolder.
98100
*/
99-
Folder createSubfolder(String subfolderName);
101+
Folder createSubfolder(String subfolderName, bool overwrite = false);
100102

101103
/*
102104
* @brief Returns File objects for all files in the current dirctory.
@@ -115,42 +117,47 @@ class Folder {
115117
* @param Folder destination - a Folder object representing the destination
116118
* @return True upon success, false otherwise.
117119
*/
118-
bool copyTo(Folder destination);
120+
bool copyTo(Folder destination, bool overwrite = false);
119121

120122
/*
121123
* @brief Copies the current directory
122124
* @param const char * destination - the path of the destination location
125+
* @param overwrite - behaviour in case the folder already exists, default is false
123126
* @return True upon success, false otherwise.
124127
*/
125-
bool copyTo(const char * destination);
128+
bool copyTo(const char * destination, bool overwrite = false);
126129

127130
/*
128131
* @brief Copies the current directory
129132
* @param String destination - the path of the destination location
133+
* @param overwrite - behaviour in case the folder already exists, default is false
130134
* @return True upon success, false otherwise.
131135
*/
132-
bool copyTo(String destination);
136+
bool copyTo(String destination, bool overwrite = false);
133137

134138
/*
135139
* @brief Moves the current directory
136140
* @param Folder destination - a Folder object representing the destination
141+
* @param overwrite - behaviour in case the folder already exists, default is false
137142
* @return True upon success, false otherwise.
138143
*/
139-
bool moveTo(Folder destination);
144+
bool moveTo(Folder destination, bool overwrite = false);
140145

141146
/*
142147
* @brief Moves the current directory
143148
* @param const char * destination - the path of the destination location
149+
* @param overwrite - behaviour in case the folder already exists, default is false
144150
* @return True upon success, false otherwise.
145151
*/
146-
bool moveTo(const char * destination);
152+
bool moveTo(const char * destination, bool overwrite = false);
147153

148154
/*
149155
* @brief Move the current directory
150156
* @param String destination - the path of the destination location
157+
* @param overwrite - behaviour in case the folder already exists, default is false
151158
* @return True upon success, false otherwise.
152159
*/
153-
bool moveTo(String destination);
160+
bool moveTo(String destination, bool overwrite = false);
154161

155162
private:
156163

0 commit comments

Comments
 (0)