forked from greiman/SdFat
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSD_CI.cpp
More file actions
193 lines (168 loc) · 4.63 KB
/
SD_CI.cpp
File metadata and controls
193 lines (168 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include "SD_CI.h"
#ifdef MOCK_PINS_COUNT
#include <cassert>
// expected by the SdFat library but not supplied by Arduino-CI
char *__brkval = nullptr;
char __bss_end = 0;
String SdFat_CI::_normalizeDirPath(String inPath) {
String outPath = _normalizeFilePath(inPath);
if (!outPath.endsWith("/")) {
outPath.concat('/');
}
return outPath;
}
String SdFat_CI::_normalizeFilePath(String inPath) {
String outPath;
if (inPath.length() == 0 || inPath == "/") {
return String("/");
}
if (inPath.at(0) == '/') {
outPath = inPath;
} else {
outPath = _cwd;
outPath.concat(inPath);
}
return outPath;
}
String SdFat_CI::_getCwd() { return _cwd; }
bool SdFat_CI::begin(uint8_t csPin) {
_didBegin = true;
return true;
}
bool SdFat_CI::chdir() {
assert(_didBegin);
_cwd = String("/");
return true;
}
bool SdFat_CI::chdir(const char *path) { return this->chdir(String(path)); }
bool SdFat_CI::chdir(const String &path) {
assert(_didBegin);
String newPath = this->_normalizeDirPath(path);
if (dirs.count(newPath)) {
_cwd = newPath;
return true;
}
return false;
}
bool SdFat_CI::exists(const char *path) { return this->exists(String(path)); }
bool SdFat_CI::exists(const String &path) {
assert(_didBegin);
if (dirs.count(this->_normalizeDirPath(path)) == 1) {
return true;
}
if (files.count(this->_normalizeFilePath(path)) == 1) {
return true;
}
return false;
}
bool SdFat_CI::format() {
assert(_didBegin);
dirs.clear();
dirs.emplace("/");
for (auto const &each : files) {
delete each.second;
}
files.clear();
return this->chdir();
}
bool SdFat_CI::ls(uint8_t flags) { return false; }
bool SdFat_CI::mkdir(const char *path, bool pFlag) {
return this->mkdir(String(path), pFlag);
}
bool SdFat_CI::mkdir(const String &path, bool pFlag) {
assert(_didBegin);
String newPath = this->_normalizeDirPath(path);
if (dirs.count(newPath)) {
return false;
}
int i = newPath.indexOf('/', 1);
while (i > 0 && i < newPath.length()) {
if (!dirs.count(newPath)) {
if (pFlag) {
dirs.emplace(newPath.substring(0, i + 1));
} else {
return false;
}
}
i = newPath.indexOf('/', i + 1);
}
dirs.emplace(newPath);
return true;
}
File_CI SdFat_CI::open(const char *path, oflag_t oflag) {
return open(String(path), oflag);
}
/*
#define O_RDONLY 0x00 ///< Open for reading only.
#define O_WRONLY 0x01 ///< Open for writing only.
#define O_RDWR 0x02 ///< Open for reading and writing.
#define O_AT_END 0x04 ///< Open at EOF.
#define O_APPEND 0x08 ///< Set append mode.
#define O_CREAT 0x10 ///< Create file if it does not exist.
#define O_TRUNC 0x20 ///< Truncate file to zero length.
#define O_EXCL 0x40 ///< Fail if the file exists.
*/
File_CI SdFat_CI::open(const String &path, oflag_t oflag) {
String fullPath = _normalizeFilePath(path);
file_ci *file = nullptr;
if (this->exists(fullPath)) {
if (oflag & O_EXCL) {
return File_CI(); // empty file reference to signal an error
}
file = files.at(fullPath);
} else { // file does not exist
if (oflag & O_CREAT) { // create file
file = new file_ci(path);
files.emplace(fullPath, file);
} else {
return File_CI(); // empty file reference to signal an error
}
}
// open existing file with proper mode
return File_CI(file, oflag);
}
bool SdFat_CI::remove(const char *path) { return this->remove(String(path)); }
bool SdFat_CI::remove(const String &path) {
if (this->exists(path)) {
String fullPath = _normalizeFilePath(path);
file_ci *file = files.at(fullPath);
files.erase(fullPath);
delete file;
return true;
}
return false;
}
bool SdFat_CI::rename(const char *oldPath, const char *newPath) {
return this->rename(String(oldPath), String(newPath));
}
bool SdFat_CI::rename(const String &oldPath, const String &newPath) {
String fullOldPath = _normalizeFilePath(oldPath);
String fullNewPath = _normalizeFilePath(newPath);
if (!this->exists(fullOldPath) || this->exists(fullNewPath)) {
return false;
}
file_ci *file = this->files.at(fullOldPath);
file->name = fullNewPath;
this->files.erase(fullOldPath);
this->files.emplace(fullNewPath, file);
return true;
}
bool SdFat_CI::rmdir(const char *path) { return this->rmdir(String(path)); }
bool SdFat_CI::rmdir(const String &path) {
assert(_didBegin);
String newPath = this->_normalizeDirPath(path);
if (!dirs.count(newPath)) {
return false;
}
for (auto dir : dirs) {
if (dir != newPath && dir.startsWith(newPath)) {
return false;
}
}
if (_cwd == newPath) {
this->chdir();
}
dirs.erase(newPath);
return true;
}
#endif