Fixed several problem with the file store.
This commit is contained in:
Executable
+1
@@ -0,0 +1 @@
|
|||||||
|
clang-check `find . | grep "\.cpp" | grep -v CMakeFiles | grep -v editormodels\.cpp`
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
BRANCH=$1
|
||||||
|
./scripts/setup_build
|
||||||
|
make -j4 -C build/sdl clean wombat
|
||||||
|
rm -rf wombat wombat-*-*.tar.gz
|
||||||
|
mkdir wombat
|
||||||
|
git rev-parse HEAD > wombat/revision.txt
|
||||||
|
cp -pr wombat_path build/sdl/src/wombat/wombat wombat
|
||||||
|
tar -cvzf wombat-${BRANCH}-`date "+%y%m%d%H%M"`.tar.gz wombat
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
pkg = sys.argv[1]
|
||||||
|
name = sys.argv[2]
|
||||||
|
ifdef = "WOMBAT_%s_%s_HPP" % (pkg.upper(), name.upper())
|
||||||
|
namespace = "namespace wombat {\nnamespace %s {\n\n}\n}" % pkg
|
||||||
|
hpp = "#ifndef %s\n#define %s\n\n%s\n\n#endif" % (ifdef, ifdef, namespace)
|
||||||
|
cpp = "#include \"%s.hpp\"\n\n%s" % (name, namespace)
|
||||||
|
|
||||||
|
open("src/%s/%s.hpp" % (pkg, name), "w").write(hpp)
|
||||||
|
open("src/%s/%s.cpp" % (pkg, name), "w").write(cpp)
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
project=`pwd`/
|
||||||
|
buildDir="build/sdl"
|
||||||
|
|
||||||
|
mkdir -p $buildDir
|
||||||
|
pushd $buildDir
|
||||||
|
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release $project
|
||||||
|
popd
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
project=`pwd`
|
||||||
|
buildDir="build/sdl_debug"
|
||||||
|
|
||||||
|
mkdir -p $buildDir
|
||||||
|
pushd $buildDir
|
||||||
|
cmake -DUSE_ASAN=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug $project
|
||||||
|
popd
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
project=`pwd`
|
||||||
|
buildDir="build/gba"
|
||||||
|
|
||||||
|
mkdir -p $buildDir
|
||||||
|
pushd $buildDir
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_TOOLCHAIN_FILE=cmake/Modules/GBA.cmake -DWOMBAT_BUILD_TYPE=GBA $project
|
||||||
|
popd
|
||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
namespace wombat {
|
namespace wombat {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
|
|
||||||
void memcpy(void *src, void *dest, int size) {
|
void memcpy(void *dest, void *src, int size) {
|
||||||
char *srcBuf = (char*) src;
|
char *srcBuf = (char*) src;
|
||||||
char *dstBuf = (char*) dest;
|
char *dstBuf = (char*) dest;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
|||||||
+5
-2
@@ -10,14 +10,17 @@ namespace fs {
|
|||||||
|
|
||||||
int strcmp(const char *str1, const char *str2) {
|
int strcmp(const char *str1, const char *str2) {
|
||||||
auto retval = 0;
|
auto retval = 0;
|
||||||
for (int i = 0; str1[i] && str2[i]; i++) {
|
auto i = 0;
|
||||||
|
do {
|
||||||
if (str1[i] < str2[i]) {
|
if (str1[i] < str2[i]) {
|
||||||
retval = -1;
|
retval = -1;
|
||||||
break;
|
break;
|
||||||
} else if (str1[i] > str2[i]) {
|
} else if (str1[i] > str2[i]) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
i++;
|
||||||
|
} while (str1[i] == str2[i] && str1[i]);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+75
-61
@@ -21,7 +21,7 @@ class FileStore {
|
|||||||
struct FsHeader {
|
struct FsHeader {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
FsSize_t size;
|
FsSize_t size;
|
||||||
FsSize_t rootInode = 0;
|
FsSize_t rootInode;
|
||||||
bool insertLeft = false; // crude tree balancing mechanism
|
bool insertLeft = false; // crude tree balancing mechanism
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,13 +33,15 @@ class FileStore {
|
|||||||
FsSize_t prev, next;
|
FsSize_t prev, next;
|
||||||
FsSize_t left, right;
|
FsSize_t left, right;
|
||||||
FsSize_t dataLen;
|
FsSize_t dataLen;
|
||||||
// offsets from Inode this
|
|
||||||
|
// The following variables should not be assumed to exist
|
||||||
FsSize_t m_id;
|
FsSize_t m_id;
|
||||||
FsSize_t m_data;
|
// must be last item
|
||||||
|
uint8_t m_data;
|
||||||
|
|
||||||
FsSize_t size();
|
FsSize_t size();
|
||||||
void setId(InodeId_t);
|
void setId(InodeId_t);
|
||||||
void setData(uint8_t *data, int size);
|
void setData(void *data, int size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Inode() = default;
|
Inode() = default;
|
||||||
@@ -47,8 +49,6 @@ class FileStore {
|
|||||||
|
|
||||||
uint8_t *m_begin, *m_end;
|
uint8_t *m_begin, *m_end;
|
||||||
uint32_t &m_version;
|
uint32_t &m_version;
|
||||||
// the last Inode in the FileStore's memory chunk
|
|
||||||
FsSize_t &m_lastRec;
|
|
||||||
Inode *m_root;
|
Inode *m_root;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -128,7 +128,7 @@ 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(Inode *root, Inode *insertValue, FsSize_t *rootParentPtr = 0);
|
bool insert(Inode *root, Inode *insertValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the FsSize_t associated with the next Inode to be allocated.
|
* Gets the FsSize_t associated with the next Inode to be allocated.
|
||||||
@@ -146,8 +146,12 @@ class FileStore {
|
|||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T ptr(FsSize_t ptr) {
|
T ptr(FsSize_t ptr) {
|
||||||
return (T) m_begin + ptr;
|
return (T) (m_begin + ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Inode *firstInode();
|
||||||
|
|
||||||
|
Inode *lastInode();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
@@ -161,16 +165,16 @@ void FileStore<FsSize_t>::Inode::setId(InodeId_t id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
void FileStore<FsSize_t>::Inode::setData(uint8_t *data, int size) {
|
void FileStore<FsSize_t>::Inode::setData(void *data, int size) {
|
||||||
memcpy(this + m_data, data, size);
|
memcpy(&m_data, data, size);
|
||||||
m_data = size;
|
dataLen = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FileStore
|
// FileStore
|
||||||
|
|
||||||
template<typename FsSize_t>
|
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(FsHeader))) {
|
FileStore<FsSize_t>::FileStore(uint8_t *begin, uint8_t *end, Error *error): m_version(*((uint32_t*) begin)) {
|
||||||
if (version() != m_version) {
|
if (version() != m_version) {
|
||||||
// version mismatch
|
// version mismatch
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -203,10 +207,11 @@ template<typename FsSize_t>
|
|||||||
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
|
int FileStore<FsSize_t>::write(InodeId_t id, void *data, FsSize_t dataLen) {
|
||||||
auto retval = 1;
|
auto retval = 1;
|
||||||
const FsSize_t size = offsetof(Inode, m_id) + dataLen;
|
const FsSize_t size = offsetof(Inode, m_id) + dataLen;
|
||||||
auto rec = (Inode*) alloc(size);
|
auto inode = (Inode*) alloc(size);
|
||||||
if (rec) {
|
if (inode) {
|
||||||
rec->dataLen = dataLen;
|
inode->m_id = id;
|
||||||
if (insert(m_root, rec)) {
|
inode->setData(data, dataLen);
|
||||||
|
if (insert(m_root, inode) || m_root == inode) {
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,7 +226,7 @@ int FileStore<FsSize_t>::read(InodeId_t id, void *data, FsSize_t *size) {
|
|||||||
if (size) {
|
if (size) {
|
||||||
*size = rec->dataLen;
|
*size = rec->dataLen;
|
||||||
}
|
}
|
||||||
memcpy(data, ptr<uint8_t*>(rec->m_data), rec->dataLen);
|
memcpy(data, &rec->m_data, rec->dataLen);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
@@ -234,37 +239,38 @@ typename FileStore<FsSize_t>::FsHeader *FileStore<FsSize_t>::getHeader() {
|
|||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getRecord(FileStore::Inode *root, InodeId_t id) {
|
typename FileStore<FsSize_t>::Inode *FileStore<FsSize_t>::getRecord(FileStore::Inode *root, InodeId_t id) {
|
||||||
auto cmp = root->m_id > id;
|
Inode *retval = nullptr;
|
||||||
FsSize_t recPt;
|
|
||||||
if (cmp) {
|
if (root->m_id > id) {
|
||||||
recPt = root->left;
|
if (root->left) {
|
||||||
} else if (!cmp) {
|
retval = getRecord(ptr<Inode*>(root->left), id);
|
||||||
recPt = root->right;
|
}
|
||||||
} else {
|
} else if (root->m_id < id) {
|
||||||
recPt = ptr(root);
|
if (root->right) {
|
||||||
}
|
retval = getRecord(ptr<Inode*>(root->right), id);
|
||||||
if (recPt) {
|
}
|
||||||
return getRecord(ptr<Inode*>(recPt), id);
|
} else if (root->m_id == id) {
|
||||||
} else {
|
retval = root;
|
||||||
return ptr<Inode*>(recPt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
|
void *FileStore<FsSize_t>::alloc(FsSize_t size) {
|
||||||
const auto iterator = this->iterator();
|
if ((lastInode()->next + size) > (uint64_t) m_end) {
|
||||||
if ((iterator + size) > (uint64_t) m_end) {
|
|
||||||
compress();
|
compress();
|
||||||
if ((iterator + size) > (uint64_t) m_end) {
|
if ((lastInode()->next + size) > (uint64_t) m_end) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr<Inode*>(m_lastRec)->next = iterator;
|
|
||||||
|
|
||||||
auto rec = ptr<uint8_t*>(iterator);
|
const auto retval = lastInode()->next;
|
||||||
|
const auto rec = ptr<Inode*>(retval);
|
||||||
memset(rec, 0, size);
|
memset(rec, 0, size);
|
||||||
ptr<Inode*>(iterator)->prev = m_lastRec;
|
rec->prev = ptr(lastInode());
|
||||||
m_lastRec = iterator;
|
rec->next = retval + size;
|
||||||
|
firstInode()->prev = retval;
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,41 +288,31 @@ void FileStore<FsSize_t>::compress() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
bool FileStore<FsSize_t>::insert(Inode *root, Inode *insertValue, FsSize_t *rootParentPtr) {
|
bool FileStore<FsSize_t>::insert(Inode *root, Inode *insertValue) {
|
||||||
auto cmp = root->m_id > insertValue->m_id;
|
auto retval = false;
|
||||||
if (cmp) {
|
|
||||||
|
if (root->m_id > insertValue->m_id) {
|
||||||
if (root->left) {
|
if (root->left) {
|
||||||
return insert(ptr<Inode*>(root->left), insertValue, &root->left);
|
retval = insert(ptr<Inode*>(root->left), insertValue);
|
||||||
} else {
|
} else {
|
||||||
root->left = ((uint8_t*) insertValue) - m_begin;
|
root->left = ptr(insertValue);
|
||||||
return true;
|
retval = true;
|
||||||
}
|
}
|
||||||
} else if (!cmp) {
|
} else if (root->m_id < insertValue->m_id) {
|
||||||
if (root->right) {
|
if (root->right) {
|
||||||
return insert(ptr<Inode*>(root->right), insertValue, &root->right);
|
retval = insert(ptr<Inode*>(root->right), insertValue);
|
||||||
} else {
|
} else {
|
||||||
root->right = ((uint8_t*) insertValue) - m_begin;
|
root->right = ptr(insertValue);
|
||||||
return true;
|
retval = true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
auto ivAddr = ((uint8_t*) insertValue) - m_begin;
|
|
||||||
if (root->prev) {
|
|
||||||
ptr<Inode*>(root->prev)->next = ivAddr;
|
|
||||||
}
|
|
||||||
if (root->next) {
|
|
||||||
ptr<Inode*>(root->next)->prev = ivAddr;
|
|
||||||
}
|
|
||||||
if (rootParentPtr) {
|
|
||||||
*rootParentPtr = ivAddr;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
FsSize_t FileStore<FsSize_t>::iterator() {
|
FsSize_t FileStore<FsSize_t>::iterator() {
|
||||||
return m_lastRec + ((Inode*) m_begin + m_lastRec)->size();
|
return ptr(lastInode()) + lastInode()->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
@@ -324,6 +320,16 @@ FsSize_t FileStore<FsSize_t>::ptr(void *ptr) {
|
|||||||
return ((uint8_t*) ptr) - m_begin;
|
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>
|
template<typename FsSize_t>
|
||||||
uint8_t FileStore<FsSize_t>::version() {
|
uint8_t FileStore<FsSize_t>::version() {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -331,9 +337,17 @@ uint8_t FileStore<FsSize_t>::version() {
|
|||||||
|
|
||||||
template<typename FsSize_t>
|
template<typename FsSize_t>
|
||||||
uint8_t *FileStore<FsSize_t>::format(uint8_t *buffer, FsSize_t size) {
|
uint8_t *FileStore<FsSize_t>::format(uint8_t *buffer, FsSize_t size) {
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
|
||||||
auto header = (FsHeader*) buffer;
|
auto header = (FsHeader*) buffer;
|
||||||
header->version = FileStore<FsSize_t>::version();
|
header->version = FileStore<FsSize_t>::version();
|
||||||
header->size = size;
|
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;
|
return (uint8_t*) header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-7
@@ -17,15 +17,25 @@ int main() {
|
|||||||
uint32_t err;
|
uint32_t err;
|
||||||
FileStore32::format(volume, size);
|
FileStore32::format(volume, size);
|
||||||
FileStore32 fs(volume, volume + size, &err);
|
FileStore32 fs(volume, volume + size, &err);
|
||||||
|
uint32_t outSize;
|
||||||
|
|
||||||
fs.write(42, (void*) "Hello", 6);
|
if (fs.write(1, (void*) "Hello", 6) ||
|
||||||
|
fs.read(1, (char*) out, &outSize) ||
|
||||||
err = fs.read(42, (char*) out, nullptr);
|
strcmp("Hello", out)) {
|
||||||
if (err) {
|
return 1;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = strcmp("Hello", out);
|
if (fs.write(2, (void*) "World", 6) ||
|
||||||
|
fs.read(2, (char*) out, nullptr) ||
|
||||||
|
strcmp("World", out)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
if (fs.read(1, (char*) out, &outSize) ||
|
||||||
|
strcmp("Hello", out)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user