[ox/fs] Fix a read/write issue in new FileStore
This commit is contained in:
parent
8094e0fe4d
commit
9541287d4a
37
deps/ox/src/ox/__buildinfo/buildinfo.cpp
vendored
Normal file
37
deps/ox/src/ox/__buildinfo/buildinfo.cpp
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2018 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::buildinfo {
|
||||||
|
|
||||||
|
#if defined(OX_USE_STDLIB)
|
||||||
|
const auto UseStdLib = true;
|
||||||
|
#else
|
||||||
|
const auto UseStdLib = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
const auto Debug = true;
|
||||||
|
#else
|
||||||
|
const auto Debug = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(NDEBUG)
|
||||||
|
const auto NDebug = true;
|
||||||
|
#else
|
||||||
|
const auto NDebug = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__BIG_ENDIAN__)
|
||||||
|
const auto BigEndian = true;
|
||||||
|
const auto LittleEndian = false;
|
||||||
|
#else
|
||||||
|
const auto BigEndian = false;
|
||||||
|
const auto LittleEndian = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
17
deps/ox/src/ox/__buildinfo/buildinfo.hpp
vendored
Normal file
17
deps/ox/src/ox/__buildinfo/buildinfo.hpp
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2018 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::buildinfo {
|
||||||
|
|
||||||
|
extern const bool UseStdLib;
|
||||||
|
extern const bool Debug;
|
||||||
|
extern const bool NDebug;
|
||||||
|
extern const bool BigEndian;
|
||||||
|
extern const bool LittleEndian;
|
||||||
|
|
||||||
|
}
|
@ -127,7 +127,7 @@ class FileStoreTemplate: public FileStore {
|
|||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) {
|
FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) {
|
||||||
m_buffSize = buffSize;
|
m_buffSize = buffSize;
|
||||||
m_buffer = static_cast<ox::fs::NodeBuffer<size_t, FileStoreItem<size_t>>*>(buff);
|
m_buffer = reinterpret_cast<ox::fs::NodeBuffer<size_t, FileStoreItem<size_t>>*>(buff);
|
||||||
if (!m_buffer->valid(buffSize)) {
|
if (!m_buffer->valid(buffSize)) {
|
||||||
m_buffSize = 0;
|
m_buffSize = 0;
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
@ -137,10 +137,15 @@ FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) {
|
|||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
Error FileStoreTemplate<size_t>::format() {
|
Error FileStoreTemplate<size_t>::format() {
|
||||||
new (m_buffer) Buffer(m_buffSize);
|
new (m_buffer) Buffer(m_buffSize);
|
||||||
auto data = m_buffer->malloc(sizeof(FileStoreData));
|
auto fsData = m_buffer->malloc(sizeof(FileStoreData));
|
||||||
if (data.valid()) {
|
if (fsData.valid()) {
|
||||||
new (data->data()) FileStoreData;
|
auto data = m_buffer->template dataOf<FileStoreData>(fsData);
|
||||||
return 0;
|
if (data.valid()) {
|
||||||
|
new (data) FileStoreData;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::format::fail") << "Could not read data section of FileStoreData";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -175,6 +180,7 @@ Error FileStoreTemplate<size_t>::decLinks(InodeId_t id) {
|
|||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSize, uint8_t fileType) {
|
Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSize, uint8_t fileType) {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::write") << "Attempting to write to inode" << id;
|
||||||
auto existing = find(id);
|
auto existing = find(id);
|
||||||
// TODO: try compacting if unable to write
|
// TODO: try compacting if unable to write
|
||||||
if (canWrite(existing, dataSize)) {
|
if (canWrite(existing, dataSize)) {
|
||||||
@ -192,18 +198,19 @@ Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSi
|
|||||||
new (dest) FileStoreItem<size_t>(dataSize);
|
new (dest) FileStoreItem<size_t>(dataSize);
|
||||||
dest->id = id;
|
dest->id = id;
|
||||||
dest->fileType = fileType;
|
dest->fileType = fileType;
|
||||||
auto destData = dest->data();
|
auto destData = m_buffer->template dataOf<uint8_t>(dest);
|
||||||
if (destData.valid()) {
|
if (destData.valid()) {
|
||||||
ox_memcpy(destData, data, dest->size());
|
ox_memcpy(destData, data, dest->size());
|
||||||
auto fsData = fileStoreData();
|
auto fsData = fileStoreData();
|
||||||
if (fsData) {
|
if (fsData) {
|
||||||
auto root = m_buffer->ptr(fsData->rootNode);
|
auto root = m_buffer->ptr(fsData->rootNode);
|
||||||
if (root.valid()) {
|
if (root.valid()) {
|
||||||
oxTrace("ox::fs::FileStoreTemplate::write") << "Placing" << dest->id << "on" << root->id;
|
oxTrace("ox::fs::FileStoreTemplate::write") << "Placing" << dest->id << "on" << root->id << "at" << destData.offset();
|
||||||
return placeItem(root, dest);
|
return placeItem(root, dest);
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::FileStoreTemplate::write") << "Initializing root inode.";
|
oxTrace("ox::fs::FileStoreTemplate::write") << "Initializing root inode with offset of" << dest.offset()
|
||||||
fsData->rootNode = dest;
|
<< "and data size of" << destData.size();
|
||||||
|
fsData->rootNode = dest.offset();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -218,16 +225,26 @@ Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSi
|
|||||||
|
|
||||||
template<typename size_t>
|
template<typename size_t>
|
||||||
Error FileStoreTemplate<size_t>::read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) {
|
Error FileStoreTemplate<size_t>::read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read") << "Attempting to read from inode" << id;
|
||||||
auto src = find(id);
|
auto src = find(id);
|
||||||
if (src.valid()) {
|
if (src.valid()) {
|
||||||
auto srcData = src->data();
|
auto srcData = m_buffer->template dataOf<uint8_t>(src);
|
||||||
|
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::found") << id << "found at"<< src.offset()
|
||||||
|
<< "with data section at" << srcData.offset();
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::outSize") << srcData.offset() << srcData.size() << dataSize;
|
||||||
if (srcData.valid() && srcData.size() <= dataSize) {
|
if (srcData.valid() && srcData.size() <= dataSize) {
|
||||||
ox_memcpy(data, srcData, srcData.size());
|
ox_memcpy(data, srcData, srcData.size());
|
||||||
if (size) {
|
if (size) {
|
||||||
*size = src.size();
|
*size = src.size();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::fail") << "Could not read data section of item:" << id;
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::fail") << "Item data section size:" << srcData.size();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::fail") << "Could not find requested item:" << id;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -238,15 +255,21 @@ Error FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart, FsSize_t
|
|||||||
if (src.valid()) {
|
if (src.valid()) {
|
||||||
auto srcData = src->data();
|
auto srcData = src->data();
|
||||||
if (srcData.valid()) {
|
if (srcData.valid()) {
|
||||||
auto sub = srcData.subPtr(readStart, readSize);
|
auto sub = srcData.template subPtr<uint8_t>(readStart, readSize);
|
||||||
if (sub.valid()) {
|
if (sub.valid()) {
|
||||||
ox_memcpy(data, sub, sub.size());
|
ox_memcpy(data, sub, sub.size());
|
||||||
if (size) {
|
if (size) {
|
||||||
*size = sub.size();
|
*size = sub.size();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::fail") << "Could not read requested data sub-section of item:" << id;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::fail") << "Could not read data section of item:" << id;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::read::fail") << "Could not find requested item:" << id;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -266,7 +289,7 @@ int FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart,
|
|||||||
// copying to final destination
|
// copying to final destination
|
||||||
T tmp;
|
T tmp;
|
||||||
for (size_t i = 0; i < sizeof(T); i++) {
|
for (size_t i = 0; i < sizeof(T); i++) {
|
||||||
*reinterpret_cast<uint8_t*>(&tmp)[i] = *(reinterpret_cast<uint8_t*>(sub.get()) + i);
|
*(reinterpret_cast<uint8_t*>(&tmp)[i]) = *(reinterpret_cast<uint8_t*>(sub.get()) + i);
|
||||||
}
|
}
|
||||||
*(data + i) = tmp;
|
*(data + i) = tmp;
|
||||||
}
|
}
|
||||||
@ -327,7 +350,7 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
|
|||||||
if (item->id > root->id) {
|
if (item->id > root->id) {
|
||||||
auto right = m_buffer->ptr(root->right);
|
auto right = m_buffer->ptr(root->right);
|
||||||
if (!right.valid() || right->id == item->id) {
|
if (!right.valid() || right->id == item->id) {
|
||||||
root->right = root;
|
root->right = root.offset();
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return placeItem(right, item, depth + 1);
|
return placeItem(right, item, depth + 1);
|
||||||
@ -335,7 +358,7 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
|
|||||||
} else if (item->id < root->id) {
|
} else if (item->id < root->id) {
|
||||||
auto left = m_buffer->ptr(root->left);
|
auto left = m_buffer->ptr(root->left);
|
||||||
if (!left.valid() || left->id == item->id) {
|
if (!left.valid() || left->id == item->id) {
|
||||||
root->left = root;
|
root->left = root.offset();
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return placeItem(left, item, depth + 1);
|
return placeItem(left, item, depth + 1);
|
||||||
@ -382,6 +405,8 @@ typename FileStoreTemplate<size_t>::ItemPtr FileStoreTemplate<size_t>::find(Item
|
|||||||
} else {
|
} else {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
oxTrace("ox::fs::FileStoreTemplate::find::fail") << "item invalid";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::FileStoreTemplate::find::fail") << "Excessive recursion depth, stopping before stack overflow. Search for:" << id;
|
oxTrace("ox::fs::FileStoreTemplate::find::fail") << "Excessive recursion depth, stopping before stack overflow. Search for:" << id;
|
||||||
|
65
deps/ox/src/ox/fs/filestore/nodebuffer.hpp
vendored
65
deps/ox/src/ox/fs/filestore/nodebuffer.hpp
vendored
@ -24,30 +24,7 @@ class __attribute__((packed)) NodeBuffer {
|
|||||||
ox::LittleEndian<size_t> firstItem = 0;
|
ox::LittleEndian<size_t> firstItem = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ItemPtr: public ox::fs::Ptr<Item, size_t, sizeof(Header)> {
|
using ItemPtr = ox::fs::Ptr<Item, size_t, sizeof(Header)>;
|
||||||
inline ItemPtr() = default;
|
|
||||||
|
|
||||||
inline ItemPtr(std::nullptr_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ItemPtr(void *dataStart, size_t dataSize, size_t itemOffset, size_t size):
|
|
||||||
Ptr<Item, size_t, sizeof(Header)>(dataStart, dataSize, itemOffset, size) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ItemPtr(void *dataStart, size_t dataSize, size_t itemOffset) {
|
|
||||||
// make sure this can be read as an Item, and then use Item::size for the size
|
|
||||||
auto itemSpace = dataSize - itemOffset;
|
|
||||||
auto item = reinterpret_cast<Item*>(static_cast<uint8_t*>(dataStart) + itemOffset);
|
|
||||||
if (itemOffset >= sizeof(Header) and
|
|
||||||
itemOffset < dataSize - sizeof(Item) and
|
|
||||||
itemSpace >= static_cast<size_t>(sizeof(Item)) and
|
|
||||||
itemSpace >= item->fullSize()) {
|
|
||||||
this->init(dataStart, dataSize, itemOffset, sizeof(item) + item->fullSize());
|
|
||||||
} else {
|
|
||||||
this->init(dataStart, dataSize, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Header m_header;
|
Header m_header;
|
||||||
|
|
||||||
@ -60,6 +37,12 @@ class __attribute__((packed)) NodeBuffer {
|
|||||||
|
|
||||||
ItemPtr lastItem();
|
ItemPtr lastItem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the data section of the given item
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr);
|
||||||
|
|
||||||
ItemPtr prev(Item *item);
|
ItemPtr prev(Item *item);
|
||||||
|
|
||||||
ItemPtr next(Item *item);
|
ItemPtr next(Item *item);
|
||||||
@ -115,6 +98,14 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename size_t, typename Item>
|
||||||
|
template<typename T>
|
||||||
|
Ptr<T, size_t, sizeof(Item)> NodeBuffer<size_t, Item>::dataOf(ItemPtr ip) {
|
||||||
|
auto out = ip.template subPtr<T>(sizeof(Item));
|
||||||
|
oxAssert(out.size() == ip.size() - sizeof(Item), "Sub Ptr has invalid size.");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename size_t, typename Item>
|
template<typename size_t, typename Item>
|
||||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) {
|
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) {
|
||||||
return ptr(item->prev);
|
return ptr(item->prev);
|
||||||
@ -126,8 +117,18 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename size_t, typename Item>
|
template<typename size_t, typename Item>
|
||||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t offset) {
|
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) {
|
||||||
return ItemPtr(this, m_header.size, offset);
|
// make sure this can be read as an Item, and then use Item::size for the size
|
||||||
|
auto itemSpace = m_header.size - itemOffset;
|
||||||
|
auto item = reinterpret_cast<Item*>(reinterpret_cast<uint8_t*>(this) + itemOffset);
|
||||||
|
if (itemOffset >= sizeof(Header) and
|
||||||
|
itemOffset < m_header.size - sizeof(Item) and
|
||||||
|
itemSpace >= static_cast<size_t>(sizeof(Item)) and
|
||||||
|
itemSpace >= item->fullSize()) {
|
||||||
|
return ItemPtr(this, m_header.size, itemOffset, item->fullSize());
|
||||||
|
} else {
|
||||||
|
return ItemPtr(this, m_header.size, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename size_t, typename Item>
|
template<typename size_t, typename Item>
|
||||||
@ -151,18 +152,18 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size
|
|||||||
new (out) Item(size);
|
new (out) Item(size);
|
||||||
|
|
||||||
auto first = firstItem();
|
auto first = firstItem();
|
||||||
out->next = first;
|
out->next = first.offset();
|
||||||
if (first.valid()) {
|
if (first.valid()) {
|
||||||
first->prev = out;
|
first->prev = out.offset();
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid first element pointer.";
|
oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid first element pointer.";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto last = lastItem();
|
auto last = lastItem();
|
||||||
out->prev = last;
|
out->prev = last.offset();
|
||||||
if (last.valid()) {
|
if (last.valid()) {
|
||||||
last->next = out;
|
last->next = out.offset();
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid last element pointer.";
|
oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid last element pointer.";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -182,12 +183,12 @@ void NodeBuffer<size_t, Item>::free(ItemPtr item) {
|
|||||||
auto prev = this->prev(item);
|
auto prev = this->prev(item);
|
||||||
auto next = this->next(item);
|
auto next = this->next(item);
|
||||||
if (prev.valid()) {
|
if (prev.valid()) {
|
||||||
prev->next = next;
|
prev->next = next.offset();
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer.";
|
oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer.";
|
||||||
}
|
}
|
||||||
if (next.valid()) {
|
if (next.valid()) {
|
||||||
next->prev = prev;
|
next->prev = prev.offset();
|
||||||
} else {
|
} else {
|
||||||
oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer.";
|
oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer.";
|
||||||
}
|
}
|
||||||
|
50
deps/ox/src/ox/fs/filestore/ptr.hpp
vendored
50
deps/ox/src/ox/fs/filestore/ptr.hpp
vendored
@ -10,8 +10,7 @@
|
|||||||
|
|
||||||
#include <ox/std/std.hpp>
|
#include <ox/std/std.hpp>
|
||||||
|
|
||||||
namespace ox {
|
namespace ox::fs {
|
||||||
namespace fs {
|
|
||||||
|
|
||||||
template<typename T, typename size_t, size_t minOffset = 1>
|
template<typename T, typename size_t, size_t minOffset = 1>
|
||||||
class Ptr {
|
class Ptr {
|
||||||
@ -49,11 +48,11 @@ class Ptr {
|
|||||||
|
|
||||||
inline T &operator*() const;
|
inline T &operator*() const;
|
||||||
|
|
||||||
inline Ptr subPtr(size_t offset, size_t size);
|
template<typename SubT>
|
||||||
|
inline Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size);
|
||||||
|
|
||||||
inline Ptr subPtr(size_t offset);
|
template<typename SubT>
|
||||||
|
inline Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset);
|
||||||
inline void init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,7 +62,15 @@ inline Ptr<T, size_t, minOffset>::Ptr(std::nullptr_t) {
|
|||||||
|
|
||||||
template<typename T, typename size_t, size_t minOffset>
|
template<typename T, typename size_t, size_t minOffset>
|
||||||
inline Ptr<T, size_t, minOffset>::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) {
|
inline Ptr<T, size_t, minOffset>::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) {
|
||||||
init(dataStart, dataSize, itemStart, itemSize);
|
// do some sanity checks before assuming this is valid
|
||||||
|
if (itemSize >= sizeof(T) and
|
||||||
|
dataStart and
|
||||||
|
itemStart >= minOffset and
|
||||||
|
itemStart + itemSize <= dataSize) {
|
||||||
|
m_dataStart = reinterpret_cast<uint8_t*>(dataStart);
|
||||||
|
m_itemOffset = itemStart;
|
||||||
|
m_itemSize = itemSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename size_t, size_t minOffset>
|
template<typename T, typename size_t, size_t minOffset>
|
||||||
@ -118,32 +125,21 @@ template<typename T, typename size_t, size_t minOffset>
|
|||||||
inline T &Ptr<T, size_t, minOffset>::operator*() const {
|
inline T &Ptr<T, size_t, minOffset>::operator*() const {
|
||||||
oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())");
|
oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())");
|
||||||
oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
|
oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
|
||||||
return *static_cast<T>(this);
|
return *reinterpret_cast<T*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename size_t, size_t minOffset>
|
template<typename T, typename size_t, size_t minOffset>
|
||||||
inline Ptr<T, size_t, minOffset> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) {
|
template<typename SubT>
|
||||||
auto dataSize = ((m_dataStart + offset) - m_dataStart) + m_itemSize;
|
inline Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) {
|
||||||
return Ptr<T, size_t, minOffset>(m_dataStart, dataSize, offset, size);
|
auto out = Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size);
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename size_t, size_t minOffset>
|
template<typename T, typename size_t, size_t minOffset>
|
||||||
inline Ptr<T, size_t, minOffset> Ptr<T, size_t, minOffset>::subPtr(size_t offset) {
|
template<typename SubT>
|
||||||
return subPtr(offset, m_itemSize - offset);
|
inline Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) {
|
||||||
}
|
oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset);
|
||||||
|
return subPtr<SubT>(offset, m_itemSize - offset);
|
||||||
template<typename T, typename size_t, size_t minOffset>
|
|
||||||
inline void Ptr<T, size_t, minOffset>::init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize) {
|
|
||||||
// do some sanity checks before assuming this is valid
|
|
||||||
if (itemSize >= sizeof(T) and
|
|
||||||
dataStart and
|
|
||||||
itemStart >= minOffset and
|
|
||||||
itemStart + itemSize <= dataSize) {
|
|
||||||
m_dataStart = static_cast<uint8_t*>(dataStart);
|
|
||||||
m_itemOffset = itemStart;
|
|
||||||
m_itemSize = itemSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
29
deps/ox/src/ox/fs/test/tests.cpp
vendored
29
deps/ox/src/ox/fs/test/tests.cpp
vendored
@ -332,6 +332,19 @@ map<string, int(*)(string)> tests = {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Ptr::subPtr",
|
||||||
|
[](string) {
|
||||||
|
constexpr auto buffLen = 5000;
|
||||||
|
uint8_t buff[buffLen];
|
||||||
|
ox::fs::Ptr<uint8_t, uint32_t> p(buff, buffLen, 500, 500);
|
||||||
|
oxAssert(p.valid(), "Ptr::subPtr: Ptr p is invalid.");
|
||||||
|
|
||||||
|
auto subPtr = p.subPtr<uint64_t>(50);
|
||||||
|
oxAssert(subPtr.valid(), "Ptr::subPtr: Ptr subPtr is invalid.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"NodeBuffer::insert",
|
"NodeBuffer::insert",
|
||||||
[](string) {
|
[](string) {
|
||||||
@ -339,7 +352,8 @@ map<string, int(*)(string)> tests = {
|
|||||||
constexpr auto buffLen = 5000;
|
constexpr auto buffLen = 5000;
|
||||||
uint8_t buff[buffLen];
|
uint8_t buff[buffLen];
|
||||||
auto list = new (buff) ox::fs::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
|
auto list = new (buff) ox::fs::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
|
||||||
err |= !(list->malloc(50).valid());
|
oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 1 failed");
|
||||||
|
oxAssert(list->malloc(50).valid(), "NodeBuffer::insert: malloc 2 failed");
|
||||||
auto first = list->firstItem();
|
auto first = list->firstItem();
|
||||||
oxAssert(first.valid(), "NodeBuffer::insert: Could not access first item");
|
oxAssert(first.valid(), "NodeBuffer::insert: Could not access first item");
|
||||||
oxAssert(first->size() == 50, "NodeBuffer::insert: First item size invalid");
|
oxAssert(first->size() == 50, "NodeBuffer::insert: First item size invalid");
|
||||||
@ -351,15 +365,20 @@ map<string, int(*)(string)> tests = {
|
|||||||
[](string) {
|
[](string) {
|
||||||
constexpr auto buffLen = 5000;
|
constexpr auto buffLen = 5000;
|
||||||
constexpr auto str1 = "Hello, World!";
|
constexpr auto str1 = "Hello, World!";
|
||||||
constexpr auto str1Len = ox_strlen(str1);
|
constexpr auto str1Len = ox_strlen(str1) + 1;
|
||||||
constexpr auto str2 = "Hello, Moon!";
|
constexpr auto str2 = "Hello, Moon!";
|
||||||
constexpr auto str2Len = ox_strlen(str2);
|
constexpr auto str2Len = ox_strlen(str2) + 1;
|
||||||
uint8_t buff[buffLen];
|
uint8_t buff[buffLen];
|
||||||
auto list = new (buff) ox::fs::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
|
auto list = new (buff) ox::fs::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
|
||||||
ox::fs::FileStore32 fileStore(list, buffLen);
|
ox::fs::FileStore32 fileStore(list, buffLen);
|
||||||
oxAssert(fileStore.format() == 0, "FileStore::format failed.");
|
oxAssert(fileStore.format() == 0, "FileStore::format failed.");
|
||||||
oxAssert(fileStore.write(4, (void*) str1, str1Len, 1) == 0, "FileStore::write 1 failed.");
|
oxAssert(fileStore.write(4, const_cast<char*>(str1), str1Len, 1) == 0, "FileStore::write 1 failed.");
|
||||||
oxAssert(fileStore.write(5, (void*) str2, str2Len, 1) == 0, "FileStore::write 2 failed.");
|
oxAssert(fileStore.write(5, const_cast<char*>(str2), str2Len, 1) == 0, "FileStore::write 2 failed.");
|
||||||
|
|
||||||
|
char str1Read[str1Len];
|
||||||
|
size_t str1ReadSize = 0;
|
||||||
|
oxAssert(fileStore.read(4, reinterpret_cast<void*>(str1Read), str1Len, &str1ReadSize) == 0, "FileStore::read 1 failed.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user