Breakup file system code into smaller files

This commit is contained in:
Gary Talent 2018-02-02 01:15:15 -06:00
parent 9ce4835000
commit 637c9f24c2
13 changed files with 360 additions and 304 deletions

View File

@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.8)
add_library(
OxFS
filesystem.cpp
pathiterator.cpp
filesystem/filesystem.cpp
filesystem/pathiterator.cpp
)
set_property(
@ -31,12 +31,18 @@ endif()
install(
FILES
filestore.hpp
filesystem.hpp
pathiterator.hpp
DESTINATION
include/ox/fs
)
install(
FILES
filesystem/filesystem.hpp
filesystem/pathiterator.hpp
DESTINATION
include/ox/fs/filesystem
)
install(
TARGETS
OxFS

View File

@ -0,0 +1,208 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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>
#include "types.hpp"
namespace ox {
template<typename String>
struct DirectoryListing {
String name;
FileStat stat;
DirectoryListing() = default;
DirectoryListing(const char *name) {
this->name = name;
}
};
template<typename String>
bool operator<(const DirectoryListing<String> &a, const DirectoryListing<String> &b) {
return a.name < b.name;
}
template<typename InodeId_t>
struct __attribute__((packed)) DirectoryEntry {
public:
InodeId_t inode = 0;
private:
uint32_t m_nameLen = 0;
public:
void *end() {
return ((uint8_t*) this) + size();
}
char *getName() {
return (char*) (this + 1);
}
void setName(const char *name) {
auto data = getName();
m_nameLen = ox_strlen(name);
ox_memcpy(data, name, m_nameLen);
data[m_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) + m_nameLen + 1;
}
};
template<typename InodeId_t, typename FsSize_t>
struct __attribute__((packed)) Directory {
/**
* Number of bytes after this Directory struct.
*/
FsSize_t size = 0;
FsSize_t children = 0;
DirectoryEntry<InodeId_t> *files() {
return size ? (DirectoryEntry<InodeId_t>*) (this + 1) : nullptr;
}
void *end();
uint64_t getFileInode(const char *name);
int getChildrenInodes(InodeId_t *inodes, size_t inodesLen);
int rmFile(const char *name);
int copy(Directory<uint64_t, uint64_t> *dirOut);
template<typename List>
int ls(List *list);
};
template<typename InodeId_t, typename FsSize_t>
void *Directory<InodeId_t, FsSize_t>::end() {
return ((int8_t*) this) + size;
}
template<typename InodeId_t, typename FsSize_t>
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name) {
uint64_t inode = 0;
auto current = files();
if (current) {
for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
i += current->size();
if (i < this->size) {
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
} else {
current = nullptr;
break;
}
}
if (current) {
inode = current->inode;
}
}
return inode;
}
template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t inodesLen) {
if (inodesLen >= this->children) {
auto current = files();
if (current) {
for (uint64_t i = 0; i < this->children; i++) {
if (ox_strcmp(current->getName(), ".") and ox_strcmp(current->getName(), "..")) {
inodes[i] = current->inode;
}
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
}
return 0;
} else {
return 1;
}
} else {
return 2;
}
}
template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::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 -= current->size();
this->children--;
err = 0;
break;
}
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
}
}
return err;
}
template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::copy(Directory<uint64_t, uint64_t> *dirOut) {
auto current = files();
auto dirOutBuff = (uint8_t*) dirOut;
dirOutBuff += sizeof(Directory<uint64_t, uint64_t>);
dirOut->size = this->size;
dirOut->children = this->children;
if (current) {
for (uint64_t i = 0; i < this->children; i++) {
auto entry = (DirectoryEntry<uint64_t>*) dirOutBuff;
if (this->end() < current->end()) {
return 1;
}
entry->inode = current->inode;
entry->setName(current->getName());
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
dirOutBuff += entry->size();
}
} else {
return 2;
}
return 0;
}
template<typename InodeId_t, typename FsSize_t>
template<typename List>
int Directory<InodeId_t, FsSize_t>::ls(List *list) {
auto current = files();
if (current) {
for (uint64_t i = 0; i < this->children; i++) {
list->push_back(current->getName());
(*list)[i].stat.inode = current->inode;
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
}
return 0;
} else {
return 1;
}
}
}

