Add support for removing directory entries

This commit is contained in:
2017-04-26 04:01:19 -05:00
parent a7a9256503
commit 544eb94f34
4 changed files with 106 additions and 8 deletions
+1
View File
@@ -5,6 +5,7 @@
* 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/.
*/
#pragma once
#include <ox/std/std.hpp>
+72 -8
View File
@@ -95,15 +95,15 @@ class FileSystemTemplate: public FileSystem {
data[nameLen] = 0;
}
static uint64_t spaceNeeded(const char *fileName) {
return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1;
}
/**
* The size in bytes.
*/
uint64_t size() {
return sizeof(DirectoryEntry) + ox_strlen(getName());
}
static uint64_t spaceNeeded(const char *fileName) {
return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1;
return spaceNeeded(getName());
}
};
@@ -118,6 +118,8 @@ class FileSystemTemplate: public FileSystem {
}
uint64_t getFileInode(const char *name, uint64_t buffSize);
int rmFile(const char *name);
};
FileStore *m_store = nullptr;
@@ -162,6 +164,11 @@ class FileSystemTemplate: public FileSystem {
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);
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) {
auto s = stat(dirPath);
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];
int err = read(s.inode, dirBuff, dirBuffSize);
if (!err) {
auto dir = (Directory*) dirBuff;
dir->size++;
dir->size += spaceNeeded;
auto entry = (DirectoryEntry*) &dirBuff[s.size];
entry->inode = inode;
entry->setName(fileName);
@@ -477,6 +485,40 @@ int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dir
#pragma warning(default:4244)
#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
@@ -485,7 +527,8 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::Directory::getFileInode(const c
uint64_t inode = 0;
auto current = files();
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) {
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
} else {
@@ -500,6 +543,27 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::Directory::getFileInode(const c
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<FileStore32, OxFS_32> FileSystem32;
typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64;
+1
View File
@@ -39,3 +39,4 @@ add_test("Test\\ PathIterator::fileName" FSTests PathIterator::fileName)
add_test("Test\\ FileSystem32::findInodeOf\\ /" FSTests "FileSystem32::findInodeOf /")
add_test("Test\\ FileSystem32::write\\(string\\)" FSTests "FileSystem32::write(string)")
add_test("Test\\ FileSystem32::rmDirectoryEntry\\(string\\)" FSTests "FileSystem32::rmDirectoryEntry(string)")
+32
View File
@@ -155,6 +155,38 @@ map<string, int(*)(string)> tests = {
delete []buff;
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;
}
},