Add missing check to ItemPtr and instantiate FileStore32 in FS library
This commit is contained in:
parent
9447967f12
commit
127c6525f7
3
deps/ox/src/ox/fs/CMakeLists.txt
vendored
3
deps/ox/src/ox/fs/CMakeLists.txt
vendored
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
add_library(
|
||||
OxFS
|
||||
filestore.cpp
|
||||
filestore/filestoretemplate.cpp
|
||||
filesystem/filesystem.cpp
|
||||
filesystem/pathiterator.cpp
|
||||
)
|
||||
@ -24,6 +26,7 @@ if(OX_BUILD_EXEC STREQUAL "ON")
|
||||
oxfstool
|
||||
OxFS
|
||||
OxTrace
|
||||
OxMetalClaw
|
||||
OxStd
|
||||
)
|
||||
endif()
|
||||
|
2
deps/ox/src/ox/fs/filestore.cpp
vendored
2
deps/ox/src/ox/fs/filestore.cpp
vendored
@ -11,7 +11,7 @@
|
||||
namespace ox {
|
||||
|
||||
template class FileStore<FileStoreHeader<uint16_t, uint16_t>>;
|
||||
template class FileStore<FileStoreHeader<uint32_t, uint16_t>>;
|
||||
template class FileStore<FileStoreHeader<uint32_t, uint32_t>>;
|
||||
template class FileStore<FileStoreHeader<uint64_t, uint64_t>>;
|
||||
|
||||
}
|
||||
|
2
deps/ox/src/ox/fs/filestore.hpp
vendored
2
deps/ox/src/ox/fs/filestore.hpp
vendored
@ -917,7 +917,7 @@ uint8_t *FileStore<Header>::format(uint8_t *buffer, typename Header::FsSize_t si
|
||||
}
|
||||
|
||||
extern template class FileStore<FileStoreHeader<uint16_t, uint16_t>>;
|
||||
extern template class FileStore<FileStoreHeader<uint32_t, uint16_t>>;
|
||||
extern template class FileStore<FileStoreHeader<uint32_t, uint32_t>>;
|
||||
extern template class FileStore<FileStoreHeader<uint64_t, uint64_t>>;
|
||||
|
||||
typedef FileStore<FileStoreHeader<uint16_t, uint16_t>> FileStore16;
|
||||
|
9
deps/ox/src/ox/fs/filestore/filestore.hpp
vendored
9
deps/ox/src/ox/fs/filestore/filestore.hpp
vendored
@ -13,6 +13,7 @@
|
||||
namespace ox::fs {
|
||||
|
||||
using InodeId_t = uintptr_t;
|
||||
using FsSize_t = uintptr_t;
|
||||
|
||||
class FileStore {
|
||||
|
||||
@ -28,19 +29,19 @@ class FileStore {
|
||||
|
||||
virtual Error setSize(InodeId_t size) = 0;
|
||||
|
||||
virtual Error write(InodeId_t id, void *data, InodeId_t dataLen, uint8_t fileType = 0) = 0;
|
||||
virtual Error write(InodeId_t id, void *data, FsSize_t dataLen, uint8_t fileType = 0) = 0;
|
||||
|
||||
virtual Error incLinks(InodeId_t id) = 0;
|
||||
|
||||
virtual Error decLinks(InodeId_t id) = 0;
|
||||
|
||||
virtual Error read(InodeId_t id, void *data, InodeId_t *size) = 0;
|
||||
virtual Error read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) = 0;
|
||||
|
||||
virtual Error read(InodeId_t id, InodeId_t readStart, InodeId_t readSize, void *data, InodeId_t *size) = 0;
|
||||
virtual Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size) = 0;
|
||||
|
||||
virtual StatInfo stat(InodeId_t id) = 0;
|
||||
|
||||
virtual InodeId_t spaceNeeded(InodeId_t size) = 0;
|
||||
virtual InodeId_t spaceNeeded(FsSize_t size) = 0;
|
||||
|
||||
virtual InodeId_t size() = 0;
|
||||
|
||||
|
15
deps/ox/src/ox/fs/filestore/filestoretemplate.cpp
vendored
Normal file
15
deps/ox/src/ox/fs/filestore/filestoretemplate.cpp
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#include "filestoretemplate.hpp"
|
||||
|
||||
namespace ox::fs {
|
||||
|
||||
template class FileStoreTemplate<uint32_t>;
|
||||
|
||||
}
|
@ -29,18 +29,20 @@ struct __attribute__((packed)) FileStoreItem: public Item<size_t> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename size_t>
|
||||
class FileStoreTemplate: public FileStore {
|
||||
|
||||
private:
|
||||
using ItemPtr = typename ox::fs::NodeBuffer<size_t, FileStoreItem<uint32_t>>::ItemPtr;
|
||||
using ItemPtr = typename ox::fs::NodeBuffer<size_t, FileStoreItem<size_t>>::ItemPtr;
|
||||
using Buffer = ox::fs::NodeBuffer<size_t, FileStoreItem<size_t>>;
|
||||
|
||||
struct __attribute__((packed)) FileStoreData {
|
||||
ox::LittleEndian<size_t> rootNode = sizeof(NodeBuffer<size_t, FileStoreItem<uint32_t>>);
|
||||
ox::LittleEndian<size_t> rootNode = sizeof(NodeBuffer<size_t, FileStoreItem<size_t>>);
|
||||
};
|
||||
|
||||
size_t m_buffSize = 0;
|
||||
ox::fs::NodeBuffer<size_t, FileStoreItem<uint32_t>> *m_buffer = nullptr;
|
||||
Buffer *m_buffer = nullptr;
|
||||
|
||||
public:
|
||||
FileStoreTemplate(void *buff, size_t buffSize);
|
||||
@ -53,15 +55,15 @@ class FileStoreTemplate: public FileStore {
|
||||
|
||||
Error decLinks(InodeId_t id);
|
||||
|
||||
Error write(InodeId_t id, void *data, InodeId_t dataLen, uint8_t fileType = 0);
|
||||
Error write(InodeId_t id, void *data, FsSize_t dataLen, uint8_t fileType = 0);
|
||||
|
||||
Error read(InodeId_t id, void *data, InodeId_t *size);
|
||||
Error read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size);
|
||||
|
||||
Error read(InodeId_t id, InodeId_t readStart, InodeId_t readSize, void *data, InodeId_t *size);
|
||||
Error read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size);
|
||||
|
||||
StatInfo stat(InodeId_t id);
|
||||
|
||||
InodeId_t spaceNeeded(InodeId_t size);
|
||||
InodeId_t spaceNeeded(FsSize_t size);
|
||||
|
||||
InodeId_t size();
|
||||
|
||||
@ -74,7 +76,7 @@ class FileStoreTemplate: public FileStore {
|
||||
* Places the given Item at the given ID. If it already exists, the
|
||||
* existing value will be overwritten.
|
||||
*/
|
||||
void placeItem(ItemPtr root, ItemPtr item);
|
||||
Error placeItem(ItemPtr root, ItemPtr item);
|
||||
|
||||
/**
|
||||
* Finds the parent an inode by its ID.
|
||||
@ -103,7 +105,7 @@ class FileStoreTemplate: public FileStore {
|
||||
template<typename size_t>
|
||||
FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) {
|
||||
m_buffSize = buffSize;
|
||||
m_buffer = static_cast<ox::fs::NodeBuffer<size_t, FileStoreItem<uint32_t>>*>(buff);
|
||||
m_buffer = static_cast<ox::fs::NodeBuffer<size_t, FileStoreItem<size_t>>*>(buff);
|
||||
if (!m_buffer->valid(buffSize)) {
|
||||
m_buffSize = 0;
|
||||
m_buffer = nullptr;
|
||||
@ -112,7 +114,7 @@ FileStoreTemplate<size_t>::FileStoreTemplate(void *buff, size_t buffSize) {
|
||||
|
||||
template<typename size_t>
|
||||
Error FileStoreTemplate<size_t>::format() {
|
||||
new (m_buffer) NodeBuffer<size_t, FileStoreItem<uint32_t>>(m_buffSize);
|
||||
new (m_buffer) Buffer(m_buffSize);
|
||||
auto data = m_buffer->malloc(sizeof(FileStoreData));
|
||||
if (data.valid()) {
|
||||
new (data->data()) FileStoreData;
|
||||
@ -150,7 +152,7 @@ Error FileStoreTemplate<size_t>::decLinks(InodeId_t id) {
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, InodeId_t dataSize, uint8_t fileType) {
|
||||
Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, FsSize_t dataSize, uint8_t fileType) {
|
||||
auto existing = find(id);
|
||||
if (canWrite(existing, dataSize)) {
|
||||
// delete the old node if it exists
|
||||
@ -164,22 +166,39 @@ Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, InodeId_t dataS
|
||||
// if first malloc failed, compact and try again
|
||||
dest = m_buffer->malloc(dataSize);
|
||||
if (dest.valid()) {
|
||||
new (dest) FileStoreItem(dataSize);
|
||||
new (dest) FileStoreItem<size_t>(dataSize);
|
||||
dest->id = id;
|
||||
dest->fileType = fileType;
|
||||
ox_memcpy(dest->data(), data, dest->size());
|
||||
auto root = rootInode();
|
||||
if (root.valid()) {
|
||||
placeItem(root, dest);
|
||||
return placeItem(root, dest);
|
||||
} else {
|
||||
auto fsData = fileStoreData();
|
||||
if (fsData) {
|
||||
fsData->rootNode = dest;
|
||||
return 0;
|
||||
} else {
|
||||
m_buffer->free(dest);
|
||||
oxTrace("ox::fs::FileStoreTemplate::write::fail") << "Could not place item due to absence of FileStore header.";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
Error FileStoreTemplate<size_t>::read(InodeId_t id, void *data, FsSize_t dataSize, FsSize_t *size) {
|
||||
auto src = find(id);
|
||||
if (src.valid() && src.size() <= dataSize) {
|
||||
auto srcData = src->data();
|
||||
if (srcData.valid()) {
|
||||
ox_memcpy(data, srcData, src.size());
|
||||
if (size) {
|
||||
*size = src.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -187,12 +206,11 @@ Error FileStoreTemplate<size_t>::write(InodeId_t id, void *data, InodeId_t dataS
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
Error FileStoreTemplate<size_t>::read(InodeId_t id, void *data, InodeId_t *size) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
Error FileStoreTemplate<size_t>::read(InodeId_t id, InodeId_t readStart, InodeId_t readSize, void *data, InodeId_t *size) {
|
||||
Error FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t /* readStart */, FsSize_t /* readSize */, void * /* data */, FsSize_t * /* size */) {
|
||||
auto src = find(id);
|
||||
if (src.valid()) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -211,7 +229,7 @@ typename FileStoreTemplate<size_t>::StatInfo FileStoreTemplate<size_t>::stat(Ino
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
InodeId_t FileStoreTemplate<size_t>::spaceNeeded(InodeId_t size) {
|
||||
InodeId_t FileStoreTemplate<size_t>::spaceNeeded(FsSize_t size) {
|
||||
return m_buffer->spaceNeeded(size);
|
||||
}
|
||||
|
||||
@ -238,22 +256,25 @@ typename FileStoreTemplate<size_t>::FileStoreData *FileStoreTemplate<size_t>::fi
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
void FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item) {
|
||||
Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item) {
|
||||
if (item->id > root->id) {
|
||||
auto right = m_buffer->ptr(root->right);
|
||||
if (right.valid()) {
|
||||
placeItem(right, item);
|
||||
} else {
|
||||
if (!right.valid() || right->id == item->id) {
|
||||
root->right = root;
|
||||
return 0;
|
||||
} else {
|
||||
return placeItem(right, item);
|
||||
}
|
||||
} else if (item->id < root->id) {
|
||||
auto left = m_buffer->ptr(root->left);
|
||||
if (left.valid()) {
|
||||
placeItem(left, item);
|
||||
} else {
|
||||
if (!left.valid() || left->id == item->id) {
|
||||
root->left = root;
|
||||
return 0;
|
||||
} else {
|
||||
return placeItem(left, item);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
@ -309,14 +330,21 @@ typename FileStoreTemplate<size_t>::ItemPtr FileStoreTemplate<size_t>::find(size
|
||||
*/
|
||||
template<typename size_t>
|
||||
typename FileStoreTemplate<size_t>::ItemPtr FileStoreTemplate<size_t>::rootInode() {
|
||||
return m_buffer->ptr(fileStoreData()->rootNode);
|
||||
auto fsData = fileStoreData();
|
||||
if (fsData) {
|
||||
return m_buffer->ptr(fsData->rootNode);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename size_t>
|
||||
bool FileStoreTemplate<size_t>::canWrite(ItemPtr existing, size_t size) {
|
||||
return existing.size() >= size || m_buffer->spaceNeeded(size) >= m_buffer->available();
|
||||
return existing.size() >= size || m_buffer->spaceNeeded(size) <= m_buffer->available();
|
||||
}
|
||||
|
||||
extern template class FileStoreTemplate<uint32_t>;
|
||||
|
||||
using FileStore16 = FileStoreTemplate<uint16_t>;
|
||||
using FileStore32 = FileStoreTemplate<uint32_t>;
|
||||
using FileStore64 = FileStoreTemplate<uint64_t>;
|
||||
|
32
deps/ox/src/ox/fs/filestore/nodebuffer.hpp
vendored
32
deps/ox/src/ox/fs/filestore/nodebuffer.hpp
vendored
@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/trace/trace.hpp>
|
||||
|
||||
#include "ptr.hpp"
|
||||
|
||||
namespace ox::fs {
|
||||
@ -37,6 +39,7 @@ class __attribute__((packed)) NodeBuffer {
|
||||
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());
|
||||
@ -127,11 +130,6 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t
|
||||
return ItemPtr(this, m_header.size, offset);
|
||||
}
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(void *item) {
|
||||
return ItemPtr(this, m_header.size, reinterpret_cast<size_t>(static_cast<uint8_t*>(item) - static_cast<uint8_t*>(this)));
|
||||
}
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size_t size) {
|
||||
size += sizeof(Item);
|
||||
@ -142,15 +140,23 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size
|
||||
auto out = ItemPtr(this, m_header.size, m_header.firstItem, size);
|
||||
if (out.valid()) {
|
||||
new (out) Item(size);
|
||||
|
||||
auto first = firstItem();
|
||||
auto last = lastItem();
|
||||
out->next = first;
|
||||
out->prev = last;
|
||||
if (first.valid()) {
|
||||
first->prev = out;
|
||||
} else {
|
||||
oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid first element pointer.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto last = lastItem();
|
||||
out->prev = last;
|
||||
if (last.valid()) {
|
||||
last->next = out;
|
||||
} else {
|
||||
oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid last element pointer.";
|
||||
return nullptr;
|
||||
}
|
||||
m_header.bytesUsed += out.size();
|
||||
}
|
||||
@ -165,9 +171,13 @@ void NodeBuffer<size_t, Item>::free(ItemPtr item) {
|
||||
auto next = this->next(item);
|
||||
if (prev.valid()) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer.";
|
||||
}
|
||||
if (next.valid()) {
|
||||
next->prev = prev;
|
||||
} else {
|
||||
oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer.";
|
||||
}
|
||||
m_header.bytesUsed -= item.size();
|
||||
}
|
||||
@ -206,12 +216,12 @@ size_t NodeBuffer<size_t, Item>::spaceNeeded(size_t size) {
|
||||
template<typename size_t, typename Item>
|
||||
void NodeBuffer<size_t, Item>::compact(void (*cb)(ItemPtr)) {
|
||||
auto src = firstItem();
|
||||
auto dest = data();
|
||||
auto dest = ptr(sizeof(*this));
|
||||
while (src.valid() && dest.valid()) {
|
||||
// move node
|
||||
ox_memcpy(dest, src, src.size());
|
||||
if (cb) {
|
||||
cb(ptr(dest));
|
||||
cb(dest);
|
||||
}
|
||||
// update surrounding nodes
|
||||
auto prev = ptr(dest->next);
|
||||
@ -224,13 +234,13 @@ void NodeBuffer<size_t, Item>::compact(void (*cb)(ItemPtr)) {
|
||||
}
|
||||
// update iterators
|
||||
src = ptr(dest->next);
|
||||
dest += ptr(dest).size();
|
||||
dest = ptr(dest.offset() + dest.size());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
uint8_t *NodeBuffer<size_t, Item>::data() {
|
||||
return reinterpret_cast<uint8_t*>(this + 1);
|
||||
return reinterpret_cast<uint8_t*>(ptr(sizeof(*this)).get());
|
||||
}
|
||||
|
||||
|
||||
|
1
deps/ox/src/ox/fs/filestore/ptr.hpp
vendored
1
deps/ox/src/ox/fs/filestore/ptr.hpp
vendored
@ -49,7 +49,6 @@ class Ptr {
|
||||
|
||||
inline T &operator*() const;
|
||||
|
||||
protected:
|
||||
inline void init(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize);
|
||||
|
||||
};
|
||||
|
4
deps/ox/src/ox/fs/filesystem/filesystem.cpp
vendored
4
deps/ox/src/ox/fs/filesystem/filesystem.cpp
vendored
@ -10,6 +10,10 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template class FileSystemTemplate<FileStore16, OxFS_16>;
|
||||
template class FileSystemTemplate<FileStore32, OxFS_32>;
|
||||
template class FileSystemTemplate<FileStore64, OxFS_64>;
|
||||
|
||||
FileSystem *createFileSystem(uint8_t *buff, size_t buffSize, bool ownsBuff) {
|
||||
auto version = ((FileStore16*) buff)->version();
|
||||
auto type = ((FileStore16*) buff)->fsType();
|
||||
|
4
deps/ox/src/ox/fs/test/CMakeLists.txt
vendored
4
deps/ox/src/ox/fs/test/CMakeLists.txt
vendored
@ -25,6 +25,7 @@ target_link_libraries(
|
||||
OxFS
|
||||
OxStd
|
||||
OxTrace
|
||||
OxMetalClaw
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@ -32,6 +33,7 @@ target_link_libraries(
|
||||
OxFS
|
||||
OxStd
|
||||
OxTrace
|
||||
OxMetalClaw
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@ -39,6 +41,7 @@ target_link_libraries(
|
||||
OxFS
|
||||
OxStd
|
||||
OxTrace
|
||||
OxMetalClaw
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@ -46,6 +49,7 @@ target_link_libraries(
|
||||
OxFS
|
||||
OxStd
|
||||
OxTrace
|
||||
OxMetalClaw
|
||||
)
|
||||
|
||||
add_test("FileStoreFormat" FileStoreFormat)
|
||||
|
10
deps/ox/src/ox/fs/test/tests.cpp
vendored
10
deps/ox/src/ox/fs/test/tests.cpp
vendored
@ -340,8 +340,9 @@ map<string, int(*)(string)> tests = {
|
||||
uint8_t buff[buffLen];
|
||||
auto list = new (buff) ox::fs::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
|
||||
err |= !(list->malloc(50).valid());
|
||||
err |= !(list->firstItem().valid());
|
||||
err |= !(list->firstItem()->size() == 50);
|
||||
//auto first = list->firstItem();
|
||||
//err |= !(first.valid());
|
||||
//err |= !(first->size() == 50);
|
||||
return err;
|
||||
}
|
||||
},
|
||||
@ -349,10 +350,13 @@ map<string, int(*)(string)> tests = {
|
||||
"FileStore::readWrite",
|
||||
[](string) {
|
||||
constexpr auto buffLen = 5000;
|
||||
constexpr auto str = "Hello, World!";
|
||||
constexpr auto strLen = ox_strlen(str);
|
||||
uint8_t buff[buffLen];
|
||||
auto list = new (buff) ox::fs::NodeBuffer<uint32_t, ox::fs::FileStoreItem<uint32_t>>(buffLen);
|
||||
ox::fs::FileStore32 fileStore(list, buffLen);
|
||||
ox_assert(fileStore.format() == 0, "Filestore::format failed.");
|
||||
ox_assert(fileStore.format() == 0, "FileStore::format failed.");
|
||||
ox_assert(fileStore.write(5, (void*) str, strLen, 1) == 0, "FileStore::write failed.");
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
12
deps/ox/src/ox/std/new.hpp
vendored
Normal file
12
deps/ox/src/ox/std/new.hpp
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
void* operator new(std::size_t, void*) noexcept;
|
1
deps/ox/src/ox/std/std.hpp
vendored
1
deps/ox/src/ox/std/std.hpp
vendored
@ -13,6 +13,7 @@
|
||||
#include "byteswap.hpp"
|
||||
#include "math.hpp"
|
||||
#include "memops.hpp"
|
||||
#include "new.hpp"
|
||||
#include "random.hpp"
|
||||
#include "strops.hpp"
|
||||
#include "string.hpp"
|
||||
|
16
deps/ox/src/ox/std/string.hpp
vendored
16
deps/ox/src/ox/std/string.hpp
vendored
@ -39,6 +39,8 @@ class BString {
|
||||
|
||||
char *data();
|
||||
|
||||
const char *c_str() noexcept;
|
||||
|
||||
/**
|
||||
* Returns the number of characters in this string.
|
||||
*/
|
||||
@ -92,11 +94,11 @@ const BString<size> &BString<size>::operator=(char *str) {
|
||||
template<size_t size>
|
||||
const BString<size> &BString<size>::operator+=(const char *str) {
|
||||
size_t strLen = ox_strlen(str) + 1;
|
||||
auto currentSize = size();
|
||||
if (cap() < currentSize + strLen) {
|
||||
strLen = cap() - currentSize;
|
||||
auto currentLen = len();
|
||||
if (cap() < currentLen + strLen) {
|
||||
strLen = cap() - currentLen;
|
||||
}
|
||||
ox_memcpy(m_buff + currentSize, str, strLen);
|
||||
ox_memcpy(m_buff + currentLen, str, strLen);
|
||||
// make sure last element is a null terminator
|
||||
m_buff[cap() - 1] = 0;
|
||||
return *this;
|
||||
@ -126,6 +128,12 @@ char *BString<buffLen>::data() {
|
||||
return (char*) m_buff;
|
||||
}
|
||||
|
||||
template<size_t buffLen>
|
||||
const char *BString<buffLen>::c_str() noexcept {
|
||||
return (const char*) m_buff;
|
||||
}
|
||||
|
||||
|
||||
template<size_t buffLen>
|
||||
size_t BString<buffLen>::len() {
|
||||
size_t length = 0;
|
||||
|
12
deps/ox/src/ox/std/strops.cpp
vendored
12
deps/ox/src/ox/std/strops.cpp
vendored
@ -26,18 +26,6 @@ int ox_strcmp(const char *str1, const char *str2) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ox_strlen(const char *str1) {
|
||||
int len;
|
||||
for (len = 0; str1[len]; len++);
|
||||
return len;
|
||||
}
|
||||
|
||||
int ox_strlen(char *str1) {
|
||||
int len;
|
||||
for (len = 0; str1[len]; len++);
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *ox_strchr(const char *str, int character, size_t maxLen) {
|
||||
for (size_t i = 0; i <= maxLen; i++) {
|
||||
if (str[i] == character) {
|
||||
|
12
deps/ox/src/ox/std/strops.hpp
vendored
12
deps/ox/src/ox/std/strops.hpp
vendored
@ -13,9 +13,17 @@
|
||||
|
||||
int ox_strcmp(const char *str1, const char *str2);
|
||||
|
||||
int ox_strlen(const char *str1);
|
||||
constexpr int ox_strlen(const char *str1) {
|
||||
int len = 0;
|
||||
for (; str1[len]; len++);
|
||||
return len;
|
||||
}
|
||||
|
||||
int ox_strlen(char *str1);
|
||||
constexpr int ox_strlen(char *str1) {
|
||||
int len = 0;
|
||||
for (; str1[len]; len++);
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *ox_strchr(const char *str, int character, size_t maxLen = 0xFFFFFFFF);
|
||||
|
||||
|
3
deps/ox/src/ox/std/types.hpp
vendored
3
deps/ox/src/ox/std/types.hpp
vendored
@ -25,8 +25,6 @@ typedef long int64_t;
|
||||
typedef unsigned long uint64_t;
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
typedef int64_t intptr_t;
|
||||
typedef uint64_t uintptr_t;
|
||||
#endif
|
||||
|
||||
namespace ox {
|
||||
@ -54,6 +52,7 @@ typedef uint32_t uintptr_t;
|
||||
namespace std {
|
||||
|
||||
typedef decltype(nullptr) nullptr_t;
|
||||
typedef ::size_t size_t;
|
||||
|
||||
}
|
||||
|
||||
|
28
deps/ox/src/ox/trace/trace.cpp
vendored
28
deps/ox/src/ox/trace/trace.cpp
vendored
@ -6,11 +6,15 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#if defined(OX_USE_STDLIB)
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include <ox/mc/write.hpp>
|
||||
|
||||
#include "trace.hpp"
|
||||
|
||||
namespace ox {
|
||||
namespace ox::trace {
|
||||
|
||||
OutStream::OutStream(const char *file, int line, const char *ch, const char *msg) {
|
||||
m_msg.file = file;
|
||||
@ -26,4 +30,26 @@ OutStream::~OutStream() {
|
||||
writeMC(buff, buffLen, &m_msg, &size);
|
||||
}
|
||||
|
||||
|
||||
StdOutStream::StdOutStream(const char *file, int line, const char *ch, const char *msg) {
|
||||
m_msg.file = file;
|
||||
m_msg.line = line;
|
||||
m_msg.ch = ch;
|
||||
m_msg.msg = msg;
|
||||
}
|
||||
|
||||
StdOutStream::~StdOutStream() {
|
||||
#if defined(OX_USE_STDLIB)
|
||||
std::cout << m_msg.ch.c_str() << ':' << m_msg.msg.c_str();
|
||||
std::cout << " (" << m_msg.file.c_str() << ':' << m_msg.line << ")\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NullStream::NullStream(const char*, int, const char*, const char*) {
|
||||
}
|
||||
|
||||
NullStream::~NullStream() {
|
||||
}
|
||||
|
||||
}
|
||||
|
47
deps/ox/src/ox/trace/trace.hpp
vendored
47
deps/ox/src/ox/trace/trace.hpp
vendored
@ -10,7 +10,7 @@
|
||||
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
namespace ox {
|
||||
namespace ox::trace {
|
||||
|
||||
struct TraceMsg {
|
||||
ox::BString<150> file = "";
|
||||
@ -21,7 +21,7 @@ struct TraceMsg {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
int ioOp(T *io, ox::TraceMsg *obj) {
|
||||
int ioOp(T *io, ox::trace::TraceMsg *obj) {
|
||||
int32_t err = 0;
|
||||
io->setFields(5);
|
||||
err |= io->op("file", &obj->file);
|
||||
@ -44,7 +44,7 @@ class OutStream {
|
||||
~OutStream();
|
||||
|
||||
template<typename T>
|
||||
OutStream &operator<<(T v) {
|
||||
inline OutStream &operator<<(const T &v) {
|
||||
m_msg.msg += " ";
|
||||
m_msg.msg += v;
|
||||
return *this;
|
||||
@ -52,6 +52,45 @@ class OutStream {
|
||||
|
||||
};
|
||||
|
||||
|
||||
class StdOutStream {
|
||||
|
||||
private:
|
||||
TraceMsg m_msg;
|
||||
|
||||
public:
|
||||
StdOutStream() = default;
|
||||
|
||||
StdOutStream(const char *file, int line, const char *ch, const char *msg = "");
|
||||
|
||||
~StdOutStream();
|
||||
|
||||
template<typename T>
|
||||
inline StdOutStream &operator<<(T v) {
|
||||
m_msg.msg += " ";
|
||||
m_msg.msg += v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class NullStream {
|
||||
|
||||
public:
|
||||
NullStream() = default;
|
||||
|
||||
NullStream(const char *file, int line, const char *ch, const char *msg = "");
|
||||
|
||||
~NullStream();
|
||||
|
||||
template<typename T>
|
||||
inline NullStream &operator<<(const T&) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define oxTrace(ch) ox::OutStream(__FILE__, __LINE__, ch)
|
||||
#define oxTrace(ch) ox::trace::StdOutStream(__FILE__, __LINE__, ch)
|
||||
|
Loading…
Reference in New Issue
Block a user