View File

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "filesystem.hpp"
#include "filesystemtemplate.hpp"
namespace ox {

View File

@ -0,0 +1,101 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/fs/filestore.hpp>
#include "directory.hpp"
#include "pathiterator.hpp"
namespace ox {
class FileSystem {
public:
virtual ~FileSystem() {};
virtual int stripDirectories() = 0;
virtual int mkdir(const char *path, bool recursive = false) = 0;
/**
* Moves an entry from one directory to another.
* @param src the path to the file
* @param dest the path of the destination directory
*/
virtual int move(const char *src, const char *dest) = 0;
template<typename List>
int ls(const char *path, List *list);
virtual int read(const char *path, void *buffer, size_t buffSize) = 0;
virtual int read(uint64_t inode, void *buffer, size_t size) = 0;
virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0;
virtual uint8_t *read(uint64_t inode, size_t *size) = 0;
virtual int remove(uint64_t inode, bool recursive = false) = 0;
virtual int remove(const char *path, bool recursive = false) = 0;
virtual void resize(uint64_t size = 0) = 0;
virtual int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) = 0;
virtual int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) = 0;
virtual FileStat stat(uint64_t inode) = 0;
virtual FileStat stat(const char *path) = 0;
virtual uint64_t spaceNeeded(uint64_t size) = 0;
virtual uint64_t available() = 0;
virtual uint64_t size() = 0;
virtual uint8_t *buff() = 0;
virtual void walk(int(*cb)(const char*, uint64_t, uint64_t)) = 0;
protected:
virtual int readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) = 0;
};
template<typename List>
int FileSystem::ls(const char *path, List *list) {
typedef Directory<uint64_t, uint64_t> Dir;
int err = 0;
auto s = stat(path);
if (s.fileType == FileType_Directory) {
uint8_t dirBuff[max(static_cast<size_t>(s.size), sizeof(Dir)) * 4];
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
err |= readDirectory(path, dir);
if (!err) {
err |= dir->ls(list);
}
}
return err;
}
FileSystem *createFileSystem(uint8_t *buff, size_t buffSize, bool ownsBuff = false);
/**
* Creates a larger version of the given FileSystem.
*/
FileSystem *expandCopy(FileSystem *src);
/**
* Calls expandCopy and deletes the original FileSystem and buff a resize was
* performed.
*/
FileSystem *expandCopyCleanup(FileSystem *fs, size_t size);
}

View File

