Renamed project Ox and restructured it to allow it to become a baremetal

unikernel/stdlib.
This commit is contained in:
2016-06-24 18:27:46 -05:00
parent f9f19819ef
commit 7a81449148
18 changed files with 80 additions and 69 deletions
+4
View File
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 2.8)
add_subdirectory(fs)
add_subdirectory(std)
+17
View File
@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 2.8)
add_library(
OxFS
filestore.cpp
filesystem.cpp
)
install(
FILES
filestore.hpp
filesystem.hpp
DESTINATION
include/ox/fs
)
add_subdirectory(test)
+8
View File
@@ -0,0 +1,8 @@
/*
* Copyright 2015 - 2016 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/.
*/
#include "filestore.hpp"
+384
View File
@@ -0,0 +1,384 @@
/*
* Copyright 2015 - 2016 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/_memops.hpp>
#include <ox/std/_types.hpp>
namespace ox {
namespace fs {
using namespace ox::std;
template<typename FsT>
class FileStore {
public:
typedef uint16_t InodeId_t;
typedef FsT FsSize_t;
struct FsHeader {
uint32_t version;
FsSize_t size;
FsSize_t rootInode;
};
struct StatInfo {
InodeId_t inodeId;
FsSize_t size;
};
private:
struct Inode {
// the next Inode in memory
FsSize_t prev, next;
FsSize_t left, right;
FsSize_t dataLen;
// The following variables should not be assumed to exist
FsSize_t m_id;
FsSize_t size();
void setId(InodeId_t);
void setData(void *data, int size);
private:
Inode() = default;
};
uint8_t *m_begin, *m_end;
uint32_t &m_version;
Inode *m_root;
public:
/**
* Constructor
* @param begin pointer to the beginning of this FileStore's memory chunk
* @param end pointer to the end of this FileStore's memory chunk
* @param error pointer to a integer return errors into
*/
FileStore(uint8_t *begin, uint8_t *end, Error *error = nullptr);
/**
* Initializes the memory chunk of this FileStore was given.
* This clears the previous contents.
*/
void init();
/**
* Writes the given data to a "file" with the given id.
* @param id the id of the file
* @param data the contents of the file
* @param dataLen the number of bytes data points to
*/
int write(void *data, FsSize_t dataLen);
/**
* Writes the given data to a "file" with the given id.
* @param id the id of the file
* @param data the contents of the file
* @param dataLen the number of bytes data points to
*/
int write(InodeId_t id, void *data, FsSize_t dataLen);
/**
* Reads the "file" at the given id. You are responsible for freeing
* the data when done with it.
* @param id id of the "file"
* @param data pointer to the pointer where the data is stored
* @param size pointer to a value that will be assigned the size of data
* @return 0 if read is a success
*/
int read(InodeId_t id, void *data, FsSize_t *size);
/**
* Reads the stat information of the inode of the given inode id.
* If the returned inode id is 0, then the requested inode was not found.
* @param id id of the inode to stat
* @return the stat information of the inode of the given inode id
*/
StatInfo stat(InodeId_t id);
static uint8_t version();
static uint8_t *format(uint8_t *buffer, FsSize_t size);
private:
/**
* Gets the header section of the file system.
* @return the header section of the file system.
*/
FsHeader *getHeader();
/**
* Gets the inode at the given id.
* @param root the root node to start comparing on
* @param id id of the "file"
* @param pathLen number of characters in pathLen
* @return the requested Inode, if available
*/
Inode *getInode(Inode *root, InodeId_t id);
/**
* Gets an address for a new Inode.
* @param size the size of the Inode
*/
void *alloc(FsSize_t size);
/**
* Compresses all of the inode into a contiguous space, starting at m_root.
*/
void compress();
/**
* Inserts the given insertValue into the tree of the given root.
* If the inode already exists, it replaces the old on deletes it.
* @return true if the inode was inserted
*/
bool insert(Inode *root, Inode *insertValue);
/**
* Gets the FsSize_t associated with the next Inode to be allocated.
* @retrun the FsSize_t associated with the next Inode to be allocated
*/
FsSize_t iterator();
/**
* Converts an actual pointer to a FsSize_t.
*/
FsSize_t ptr(void *ptr);
/**
* Converts a FsSize_t to an actual pointer.
*/
template<typename T>
T ptr(FsSize_t ptr) {
return (T) (m_begin + ptr);
};
Inode *firstInode();
Inode *lastInode();
};
template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::Inode::size() {
return sizeof(Inode) + dataLen;
}
template<typename FsSize_t>
void FileStore<FsSize_t>::Inode::setId(InodeId_t id) {
this->m_id = id;
}
template<typename FsSize_t>
void FileStore<FsSize_t>::Inode::setData(void *data, int size) {
memcpy(this + 1, data, size);
dataLen = size;
}
// FileStore
template<typename FsSize_t>
FileStore<FsSize_t>::FileStore(uint8_t *begin, uint8_t *end, Error *error): m_version(*((uint32_t*) begin)) {
if (version() != m_version) {
// version mismatch
if (error) {
*error = 1;
}
} else {
// ok
m_begin = begin;
m_end = end;
auto header = (FsHeader*) m_begin;
m_root = ptr<Inode*>(header->rootInode);
if (error) {
*error = header->size != (unsigned ) (m_end - m_begin);
}
}
}
template<typename FsSize_t>
void FileStore<FsSize_t>::init() {
memset(m_begin, 0, m_end - m_begin);
m_version = version();
}
template<typename FsSize_t>
int FileStore<FsSize_t>::write(void *data, FsSize_t dataLen) {
return 1;
}
template<typename FsSize_t>
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
auto retval = 1;
const FsSize_t size = sizeof(Inode) + dataLen;
auto inode = (Inode*) alloc(size);
if (inode) {
inode->m_id = id;
inode->setData(data, dataLen);
if (insert(m_root, inode) || m_root == inode) {
retval = 0;
}
}
return retval;
}
template<typename FsSize_t>
int FileStore<FsSize_t>::read(InodeId_t id, void *data, FsSize_t *size) {
auto inode = getInode(m_root, id);
int retval = 1;
if (inode) {
if (size) {
*size = inode->dataLen;
}
memcpy(data, inode + 1, inode->dataLen);
retval = 0;
}
return retval;
}
template<typename FsSize_t>
typename FileStore<FsSize_t>::StatInfo FileStore<FsSize_t>::stat(InodeId_t id) {
auto inode = getInode(m_root, id);
StatInfo stat;
if (inode) {
stat.size = inode->dataLen;
stat.inodeId = id;
} else {
stat.inodeId = 0;
}
return stat;
}
template<typename FsSize_t>
typename FileStore<FsSize_t>::FsHeader *FileStore<FsSize_t>::getHeader() {
return (FsHeader*) m_begin;
}
template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getInode(Inode *root, InodeId_t id) {
Inode *retval = nullptr;
if (root->m_id > id) {
if (root->left) {
retval = getInode(ptr<Inode*>(root->left), id);
}
} else if (root->m_id < id) {
if (root->right) {
retval = getInode(ptr<Inode*>(root->right), id);
}
} else if (root->m_id == id) {
retval = root;
}
return retval;
}
template<typename FsSize_t>
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
if ((lastInode()->next + size) > (uint64_t) m_end) {
compress();
if ((lastInode()->next + size) > (uint64_t) m_end) {
return nullptr;
}
}
const auto retval = lastInode()->next;
const auto inode = ptr<Inode*>(retval);
memset(inode, 0, size);
inode->prev = ptr(lastInode());
inode->next = retval + size;
firstInode()->prev = retval;
return inode;
}
template<typename FsSize_t>
void FileStore<FsSize_t>::compress() {
auto current = m_root;
while (current->next) {
auto prevEnd = current + current->size();
current = ptr<Inode*>(current->next);
if (prevEnd != current) {
memcpy(prevEnd, current, current->size());
current = prevEnd;
}
}
}
template<typename FsSize_t>
bool FileStore<FsSize_t>::insert(Inode *root, Inode *insertValue) {
auto retval = false;
if (root->m_id > insertValue->m_id) {
if (root->left) {
retval = insert(ptr<Inode*>(root->left), insertValue);
} else {
root->left = ptr(insertValue);
retval = true;
}
} else if (root->m_id < insertValue->m_id) {
if (root->right) {
retval = insert(ptr<Inode*>(root->right), insertValue);
} else {
root->right = ptr(insertValue);
retval = true;
}
}
return retval;
}
template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::iterator() {
return ptr(lastInode()) + lastInode()->size();
}
template<typename FsSize_t>
FsSize_t FileStore<FsSize_t>::ptr(void *ptr) {
return ((uint8_t*) ptr) - m_begin;
}
template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::firstInode() {
return ptr<Inode*>(sizeof(FsHeader));
}
template<typename FsSize_t>
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::lastInode() {
return ptr<Inode*>(firstInode()->prev);
}
template<typename FsSize_t>
uint8_t FileStore<FsSize_t>::version() {
return 0;
};
template<typename FsSize_t>
uint8_t *FileStore<FsSize_t>::format(uint8_t *buffer, FsSize_t size) {
memset(buffer, 0, size);
auto header = (FsHeader*) buffer;
header->version = FileStore<FsSize_t>::version();
header->size = size;
header->rootInode = sizeof(FsHeader);
auto inodeSection = (Inode*) (buffer + header->rootInode);
inodeSection->m_id = 0;
inodeSection->next = inodeSection->prev = (uint8_t*) inodeSection - (uint8_t*) buffer;
return (uint8_t*) header;
}
typedef FileStore<uint16_t> FileStore16;
typedef FileStore<uint32_t> FileStore32;
typedef FileStore<uint64_t> FileStore64;
}
}
+8
View File
@@ -0,0 +1,8 @@
/*
* Copyright 2015 - 2016 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/.
*/
#include "filesystem.hpp"
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright 2015 - 2016 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/_memops.hpp>
#include <ox/std/_strops.hpp>
#include <ox/std/_types.hpp>
#include "filestore.hpp"
namespace ox {
namespace fs {
struct FileStat {
uint64_t inode;
uint64_t size;
};
template<typename FileStore>
class FileSystem {
private:
FileStore *store = nullptr;
public:
int read(const char *path, void *buffer);
FileStat stat(const char *path);
FileStat stat(typename FileStore::InodeId_t inode);
};
template<typename FileStore>
FileStat FileSystem<FileStore>::stat(const char *path) {
FileStat stat;
return stat;
}
template<typename FileStore>
FileStat FileSystem<FileStore>::stat(typename FileStore::InodeId_t inode) {
FileStat stat;
auto s = store->stat(inode);
stat.size = s.size;
stat.inode = s.inodeId;
return stat;
}
typedef FileSystem<FileStore16> FileSystem16;
typedef FileSystem<FileStore32> FileSystem32;
typedef FileSystem<FileStore64> FileSystem64;
}
}
+17
View File
@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 2.8)
add_executable(
Format
format.cpp
)
add_executable(
FileStoreIO
filestoreio.cpp
)
target_link_libraries(Format OxFS OxStd)
target_link_libraries(FileStoreIO OxFS OxStd)
add_test("Format" Format)
add_test("FileStoreIO" FileStoreIO)
+46
View File
@@ -0,0 +1,46 @@
/*
* Copyright 2015 - 2016 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/.
*/
#include <ox/std/_strops.hpp>
#include <ox/fs/filestore.hpp>
using namespace ox::fs;
template<typename FileStore>
int test() {
const auto size = 65535;
uint8_t volume[size];
char out[6];
uint32_t err;
typename FileStore::FsSize_t outSize;
FileStore::format(volume, size);
FileStore fs(volume, volume + size, &err);
if (fs.write(1, (void*) "Hello", 6) ||
fs.read(1, (char*) out, &outSize) ||
strcmp("Hello", out)) {
return 1;
}
if (fs.write(2, (void*) "World", 6) ||
fs.read(2, (char*) out, &outSize) ||
strcmp("World", out)) {
return 1;
}
// make sure first value was not overwritten
if (fs.read(1, (char*) out, &outSize) ||
strcmp("Hello", out)) {
return 1;
}
return 0;
}
int main() {
return test<FileStore16>() | test<FileStore32>() | test<FileStore64>();
}
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright 2015 - 2016 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/.
*/
#include <ox/fs/filestore.hpp>
using namespace ox::fs;
int main() {
const auto size = 65535;
uint8_t volume[size];
uint32_t err;
FileStore32::format(volume, size);
FileStore32(volume, volume + size, &err);
return err;
}
+15
View File
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 2.8)
add_library(
OxStd
_memops.cpp
_strops.cpp
)
install(
FILES
_memops.hpp
_strops.hpp
DESTINATION
include/ox/std
)
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright 2015 - 2016 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/.
*/
#include "_memops.hpp"
namespace ox {
namespace std {
void memcpy(void *dest, void *src, int size) {
char *srcBuf = (char*) src;
char *dstBuf = (char*) dest;
for (int i = 0; i < size; i++) {
dstBuf[i] = (char) srcBuf[i];
}
}
void memset(void *ptr, char val, int size) {
char *buf = (char*) ptr;
for (int i = 0; i < size; i++) {
buf[i] = val;
}
}
}
}
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright 2015 - 2016 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
namespace ox {
namespace std {
void memcpy(void *src, void *dest, int size);
void memset(void *ptr, char val, int size);
}
}
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright 2015 - 2016 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/.
*/
namespace ox {
namespace std {
int strcmp(const char *str1, const char *str2) {
auto retval = 0;
auto i = 0;
do {
if (str1[i] < str2[i]) {
retval = -1;
break;
} else if (str1[i] > str2[i]) {
retval = 1;
break;
}
i++;
} while (str1[i] == str2[i] && str1[i]);
return retval;
}
}
}
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright 2015 - 2016 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
namespace ox {
namespace std {
int strcmp(const char *str1, const char *str2);
}
}
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright 2015 - 2016 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
namespace ox {
namespace std {
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned uint_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef uint32_t Error;
#if defined(_LP64) || defined(__ppc64__) || defined(_WIN64)
typedef uint64_t size_t;
#elif defined(_LP32) || defined(__ppc__) || defined(_WIN32)
typedef uint32_t size_t;
#else
#error size_t undefined
#endif
}
}