[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 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 StatInfo stat(InodeId_t id) = 0;
virtual InodeId_t spaceNeeded(FsSize_t size) = 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> left = 0;
ox::LittleEndian<size_t> right = 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() { ptrarith::Ptr<uint8_t, size_t> data() {
return ptrarith::Ptr<uint8_t, size_t>(this, this->size(), sizeof(*this), this->size() - sizeof(*this)); 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 { class FileStoreTemplate: public FileStore {
private: private:
using Item = FileStoreItem<size_t>;
using ItemPtr = typename ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>::ItemPtr; using ItemPtr = typename ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>::ItemPtr;
using Buffer = ptrarith::NodeBuffer<size_t, FileStoreItem<size_t>>; 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); 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 * Reads the "file" at the given id. You are responsible for freeing
* the data when done with it. * the data when done with it.
@ -304,6 +311,11 @@ int FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart,
return 1; 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> template<typename size_t>
typename FileStoreTemplate<size_t>::StatInfo FileStoreTemplate<size_t>::stat(InodeId_t id) { typename FileStoreTemplate<size_t>::StatInfo FileStoreTemplate<size_t>::stat(InodeId_t id) {
auto inode = find(id); auto inode = find(id);

View File

@ -89,6 +89,13 @@ int PathIterator::next(char *pathOut, std::size_t pathOutSize) {
return retval; 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 { ValErr<std::size_t> PathIterator::nextSize() const {
std::size_t size = 0; std::size_t size = 0;
Error retval = 1; Error retval = 1;

View File

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

View File

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

View File

@ -386,13 +386,16 @@ map<string, int(*)(string)> tests = {
{ {
"Directory", "Directory",
[](string) { [](string) {
std::array<uint8_t, 1000> buff; //std::array<uint8_t, 5000> fsBuff;
ox::fs::Directory32 dir(buff.data(), buff.size()); //std::array<uint8_t, 1000> dirBuff;
dir.init(); //ox::fs::FileStore32 fileStore(fsBuff.data(), fsBuff.size());
dir.write("/file1", 1); //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"); //oxAssert(dir.find("/file1") == 1, "Could not find /file1");
dir.write("/file3", 3); //dir.write("/file3", 3);
dir.write("/file2", 2); //dir.write("/file2", 2);
return 0; 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); auto out = ItemPtr(this, m_header.size, addr, fullSize);
if (out.valid()) { if (out.valid()) {
new (out) Item(size); new (out) Item;
out->setSize(size);
auto first = firstItem(); auto first = firstItem();
out->next = first.offset(); out->next = first.offset();
@ -329,12 +330,12 @@ struct __attribute__((packed)) Item {
ox::LittleEndian<size_t> m_size = sizeof(Item); ox::LittleEndian<size_t> m_size = sizeof(Item);
public: public:
explicit Item(size_t size) { size_t size() const {
this->m_size = size; return m_size;
} }
virtual size_t size() const { void setSize(size_t size) {
return m_size; m_size = size;
} }
}; };

View File

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

View File

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