@ -8,303 +8,10 @@
#pragma once
#include <ox/std/std.hpp>
#include "pathiterator.hpp"
#include "filestore.hpp"
#include "filesystem.hpp"
namespace ox {
enum FsType {
OxFS_16 = 1,
OxFS_32 = 2,
OxFS_64 = 3
};
enum FileType {
FileType_NormalFile = 1,
FileType_Directory = 2
};
struct FileStat {
uint64_t inode = 0;
uint64_t links = 0;
uint64_t size = 0;
uint8_t fileType = 0;
};
template<typename String>
struct DirectoryListing {
String name;
FileStat stat;
DirectoryListing() = default;
DirectoryListing(const char *name) {
this->name = name;
}
};
template<typename String>
bool operator<(const DirectoryListing<String> &a, const DirectoryListing<String> &b) {
return a.name < b.name;
}
template<typename InodeId_t>
struct __attribute__((packed)) DirectoryEntry {
public:
InodeId_t inode = 0;
private:
uint32_t m_nameLen = 0;
public:
void *end() {
return ((uint8_t*) this) + size();
}
char *getName() {
return (char*) (this + 1);
}
void setName(const char *name) {
auto data = getName();
m_nameLen = ox_strlen(name);
ox_memcpy(data, name, m_nameLen);
data[m_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) + m_nameLen + 1;
}
};
template<typename InodeId_t, typename FsSize_t>
struct __attribute__((packed)) Directory {
/**
* Number of bytes after this Directory struct.
*/
FsSize_t size = 0;
FsSize_t children = 0;
DirectoryEntry<InodeId_t> *files() {
return size ? (DirectoryEntry<InodeId_t>*) (this + 1) : nullptr;
}
void *end();
uint64_t getFileInode(const char *name);
int getChildrenInodes(InodeId_t *inodes, size_t inodesLen);
int rmFile(const char *name);
int copy(Directory<uint64_t, uint64_t> *dirOut);
template<typename List>
int ls(List *list);
};
template<typename InodeId_t, typename FsSize_t>
void *Directory<InodeId_t, FsSize_t>::end() {
return ((int8_t*) this) + size;
}
template<typename InodeId_t, typename FsSize_t>
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name) {
uint64_t inode = 0;
auto current = files();
if (current) {
for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
i += current->size();
if (i < this->size) {
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
} else {
current = nullptr;
break;
}
}
if (current) {
inode = current->inode;
}
}
return inode;
}
template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t inodesLen) {
if (inodesLen >= this->children) {
auto current = files();
if (current) {
for (uint64_t i = 0; i < this->children; i++) {
if (ox_strcmp(current->getName(), ".") and ox_strcmp(current->getName(), "..")) {
inodes[i] = current->inode;
}
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
}
return 0;
} else {
return 1;
}
} else {
return 2;
}
}
template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::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 -= current->size();
this->children--;
err = 0;
break;
}
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
}
}
return err;
}
template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::copy(Directory<uint64_t, uint64_t> *dirOut) {
auto current = files();
auto dirOutBuff = (uint8_t*) dirOut;
dirOutBuff += sizeof(Directory<uint64_t, uint64_t>);
dirOut->size = this->size;
dirOut->children = this->children;
if (current) {
for (uint64_t i = 0; i < this->children; i++) {
auto entry = (DirectoryEntry<uint64_t>*) dirOutBuff;
if (this->end() < current->end()) {
return 1;
}
entry->inode = current->inode;
entry->setName(current->getName());
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
dirOutBuff += entry->size();
}
} else {
return 2;
}
return 0;
}
template<typename InodeId_t, typename FsSize_t>
template<typename List>
int Directory<InodeId_t, FsSize_t>::ls(List *list) {
auto current = files();
if (current) {
for (uint64_t i = 0; i < this->children; i++) {
list->push_back(current->getName());
(*list)[i].stat.inode = current->inode;
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
}
return 0;
} else {
return 1;
}
}
class FileSystem {
public:
virtual ~FileSystem() {};
virtual int stripDirectories() = 0;
virtual int mkdir(const char *path, bool recursive = false) = 0;
/**
* Moves an entry from one directory to another.
* @param src the path to the file
* @param dest the path of the destination directory
*/
virtual int move(const char *src, const char *dest) = 0;
template<typename List>
int ls(const char *path, List *list);
virtual int read(const char *path, void *buffer, size_t buffSize) = 0;
virtual int read(uint64_t inode, void *buffer, size_t size) = 0;
virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0;
virtual uint8_t *read(uint64_t inode, size_t *size) = 0;
virtual int remove(uint64_t inode, bool recursive = false) = 0;
virtual int remove(const char *path, bool recursive = false) = 0;
virtual void resize(uint64_t size = 0) = 0;
virtual int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) = 0;
virtual int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) = 0;
virtual FileStat stat(uint64_t inode) = 0;
virtual FileStat stat(const char *path) = 0;
virtual uint64_t spaceNeeded(uint64_t size) = 0;
virtual uint64_t available() = 0;
virtual uint64_t size() = 0;
virtual uint8_t *buff() = 0;
virtual void walk(int(*cb)(const char*, uint64_t, uint64_t)) = 0;
protected:
virtual int readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) = 0;
};
template<typename List>
int FileSystem::ls(const char *path, List *list) {
typedef Directory<uint64_t, uint64_t> Dir;
int err = 0;
auto s = stat(path);
if (s.fileType == FileType_Directory) {
uint8_t dirBuff[max(static_cast<size_t>(s.size), sizeof(Dir)) * 4];
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
err |= readDirectory(path, dir);
if (!err) {
err |= dir->ls(list);
}
}
return err;
}
FileSystem *createFileSystem(uint8_t *buff, size_t buffSize, bool ownsBuff = false);
/**
* Creates a larger version of the given FileSystem.
*/
FileSystem *expandCopy(FileSystem *src);
/**
* Calls expandCopy and deletes the original FileSystem and buff a resize was
* performed.
*/
FileSystem *expandCopyCleanup(FileSystem *fs, size_t size);
template<typename FileStore, FsType FS_TYPE>
class FileSystemTemplate: public FileSystem {

33
deps/ox/src/ox/fs/filesystem/types.hpp vendored Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright 2015 - 2018 gtalent2@gmail.com
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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>
namespace ox {
enum FsType {
OxFS_16 = 1,
OxFS_32 = 2,
OxFS_64 = 3
};
enum FileType {
FileType_NormalFile = 1,
FileType_Directory = 2
};
struct FileStat {
uint64_t inode = 0;
uint64_t links = 0;
uint64_t size = 0;
uint8_t fileType = 0;
};
}

View File

@ -8,4 +8,4 @@
#pragma once
#include "filesystem.hpp"
#include "filesystem/filesystemtemplate.hpp"

View File

@ -13,7 +13,7 @@
#include <stdlib.h>
#include <map>
#include <ox/std/strops.hpp>
#include <ox/fs/filesystem.hpp>
#include <ox/fs/fs.hpp>
#include "toollib.hpp"

View File

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <ox/fs/filesystem.hpp>
#include <ox/fs/fs.hpp>
using namespace ox;

View File

@ -11,8 +11,7 @@
#include <map>
#include <vector>
#include <string>
#include <ox/fs/filesystem.hpp>
#include <ox/fs/pathiterator.hpp>
#include <ox/fs/fs.hpp>
#include <ox/std/std.hpp>
using namespace std;

View File

@ -23,6 +23,8 @@ typedef long int64_t;
typedef unsigned long uint64_t;
#endif
typedef uint64_t uintmax_t;
namespace ox {
typedef uint32_t Error;