[ox/fs] Add new FileStore write

This commit is contained in:
Gary Talent 2018-04-26 21:11:48 -05:00
parent 59cc34b4e8
commit 24fbb8ba86
9 changed files with 81 additions and 35 deletions

View File

@ -39,6 +39,8 @@ class FileStore {
virtual Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size) = 0;
virtual ValErr<const uint8_t*> read(InodeId_t id) = 0;
virtual StatInfo stat(InodeId_t id) = 0;
virtual InodeId_t spaceNeeded(FsSize_t size) = 0;

View File

@ -22,7 +22,10 @@ struct __attribute__((packed)) FileStoreItem: public ptrarith::Item<size_t> {
ox::LittleEndian<size_t> left = 0;
ox::LittleEndian<size_t> right = 0;
explicit FileStoreItem(size_t size): ptrarith::Item<size_t>(size) {
FileStoreItem() = default;
explicit FileStoreItem(size_t size) {
this->setSize(size);
}
/**
@ -35,6 +38,7 @@ struct __attribute__((packed)) FileStoreItem: public ptrarith::Item<size_t> {
ptrarith::Ptr<uint8_t, size_t> data() {
return ptrarith::Ptr<uint8_t, size_t>(this, this->size(), sizeof(*this), this->size() - sizeof(*this));
}
};
@ -42,6 +46,7 @@ template<typename size_t>
class FileStoreTemplate: public FileStore {
private:
using Item = FileStoreItem<size_t>;
using ItemPtr = typename ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>::ItemPtr;
using Buffer = ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>;
@ -69,6 +74,8 @@ class FileStoreTemplate: public FileStore {
Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size);
ValErr<const uint8_t*> read(InodeId_t id);
/**
* Reads the "file" at the given id. You are responsible for freeing
* the data when done with it.
@ -304,6 +311,11 @@ int FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart,
return 1;
}
template<typename size_t>
ValErr<const uint8_t*> FileStoreTemplate<size_t>::read(InodeId_t id) {
return reinterpret_cast<uint8_t*>(find(id).get());
}
template<typename size_t>
typename FileStoreTemplate<size_t>::StatInfo FileStoreTemplate<size_t>::stat(InodeId_t id) {
auto inode = find(id);

View File

@ -89,6 +89,13 @@ int PathIterator::next(char *pathOut, std::size_t pathOutSize) {
return retval;
}
/**
* @return 0 if no error
*/
int PathIterator::next(BString<MaxFileNameLength> *fileName) {
return next(fileName->data(), fileName->cap());
}
ValErr<std::size_t> PathIterator::nextSize() const {
std::size_t size = 0;
Error retval = 1;

View File

@ -8,11 +8,12 @@
#pragma once
#include <ox/std/strops.hpp>
#include <ox/std/types.hpp>
#include <ox/std/std.hpp>
namespace ox {
constexpr auto MaxFileNameLength = 255;
class PathIterator {
private:
const char *m_path = nullptr;
@ -39,6 +40,11 @@ class PathIterator {
*/
int next(char *pathOut, std::size_t pathOutSize);
/**
* @return 0 if no error
*/
int next(BString<MaxFileNameLength> *fileName);
/**
* @return 0 if no error
*/

View File

@ -9,7 +9,7 @@
#pragma once
#include <ox/fs/filesystem/pathiterator.hpp>
#include <ox/fs/filestore.hpp>
#include <ox/fs/filestore/filestore.hpp>
#include <ox/ptrarith/nodebuffer.hpp>
#include <ox/std/std.hpp>
@ -19,12 +19,14 @@ template<typename InodeId_t>
struct __attribute__((packed)) DirectoryEntry {
// NodeBuffer fields
ox::LittleEndian<std::size_t> prev = 0;
ox::LittleEndian<std::size_t> next = 0;
LittleEndian<InodeId_t> prev = 0;
LittleEndian<InodeId_t> next = 0;
// DirectoryEntry fields
ox::LittleEndian<InodeId_t> inode = 0;
BString<255> name;
LittleEndian<InodeId_t> inode = 0;
BString<MaxFileNameLength> name;
DirectoryEntry() = default;
explicit DirectoryEntry(const char *name) {
this->name = name;
@ -41,6 +43,10 @@ struct __attribute__((packed)) DirectoryEntry {
return fullSize() - offsetof(DirectoryEntry, inode);
}
void setSize(InodeId_t) {
// ignore set value
}
ptrarith::Ptr<uint8_t, InodeId_t> data() {
return ptrarith::Ptr<uint8_t, InodeId_t>(this, this->size(), sizeof(*this), this->size() - sizeof(*this));
}
@ -55,9 +61,10 @@ class Directory {
using Buffer = ptrarith::NodeBuffer<InodeId_t, DirectoryEntry<InodeId_t>>;
std::size_t m_size = 0;
Buffer *m_buff = nullptr;
FileStore *m_fs = nullptr;
public:
Directory(uint8_t *buff, std::size_t size);
Directory(fs::FileStore *fs, InodeId_t inode);
/**
* Initializes Directory.
@ -73,9 +80,10 @@ class Directory {
};
template<typename InodeId_t>
Directory<InodeId_t>::Directory(uint8_t *buff, std::size_t size) {
m_size = size;
m_buff = reinterpret_cast<decltype(m_buff)>(buff);
Directory<InodeId_t>::Directory(fs::FileStore *fs, InodeId_t) {
m_fs = fs;
//m_size = size;
//m_buff = reinterpret_cast<decltype(m_buff)>(buff);
}
template<typename InodeId_t>
@ -88,16 +96,25 @@ Error Directory<InodeId_t>::init() noexcept {
}
template<typename InodeId_t>
Error Directory<InodeId_t>::write(PathIterator it, InodeId_t inode) noexcept {
if (it.hasNext()) {
return write(it + 1, inode);
} else {
auto current = find(it);
if (current.ok()) {
} else {
Error Directory<InodeId_t>::write(PathIterator path, InodeId_t inode) noexcept {
// find existing entry and update if exists
if (!path.hasNext()) {
BString<MaxFileNameLength> name;
path.next(&name);
auto val = m_buff->malloc(name.size());
if (val.valid()) {
new (val) DirectoryEntry<InodeId_t>(name.data());
val->name = name;
val->inode = inode;
return 0;
}
return 1;
}
return 1;
// TODO: get sub directory and call its write instead of recursing on this directory
return write(path + 1, inode);
}
template<typename InodeId_t>

View File

@ -386,13 +386,16 @@ map<string, int(*)(string)> tests = {
{
"Directory",
[](string) {
std::array<uint8_t, 1000> buff;
ox::fs::Directory32 dir(buff.data(), buff.size());
dir.init();
dir.write("/file1", 1);
//std::array<uint8_t, 5000> fsBuff;
//std::array<uint8_t, 1000> dirBuff;
//ox::fs::FileStore32 fileStore(fsBuff.data(), fsBuff.size());
//fileStore.format();
//ox::fs::Directory32 dir(&fileStore, dirBuff.data(), dirBuff.size());
//dir.init();
//dir.write("/file1", 1);
//oxAssert(dir.find("/file1") == 1, "Could not find /file1");
dir.write("/file3", 3);
dir.write("/file2", 2);
//dir.write("/file3", 3);
//dir.write("/file2", 2);
return 0;
}
},

View File

@ -211,7 +211,8 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size
}
auto out = ItemPtr(this, m_header.size, addr, fullSize);
if (out.valid()) {
new (out) Item(size);
new (out) Item;
out->setSize(size);
auto first = firstItem();
out->next = first.offset();
@ -329,12 +330,12 @@ struct __attribute__((packed)) Item {
ox::LittleEndian<size_t> m_size = sizeof(Item);
public:
explicit Item(size_t size) {
this->m_size = size;
size_t size() const {
return m_size;
}
virtual size_t size() const {
return m_size;
void setSize(size_t size) {
m_size = size;
}
};

View File

@ -18,7 +18,7 @@ namespace ox {
template<std::size_t buffLen>
class BString {
private:
uint8_t m_buff[buffLen];
uint8_t m_buff[buffLen + 1];
public:
BString() noexcept;

View File

@ -61,9 +61,7 @@ struct ValErr {
inline constexpr ValErr() = default;
inline constexpr ValErr(T value, Error error = 0) {
this->value = value;
this->error = error;
inline constexpr ValErr(T value, Error error = 0): value(value), error(error) {
}
inline constexpr operator const T&() const {