Made FileStore a template to support arbitrary address space sizes.
This commit is contained in:
+3
-2
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.8)
|
cmake_minimum_required(VERSION 2.8.8)
|
||||||
|
|
||||||
project(Memphis)
|
project(WombatFS)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||||
include(address_sanitizer)
|
include(address_sanitizer)
|
||||||
@@ -24,4 +24,5 @@ include_directories("src")
|
|||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
|
||||||
add_test("MemFs" test/MemFsTest)
|
add_test("Format" test/Format)
|
||||||
|
add_test("FsStore" test/FsStore)
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.8)
|
cmake_minimum_required(VERSION 2.8.8)
|
||||||
|
|
||||||
add_library(
|
add_library(
|
||||||
Memphis
|
WFS
|
||||||
filestore.cpp
|
filestore.cpp
|
||||||
_memops.cpp
|
_memops.cpp
|
||||||
)
|
)
|
||||||
@@ -11,5 +11,5 @@ install(
|
|||||||
filestore.hpp
|
filestore.hpp
|
||||||
_memops.hpp
|
_memops.hpp
|
||||||
DESTINATION
|
DESTINATION
|
||||||
include/Memphis
|
include/WFS
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,156 +10,5 @@
|
|||||||
|
|
||||||
namespace wombat {
|
namespace wombat {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
uint32_t FileStore::version = 0;
|
|
||||||
|
|
||||||
uint8_t *initFs(uint8_t *buffer, size_t size, bool hasDirectories) {
|
|
||||||
auto fs = (MemFsHeader*) buffer;
|
|
||||||
fs->version = FileStore::version;
|
|
||||||
return (uint8_t*) fs;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemFsPtr FileStore::Record::size() {
|
|
||||||
return offsetof(FileStore::Record, m_id) + dataLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileStore::Record::setId(RecordId id) {
|
|
||||||
this->m_id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileStore::Record::setData(uint8_t *data, int size) {
|
|
||||||
memcpy(this + m_data, data, size);
|
|
||||||
m_data = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FileStore
|
|
||||||
|
|
||||||
FileStore::FileStore(uint8_t *begin, uint8_t *end, Error *error): m_version(*((uint32_t*) begin)), m_lastRec(*(MemFsPtr*) (begin + sizeof(m_version))) {
|
|
||||||
if (version != m_version) {
|
|
||||||
// version mismatch
|
|
||||||
if (error) {
|
|
||||||
*error = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ok
|
|
||||||
m_begin = begin;
|
|
||||||
m_end = end;
|
|
||||||
m_root = (Record*) (begin + sizeof(MemFsPtr));
|
|
||||||
if (error) {
|
|
||||||
*error = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileStore::init() {
|
|
||||||
memset(m_begin, 0, m_end - m_begin);
|
|
||||||
m_version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileStore::write(RecordId id, uint8_t *data, MemFsPtr dataLen) {
|
|
||||||
const MemFsPtr size = offsetof(FileStore::Record, m_id) + dataLen;
|
|
||||||
auto rec = (Record*) alloc(size);
|
|
||||||
rec->dataLen = dataLen;
|
|
||||||
insert(m_root, rec);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FileStore::read(RecordId id, uint8_t *data, MemFsPtr *size) {
|
|
||||||
auto rec = getRecord(m_root, id);
|
|
||||||
int retval = 1;
|
|
||||||
if (rec) {
|
|
||||||
*size = rec->dataLen;
|
|
||||||
memcpy(data, ptr<uint8_t*>(rec->m_data), *size);
|
|
||||||
retval = 0;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStore::Record *FileStore::getRecord(FileStore::Record *root, RecordId id) {
|
|
||||||
auto cmp = root->m_id > id;
|
|
||||||
MemFsPtr recPt;
|
|
||||||
if (cmp) {
|
|
||||||
recPt = root->left;
|
|
||||||
} else if (!cmp) {
|
|
||||||
recPt = root->right;
|
|
||||||
} else {
|
|
||||||
recPt = ptr(root);
|
|
||||||
}
|
|
||||||
if (recPt) {
|
|
||||||
return getRecord(ptr<Record*>(recPt), id);
|
|
||||||
} else {
|
|
||||||
return ptr<Record*>(recPt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *FileStore::alloc(MemFsPtr size) {
|
|
||||||
const auto iterator = this->iterator();
|
|
||||||
if ((iterator + size) > (uint64_t) m_end) {
|
|
||||||
compress();
|
|
||||||
if ((iterator + size) > (uint64_t) m_end) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptr<Record*>(m_lastRec)->next = iterator;
|
|
||||||
|
|
||||||
auto rec = ptr<uint8_t*>(iterator);
|
|
||||||
memset(rec, 0, size);
|
|
||||||
ptr<Record*>(iterator)->prev = m_lastRec;
|
|
||||||
m_lastRec = iterator;
|
|
||||||
return rec;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileStore::compress() {
|
|
||||||
auto current = m_root;
|
|
||||||
while (current->next) {
|
|
||||||
auto prevEnd = current + current->size();
|
|
||||||
current = ptr<Record*>(current->next);
|
|
||||||
if (prevEnd != current) {
|
|
||||||
memcpy(prevEnd, current, current->size());
|
|
||||||
current = prevEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileStore::insert(Record *root, Record *insertValue, MemFsPtr *rootParentPtr) {
|
|
||||||
auto cmp = root->m_id > insertValue->m_id;
|
|
||||||
if (cmp) {
|
|
||||||
if (root->left) {
|
|
||||||
return insert(ptr<Record*>(root->left), insertValue, &root->left);
|
|
||||||
} else {
|
|
||||||
root->left = ((uint8_t*) insertValue) - m_begin;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (!cmp) {
|
|
||||||
if (root->right) {
|
|
||||||
return insert(ptr<Record*>(root->right), insertValue, &root->right);
|
|
||||||
} else {
|
|
||||||
root->right = ((uint8_t*) insertValue) - m_begin;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto ivAddr = ((uint8_t*) insertValue) - m_begin;
|
|
||||||
if (root->prev) {
|
|
||||||
ptr<Record*>(root->prev)->next = ivAddr;
|
|
||||||
}
|
|
||||||
if (root->next) {
|
|
||||||
ptr<Record*>(root->next)->prev = ivAddr;
|
|
||||||
}
|
|
||||||
if (rootParentPtr) {
|
|
||||||
*rootParentPtr = ivAddr;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemFsPtr FileStore::iterator() {
|
|
||||||
return m_lastRec + ((Record*) m_begin + m_lastRec)->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
MemFsPtr FileStore::ptr(void *ptr) {
|
|
||||||
return ((uint8_t*) ptr) - m_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+213
-41
@@ -8,42 +8,42 @@
|
|||||||
#ifndef WOMBAT_FS_FILESTORE_HPP
|
#ifndef WOMBAT_FS_FILESTORE_HPP
|
||||||
#define WOMBAT_FS_FILESTORE_HPP
|
#define WOMBAT_FS_FILESTORE_HPP
|
||||||
|
|
||||||
|
#include "_memops.hpp"
|
||||||
#include "_types.hpp"
|
#include "_types.hpp"
|
||||||
|
|
||||||
namespace wombat {
|
namespace wombat {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
typedef uint32_t MemFsPtr;
|
template<typename FsSize_t>
|
||||||
typedef uint32_t RecordId;
|
|
||||||
|
|
||||||
struct MemFsHeader {
|
|
||||||
uint32_t version;
|
|
||||||
MemFsPtr rootDir = -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DirectoryHeader {
|
|
||||||
/**
|
|
||||||
* Count of the number of files listed in this directory.
|
|
||||||
*/
|
|
||||||
MemFsPtr files;
|
|
||||||
|
|
||||||
const char* operator[](int i);
|
|
||||||
};
|
|
||||||
|
|
||||||
class FileStore {
|
class FileStore {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static uint32_t version;
|
struct FsHeader {
|
||||||
|
uint32_t version;
|
||||||
|
FsSize_t rootDir = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Inode {
|
||||||
|
enum class Type: uint8_t {
|
||||||
|
FILE,
|
||||||
|
DIRECTORY
|
||||||
|
} type;
|
||||||
|
FsSize_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef FsSize_t RecordId;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Record {
|
struct Record {
|
||||||
// the next Record in memory
|
// the next Record in memory
|
||||||
MemFsPtr prev, next;
|
FsSize_t prev, next;
|
||||||
MemFsPtr left, right;
|
FsSize_t left, right;
|
||||||
MemFsPtr dataLen;
|
FsSize_t dataLen;
|
||||||
// offsets from Record this
|
// offsets from Record this
|
||||||
MemFsPtr m_id;
|
FsSize_t m_id;
|
||||||
MemFsPtr m_data;
|
FsSize_t m_data;
|
||||||
|
|
||||||
MemFsPtr size();
|
FsSize_t size();
|
||||||
void setId(RecordId);
|
void setId(RecordId);
|
||||||
void setData(uint8_t *data, int size);
|
void setData(uint8_t *data, int size);
|
||||||
};
|
};
|
||||||
@@ -51,7 +51,7 @@ class FileStore {
|
|||||||
uint8_t *m_begin, *m_end;
|
uint8_t *m_begin, *m_end;
|
||||||
uint32_t &m_version;
|
uint32_t &m_version;
|
||||||
// the last Record in the FileStore's memory chunk
|
// the last Record in the FileStore's memory chunk
|
||||||
MemFsPtr &m_lastRec;
|
FsSize_t &m_lastRec;
|
||||||
Record *m_root;
|
Record *m_root;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -75,7 +75,7 @@ class FileStore {
|
|||||||
* @param data the contents of the file
|
* @param data the contents of the file
|
||||||
* @param dataLen the number of bytes data points to
|
* @param dataLen the number of bytes data points to
|
||||||
*/
|
*/
|
||||||
void write(RecordId id, uint8_t *data, MemFsPtr dataLen);
|
void write(RecordId id, uint8_t *data, FsSize_t dataLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the "file" at the given id. You are responsible for freeing
|
* Reads the "file" at the given id. You are responsible for freeing
|
||||||
@@ -85,7 +85,11 @@ class FileStore {
|
|||||||
* @param size pointer to a value that will be assigned the size of data
|
* @param size pointer to a value that will be assigned the size of data
|
||||||
* @return 0 if read is a success
|
* @return 0 if read is a success
|
||||||
*/
|
*/
|
||||||
int read(RecordId id, uint8_t *data, MemFsPtr *size);
|
int read(RecordId id, uint8_t *data, FsSize_t *size);
|
||||||
|
|
||||||
|
static uint8_t version();
|
||||||
|
|
||||||
|
static uint8_t *format(uint8_t *buffer, size_t size, bool hasDirectories);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@@ -95,13 +99,13 @@ class FileStore {
|
|||||||
* @param pathLen number of characters in pathLen
|
* @param pathLen number of characters in pathLen
|
||||||
* @return the requested Record, if available
|
* @return the requested Record, if available
|
||||||
*/
|
*/
|
||||||
Record *getRecord(Record *root, RecordId id);
|
Record *getRecord(FileStore::Record *root, RecordId id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an address for a new Record.
|
* Gets an address for a new Record.
|
||||||
* @param size the size of the Record
|
* @param size the size of the Record
|
||||||
*/
|
*/
|
||||||
void *alloc(MemFsPtr size);
|
void *alloc(FsSize_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compresses all of the records into a contiguous space, starting at m_root.
|
* Compresses all of the records into a contiguous space, starting at m_root.
|
||||||
@@ -113,32 +117,200 @@ class FileStore {
|
|||||||
* If the record already exists, it replaces the old on deletes it.
|
* If the record already exists, it replaces the old on deletes it.
|
||||||
* @return true if the record was inserted
|
* @return true if the record was inserted
|
||||||
*/
|
*/
|
||||||
bool insert(Record *root, Record *insertValue, MemFsPtr *rootParentPtr = 0);
|
bool insert(Record *root, Record *insertValue, FsSize_t *rootParentPtr = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the MemFsPtr associated with the next Record to be allocated.
|
* Gets the FsSize_t associated with the next Record to be allocated.
|
||||||
* @retrun the MemFsPtr associated with the next Record to be allocated
|
* @retrun the FsSize_t associated with the next Record to be allocated
|
||||||
*/
|
*/
|
||||||
MemFsPtr iterator();
|
FsSize_t iterator();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an actual pointer to a MemFsPtr.
|
* Converts an actual pointer to a FsSize_t.
|
||||||
*/
|
*/
|
||||||
MemFsPtr ptr(void *ptr);
|
FsSize_t ptr(void *ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a MemFsPtr to an actual pointer.
|
* Converts a FsSize_t to an actual pointer.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T ptr(MemFsPtr ptr);
|
T ptr(FsSize_t ptr) {
|
||||||
|
return (T) m_begin + ptr;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename FsSize_t>
|
||||||
T FileStore::ptr(MemFsPtr ptr) {
|
FsSize_t FileStore<FsSize_t>::Record::size() {
|
||||||
return (T) m_begin + ptr;
|
return offsetof(FileStore::Record, m_id) + dataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *initFs(uint8_t *buffer, size_t size, bool hasDirectories);
|
template<typename FsSize_t>
|
||||||
|
void FileStore<FsSize_t>::Record::setId(RecordId id) {
|
||||||
|
this->m_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
void FileStore<FsSize_t>::Record::setData(uint8_t *data, int size) {
|
||||||
|
memcpy(this + m_data, data, size);
|
||||||
|
m_data = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FileStore
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
FileStore<FsSize_t>::FileStore(uint8_t *begin, uint8_t *end, Error *error): m_version(*((uint32_t*) begin)), m_lastRec(*(FsSize_t*) (begin + sizeof(m_version))) {
|
||||||
|
if (version() != m_version) {
|
||||||
|
// version mismatch
|
||||||
|
if (error) {
|
||||||
|
*error = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ok
|
||||||
|
m_begin = begin;
|
||||||
|
m_end = end;
|
||||||
|
m_root = (Record*) (begin + sizeof(FsSize_t));
|
||||||
|
if (error) {
|
||||||
|
*error = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
void FileStore<FsSize_t>::init() {
|
||||||
|
memset(m_begin, 0, m_end - m_begin);
|
||||||
|
m_version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
void FileStore<FsSize_t>::write(RecordId id, uint8_t *data, FsSize_t dataLen) {
|
||||||
|
const FsSize_t size = offsetof(FileStore::Record, m_id) + dataLen;
|
||||||
|
auto rec = (Record*) alloc(size);
|
||||||
|
rec->dataLen = dataLen;
|
||||||
|
insert(m_root, rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
int FileStore<FsSize_t>::read(RecordId id, uint8_t *data, FsSize_t *size) {
|
||||||
|
auto rec = getRecord(m_root, id);
|
||||||
|
int retval = 1;
|
||||||
|
if (rec) {
|
||||||
|
if (size) {
|
||||||
|
*size = rec->dataLen;
|
||||||
|
}
|
||||||
|
memcpy(data, ptr<uint8_t*>(rec->m_data), rec->dataLen);
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
typename FileStore<FsSize_t>::Record *FileStore<FsSize_t>::getRecord(FileStore::Record *root, RecordId id) {
|
||||||
|
auto cmp = root->m_id > id;
|
||||||
|
FsSize_t recPt;
|
||||||
|
if (cmp) {
|
||||||
|
recPt = root->left;
|
||||||
|
} else if (!cmp) {
|
||||||
|
recPt = root->right;
|
||||||
|
} else {
|
||||||
|
recPt = ptr(root);
|
||||||
|
}
|
||||||
|
if (recPt) {
|
||||||
|
return getRecord(ptr<Record*>(recPt), id);
|
||||||
|
} else {
|
||||||
|
return ptr<Record*>(recPt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
|
||||||
|
const auto iterator = this->iterator();
|
||||||
|
if ((iterator + size) > (uint64_t) m_end) {
|
||||||
|
compress();
|
||||||
|
if ((iterator + size) > (uint64_t) m_end) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr<Record*>(m_lastRec)->next = iterator;
|
||||||
|
|
||||||
|
auto rec = ptr<uint8_t*>(iterator);
|
||||||
|
memset(rec, 0, size);
|
||||||
|
ptr<Record*>(iterator)->prev = m_lastRec;
|
||||||
|
m_lastRec = iterator;
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
void FileStore<FsSize_t>::compress() {
|
||||||
|
auto current = m_root;
|
||||||
|
while (current->next) {
|
||||||
|
auto prevEnd = current + current->size();
|
||||||
|
current = ptr<Record*>(current->next);
|
||||||
|
if (prevEnd != current) {
|
||||||
|
memcpy(prevEnd, current, current->size());
|
||||||
|
current = prevEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
bool FileStore<FsSize_t>::insert(Record *root, Record *insertValue, FsSize_t *rootParentPtr) {
|
||||||
|
auto cmp = root->m_id > insertValue->m_id;
|
||||||
|
if (cmp) {
|
||||||
|
if (root->left) {
|
||||||
|
return insert(ptr<Record*>(root->left), insertValue, &root->left);
|
||||||
|
} else {
|
||||||
|
root->left = ((uint8_t*) insertValue) - m_begin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (!cmp) {
|
||||||
|
if (root->right) {
|
||||||
|
return insert(ptr<Record*>(root->right), insertValue, &root->right);
|
||||||
|
} else {
|
||||||
|
root->right = ((uint8_t*) insertValue) - m_begin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto ivAddr = ((uint8_t*) insertValue) - m_begin;
|
||||||
|
if (root->prev) {
|
||||||
|
ptr<Record*>(root->prev)->next = ivAddr;
|
||||||
|
}
|
||||||
|
if (root->next) {
|
||||||
|
ptr<Record*>(root->next)->prev = ivAddr;
|
||||||
|
}
|
||||||
|
if (rootParentPtr) {
|
||||||
|
*rootParentPtr = ivAddr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
FsSize_t FileStore<FsSize_t>::iterator() {
|
||||||
|
return m_lastRec + ((Record*) m_begin + m_lastRec)->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FsSize_t>
|
||||||
|
FsSize_t FileStore<FsSize_t>::ptr(void *ptr) {
|
||||||
|
return ((uint8_t*) ptr) - m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, size_t size, bool hasDirectories) {
|
||||||
|
auto retval = (typename FileStore<FsSize_t>::FsHeader*) buffer;
|
||||||
|
retval->version = FileStore<FsSize_t>::version();
|
||||||
|
return (uint8_t*) retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef FileStore<uint16_t> FileStore16;
|
||||||
|
typedef FileStore<uint32_t> FileStore32;
|
||||||
|
typedef FileStore<uint64_t> FileStore64;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -1,8 +1,14 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.8)
|
cmake_minimum_required(VERSION 2.8.8)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
MemFsTest
|
Format
|
||||||
test.cpp
|
format.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(MemFsTest Memphis)
|
add_executable(
|
||||||
|
FsStore
|
||||||
|
fsstore.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(Format WFS)
|
||||||
|
target_link_libraries(FsStore WFS)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ int main() {
|
|||||||
const auto size = 1 << 16;
|
const auto size = 1 << 16;
|
||||||
uint8_t volume[size];
|
uint8_t volume[size];
|
||||||
uint32_t err;
|
uint32_t err;
|
||||||
initFs(volume, size, false);
|
FileStore32::format(volume, size, false);
|
||||||
FileStore(volume, volume + size, &err);
|
FileStore32(volume, volume + size, &err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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>
|
||||||
|
|
||||||
|
using namespace wombat::fs;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const auto size = 1 << 16;
|
||||||
|
uint8_t volume[size];
|
||||||
|
char out[6];
|
||||||
|
uint32_t err;
|
||||||
|
FileStore32 fs(volume, volume + size, &err);
|
||||||
|
fs.write(42, (uint8_t*) "Hello", 6);
|
||||||
|
err = fs.read(42, (uint8_t*) out, nullptr);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user