Add support for removing directory entries
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ox/std/std.hpp>
|
#include <ox/std/std.hpp>
|
||||||
|
|||||||
@@ -95,15 +95,15 @@ class FileSystemTemplate: public FileSystem {
|
|||||||
data[nameLen] = 0;
|
data[nameLen] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t spaceNeeded(const char *fileName) {
|
||||||
|
return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The size in bytes.
|
* The size in bytes.
|
||||||
*/
|
*/
|
||||||
uint64_t size() {
|
uint64_t size() {
|
||||||
return sizeof(DirectoryEntry) + ox_strlen(getName());
|
return spaceNeeded(getName());
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t spaceNeeded(const char *fileName) {
|
|
||||||
return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -118,6 +118,8 @@ class FileSystemTemplate: public FileSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getFileInode(const char *name, uint64_t buffSize);
|
uint64_t getFileInode(const char *name, uint64_t buffSize);
|
||||||
|
|
||||||
|
int rmFile(const char *name);
|
||||||
};
|
};
|
||||||
|
|
||||||
FileStore *m_store = nullptr;
|
FileStore *m_store = nullptr;
|
||||||
@@ -162,6 +164,11 @@ class FileSystemTemplate: public FileSystem {
|
|||||||
|
|
||||||
uint8_t *buff() override;
|
uint8_t *buff() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an entry from a directory. This does not delete the referred to file.
|
||||||
|
*/
|
||||||
|
int rmDirectoryEntry(const char *dirPath);
|
||||||
|
|
||||||
static uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories);
|
static uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -455,13 +462,14 @@ template<typename FileStore, FsType FS_TYPE>
|
|||||||
int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode) {
|
int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode) {
|
||||||
auto s = stat(dirPath);
|
auto s = stat(dirPath);
|
||||||
if (s.inode) {
|
if (s.inode) {
|
||||||
size_t dirBuffSize = s.size + DirectoryEntry::spaceNeeded(fileName);
|
auto spaceNeeded = DirectoryEntry::spaceNeeded(fileName);
|
||||||
|
size_t dirBuffSize = s.size + spaceNeeded;
|
||||||
uint8_t dirBuff[dirBuffSize];
|
uint8_t dirBuff[dirBuffSize];
|
||||||
int err = read(s.inode, dirBuff, dirBuffSize);
|
int err = read(s.inode, dirBuff, dirBuffSize);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
auto dir = (Directory*) dirBuff;
|
auto dir = (Directory*) dirBuff;
|
||||||
dir->size++;
|
dir->size += spaceNeeded;
|
||||||
auto entry = (DirectoryEntry*) &dirBuff[s.size];
|
auto entry = (DirectoryEntry*) &dirBuff[s.size];
|
||||||
entry->inode = inode;
|
entry->inode = inode;
|
||||||
entry->setName(fileName);
|
entry->setName(fileName);
|
||||||
@@ -477,6 +485,40 @@ int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dir
|
|||||||
#pragma warning(default:4244)
|
#pragma warning(default:4244)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename FileStore, FsType FS_TYPE>
|
||||||
|
int FileSystemTemplate<FileStore, FS_TYPE>::rmDirectoryEntry(const char *path) {
|
||||||
|
int err = 0;
|
||||||
|
size_t pathLen = ox_strlen(path);
|
||||||
|
char dirPath[pathLen];
|
||||||
|
char fileName[pathLen];
|
||||||
|
PathIterator pathReader(path, pathLen);
|
||||||
|
err |= pathReader.fileName(fileName, pathLen);
|
||||||
|
err |= pathReader.dirPath(dirPath, pathLen);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dirStat = stat(dirPath);
|
||||||
|
auto dirBuffLen = dirStat.size;
|
||||||
|
uint8_t dirBuff[dirBuffLen];
|
||||||
|
|
||||||
|
err = read(dirStat.inode, dirBuff, dirBuffLen);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dir = (Directory*) dirBuff;
|
||||||
|
err = dir->rmFile(fileName);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = write(dirStat.inode, dirBuff, dirBuffLen - DirectoryEntry::spaceNeeded(fileName));
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Directory
|
// Directory
|
||||||
|
|
||||||
@@ -485,7 +527,8 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::Directory::getFileInode(const c
|
|||||||
uint64_t inode = 0;
|
uint64_t inode = 0;
|
||||||
auto current = files();
|
auto current = files();
|
||||||
if (current) {
|
if (current) {
|
||||||
for (uint64_t i = 1; ox_strcmp(current->getName(), name) != 0; i++) {
|
for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
|
||||||
|
i += current->size();
|
||||||
if (i < this->size) {
|
if (i < this->size) {
|
||||||
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
|
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
|
||||||
} else {
|
} else {
|
||||||
@@ -500,6 +543,27 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::Directory::getFileInode(const c
|
|||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename FileStore, FsType FS_TYPE>
|
||||||
|
int FileSystemTemplate<FileStore, FS_TYPE>::Directory::rmFile(const char *name) {
|
||||||
|
int err = 1;
|
||||||
|
auto current = files();
|
||||||
|
if (current) {
|
||||||
|
for (uint64_t i = 0; i < this->size;) {
|
||||||
|
i += current->size();
|
||||||
|
if (ox_strcmp(current->getName(), name) == 0) {
|
||||||
|
auto dest = (uint8_t*) current;
|
||||||
|
auto src = dest + current->size();
|
||||||
|
ox_memcpy(dest, src, this->size - i);
|
||||||
|
this->size -= i;
|
||||||
|
err = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
typedef FileSystemTemplate<FileStore16, OxFS_16> FileSystem16;
|
typedef FileSystemTemplate<FileStore16, OxFS_16> FileSystem16;
|
||||||
typedef FileSystemTemplate<FileStore32, OxFS_32> FileSystem32;
|
typedef FileSystemTemplate<FileStore32, OxFS_32> FileSystem32;
|
||||||
typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64;
|
typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64;
|
||||||
|
|||||||
@@ -39,3 +39,4 @@ add_test("Test\\ PathIterator::fileName" FSTests PathIterator::fileName)
|
|||||||
|
|
||||||
add_test("Test\\ FileSystem32::findInodeOf\\ /" FSTests "FileSystem32::findInodeOf /")
|
add_test("Test\\ FileSystem32::findInodeOf\\ /" FSTests "FileSystem32::findInodeOf /")
|
||||||
add_test("Test\\ FileSystem32::write\\(string\\)" FSTests "FileSystem32::write(string)")
|
add_test("Test\\ FileSystem32::write\\(string\\)" FSTests "FileSystem32::write(string)")
|
||||||
|
add_test("Test\\ FileSystem32::rmDirectoryEntry\\(string\\)" FSTests "FileSystem32::rmDirectoryEntry(string)")
|
||||||
|
|||||||
@@ -155,6 +155,38 @@ map<string, int(*)(string)> tests = {
|
|||||||
delete []buff;
|
delete []buff;
|
||||||
delete []dataOut;
|
delete []dataOut;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FileSystem32::rmDirectoryEntry(string)",
|
||||||
|
[](string) {
|
||||||
|
int retval = 0;
|
||||||
|
auto path = "/usr/share/test.txt";
|
||||||
|
auto dataIn = "test string";
|
||||||
|
auto dataOutLen = ox_strlen(dataIn) + 1;
|
||||||
|
auto dataOut = new char[dataOutLen];
|
||||||
|
|
||||||
|
const auto size = 1024 * 1024 * 10;
|
||||||
|
auto buff = new uint8_t[size];
|
||||||
|
FileSystem32::format(buff, (FileStore32::FsSize_t) size, true);
|
||||||
|
auto fs = (FileSystem32*) createFileSystem(buff, size);
|
||||||
|
|
||||||
|
retval |= fs->mkdir("/usr");
|
||||||
|
retval |= fs->mkdir("/usr/share");
|
||||||
|
|
||||||
|
retval |= fs->write(path, (void*) dataIn, ox_strlen(dataIn) + 1);
|
||||||
|
retval |= fs->read(path, dataOut, dataOutLen);
|
||||||
|
retval |= ox_strcmp(dataIn, dataOut) != 0;
|
||||||
|
|
||||||
|
retval |= fs->rmDirectoryEntry(path);
|
||||||
|
// the lookup should fail
|
||||||
|
retval |= fs->read(path, dataOut, dataOutLen) == 0;
|
||||||
|
|
||||||
|
delete fs;
|
||||||
|
delete []buff;
|
||||||
|
delete []dataOut;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user