Compare commits

..

2 Commits

Author SHA1 Message Date
cc4da3a4c4 [buildcore] Map aarch64 to arm64 in util.get_arch
All checks were successful
Build / build (push) Successful in 2m56s
2024-12-14 21:05:56 -06:00
1bc050026f [ox/std] Fix compiler warning 2024-12-14 21:02:33 -06:00
538 changed files with 7332 additions and 36781 deletions

1
.gitattributes vendored
View File

@ -1 +0,0 @@
sample_project text eol=lf

View File

@ -4,7 +4,7 @@ on: [push]
jobs: jobs:
build: build:
runs-on: olympic runs-on: nostalgia
steps: steps:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v3 uses: actions/checkout@v3
@ -17,10 +17,3 @@ jobs:
- run: make purge configure-release - run: make purge configure-release
- run: make build - run: make build
- run: make test - run: make test
- run: make install
- run: mv dist/linux-x86_64-release nostalgia-linux-x86_64
- run: tar cf nostalgia-linux-x86_64.tar nostalgia-linux-x86_64
- uses: actions/upload-artifact@v3
with:
name: nostalgia-linux-x86_64
path: nostalgia-linux-x86_64.tar

4
.gitignore vendored
View File

@ -6,14 +6,12 @@
.mypy_cache .mypy_cache
.stfolder .stfolder
.stignore .stignore
.vs scripts/__pycache__
util/scripts/__pycache__
pyenv pyenv
CMakeLists.txt.user CMakeLists.txt.user
ROM.oxfs ROM.oxfs
Session.vim Session.vim
build build
cmake-build-*
compile_commands.json compile_commands.json
dist dist
graph_info.json graph_info.json

View File

@ -2,4 +2,4 @@
source: source:
- src - src
copyright_notice: |- copyright_notice: |-
Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved. Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.

View File

@ -1,4 +1,4 @@
FROM fedora:41 FROM fedora:36
RUN dnf update -y RUN dnf update -y

View File

@ -1,49 +1,35 @@
BC_VAR_PROJECT_NAME=nostalgia BC_VAR_PROJECT_NAME=nostalgia
BC_VAR_PROJECT_NAME_CAP=Nostalgia BC_VAR_PROJECT_NAME_CAP=Nostalgia
BC_VAR_DEVENV_ROOT=util
BUILDCORE_PATH=deps/buildcore BUILDCORE_PATH=deps/buildcore
include ${BUILDCORE_PATH}/base.mk include ${BUILDCORE_PATH}/base.mk
ifeq ($(BC_VAR_OS),darwin) ifeq ($(BC_VAR_OS),darwin)
PROJECT_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio.app/Contents/MacOS/${BC_VAR_PROJECT_NAME_CAP}Studio
MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA MGBA=/Applications/mGBA.app/Contents/MacOS/mGBA
else else
PROJECT_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio NOSTALGIA_STUDIO=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}Studio
MGBA=mgba-qt MGBA=mgba-qt
endif endif
PROJECT_PLAYER=./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME_CAP}
.PHONY: pkg-gba .PHONY: pkg-gba
pkg-gba: build pkg-gba: build
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME_CAP} ${BC_CMD_ENVRUN} ${BC_PY3} ./scripts/pkg-gba.py sample_project ${BC_VAR_PROJECT_NAME}
.PHONY: pkg-mac
pkg-mac: install
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/pkg-dmg.py NostalgiaStudio
.PHONY: generate-studio-rsrc
generate-studio-rsrc:
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/file-to-cpp.py --rsrc src/olympic/studio/applib/src/rsrc.json
${BC_CMD_ENVRUN} ${BC_PY3} ./util/scripts/file-to-cpp.py --rsrc src/nostalgia/studio/rsrc.json
.PHONY: build-player
build-player:
${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} ${BC_VAR_PROJECT_NAME_CAP}
.PHONY: run .PHONY: run
run: build-player run: build
${PROJECT_PLAYER} sample_project ./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
.PHONY: run-studio .PHONY: run-studio
run-studio: build run-studio: build
${PROJECT_STUDIO} ${NOSTALGIA_STUDIO}
.PHONY: gba-run .PHONY: gba-run
gba-run: pkg-gba gba-run: pkg-gba
${MGBA} ${BC_VAR_PROJECT_NAME_CAP}.gba ${MGBA} ${BC_VAR_PROJECT_NAME}.gba
.PHONY: debug .PHONY: debug
debug: build debug: build
${BC_CMD_HOST_DEBUGGER} ${PROJECT_PLAYER} sample_project ${BC_CMD_HOST_DEBUGGER} ./build/${BC_VAR_CURRENT_BUILD}/bin/${BC_VAR_PROJECT_NAME} sample_project
.PHONY: debug-studio .PHONY: debug-studio
debug-studio: build debug-studio: build
${BC_CMD_HOST_DEBUGGER} ${PROJECT_STUDIO} ${BC_CMD_HOST_DEBUGGER} ${NOSTALGIA_STUDIO}
.PHONY: configure-gba .PHONY: configure-gba
configure-gba: configure-gba:
@ -52,25 +38,3 @@ configure-gba:
.PHONY: configure-gba-debug .PHONY: configure-gba-debug
configure-gba-debug: configure-gba-debug:
${BC_CMD_SETUP_BUILD} --toolchain=deps/gbabuildcore/cmake/modules/GBA.cmake --target=gba --current_build=0 --build_type=debug --build_root=${BC_VAR_BUILD_PATH} ${BC_CMD_SETUP_BUILD} --toolchain=deps/gbabuildcore/cmake/modules/GBA.cmake --target=gba --current_build=0 --build_type=debug --build_root=${BC_VAR_BUILD_PATH}
.PHONY: loc
loc:
${BC_PY3} util/scripts/loc.py \
--search-dirs \
src \
deps/ox/src \
deps/buildcore \
deps/gbabuildcore \
deps/glutils \
deps/teagba \
--include-exts \
.cpp \
.hpp \
.py \
.s \
.cmake \
--exclude-paths \
deps/teagba/src/gba_crt0.s \
src/olympic/studio/applib/src/font.cpp \
src/olympic/studio/applib/src/font.hpp \
src/nostalgia/studio/icondata.cpp

View File

@ -93,7 +93,7 @@ purge:
${BC_CMD_RM_RF} compile_commands.json ${BC_CMD_RM_RF} compile_commands.json
.PHONY: test .PHONY: test
test: build test: build
${BC_CMD_ENVRUN} ${BC_CMD_PY3} -m mypy ${BC_VAR_SCRIPTS} ${BC_CMD_ENVRUN} mypy ${BC_VAR_SCRIPTS}
${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test ${BC_CMD_CMAKE_BUILD} ${BC_VAR_BUILD_PATH} test
.PHONY: test-verbose .PHONY: test-verbose
test-verbose: build test-verbose: build

View File

@ -11,7 +11,6 @@
# "Python Busy Box" - adds cross-platform equivalents to Unix commands that # "Python Busy Box" - adds cross-platform equivalents to Unix commands that
# don't translate well to that other operating system # don't translate well to that other operating system
import multiprocessing
import os import os
import platform import platform
import shutil import shutil
@ -58,11 +57,7 @@ def cmake_build(base_path: str, target: Optional[str]) -> int:
path = os.path.join(base_path, d) path = os.path.join(base_path, d)
if not os.path.isdir(path): if not os.path.isdir(path):
continue continue
args = ['cmake', '--build', path, f'-j{multiprocessing.cpu_count()}'] args = ['cmake', '--build', path]
if path.endswith('release'):
args.append('--config=release')
elif path.endswith('debug'):
args.append('--config=debug')
if target is not None: if target is not None:
args.extend(['--target', target]) args.extend(['--target', target])
err = subprocess.run(args).returncode err = subprocess.run(args).returncode

View File

@ -1,8 +1,8 @@
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-unwind-tables")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb-interwork") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb-interwork")

View File

@ -1,11 +1,2 @@
add_library(glad src/glad.c) add_library(glad OBJECT src/glad.c)
target_include_directories(glad PUBLIC include) target_include_directories(glad PUBLIC include)
install(
TARGETS
glad
DESTINATION
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

View File

@ -89,7 +89,7 @@ struct GLObject: public Base {
return id; return id;
} }
constexpr operator GLuint const&() const noexcept { constexpr operator const GLuint&() const noexcept {
return id; return id;
} }
@ -135,7 +135,7 @@ struct FrameBuffer {
return fbo.id; return fbo.id;
} }
constexpr operator GLuint const&() const noexcept { constexpr operator const GLuint&() const noexcept {
return fbo.id; return fbo.id;
} }
@ -158,14 +158,14 @@ struct FrameBuffer {
class FrameBufferBind { class FrameBufferBind {
private: private:
static FrameBuffer const *s_activeFb; static const FrameBuffer *s_activeFb;
FrameBuffer const *m_restoreFb = nullptr; const FrameBuffer *m_restoreFb = nullptr;
public: public:
explicit FrameBufferBind(FrameBuffer const &fb) noexcept; explicit FrameBufferBind(const FrameBuffer &fb) noexcept;
~FrameBufferBind() noexcept; ~FrameBufferBind() noexcept;
}; };
void bind(FrameBuffer const &fb) noexcept; void bind(const FrameBuffer &fb) noexcept;
struct ShaderVarSet { struct ShaderVarSet {
GLsizei len{}; GLsizei len{};
@ -176,7 +176,7 @@ struct ProgramSource {
ox::Vector<glutils::ShaderVarSet> const shaderParams; ox::Vector<glutils::ShaderVarSet> const shaderParams;
GLsizei const rowLen = [this] { GLsizei const rowLen = [this] {
GLsizei len{}; GLsizei len{};
for (auto const &v : shaderParams) { for (auto const&v : shaderParams) {
len += v.len; len += v.len;
} }
return len; return len;
@ -187,23 +187,23 @@ struct ProgramSource {
ox::String const geomShader{}; ox::String const geomShader{};
}; };
ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept; ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept;
ox::Result<GLProgram> buildShaderProgram( ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const &vert, ox::CStringView const&vert,
ox::CStringView const &frag, ox::CStringView const&frag,
ox::CStringView const &geo = "") noexcept; ox::CStringView const&geo = "") noexcept;
void setupShaderParams( void setupShaderParams(
GLProgram const &shader, GLProgram const&shader,
ox::Vector<ShaderVarSet> const &vars, ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept; GLsizei vertexRowLen) noexcept;
void setupShaderParams(GLProgram const &shader, ox::Vector<ShaderVarSet> const &vars) noexcept; void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept;
GLVertexArray generateVertexArrayObject() noexcept; glutils::GLVertexArray generateVertexArrayObject() noexcept;
GLBuffer generateBuffer() noexcept; glutils::GLBuffer generateBuffer() noexcept;
[[nodiscard]] [[nodiscard]]
FrameBuffer generateFrameBuffer(int width, int height) noexcept; FrameBuffer generateFrameBuffer(int width, int height) noexcept;
@ -215,20 +215,20 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
*/ */
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept; void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const &sz) noexcept; void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept;
struct BufferSet { struct BufferSet {
GLVertexArray vao; glutils::GLVertexArray vao;
GLBuffer vbo; glutils::GLBuffer vbo;
GLBuffer ebo; glutils::GLBuffer ebo;
GLTexture tex; glutils::GLTexture tex;
ox::Vector<float> vertices; ox::Vector<float> vertices;
ox::Vector<GLuint> elements; ox::Vector<GLuint> elements;
}; };
void sendVbo(BufferSet const &bs) noexcept; void sendVbo(BufferSet const&bs) noexcept;
void sendEbo(BufferSet const &bs) noexcept; void sendEbo(BufferSet const&bs) noexcept;
void clearScreen() noexcept; void clearScreen() noexcept;

View File

@ -46,9 +46,9 @@ template struct GLObject<deleteVertexArray>;
template struct GLObject<deleteProgram>; template struct GLObject<deleteProgram>;
template struct GLObject<deleteShader>; template struct GLObject<deleteShader>;
FrameBuffer const *FrameBufferBind::s_activeFb = nullptr; const FrameBuffer *FrameBufferBind::s_activeFb = nullptr;
FrameBufferBind::FrameBufferBind(FrameBuffer const &fb) noexcept: m_restoreFb(s_activeFb) { FrameBufferBind::FrameBufferBind(const FrameBuffer &fb) noexcept: m_restoreFb(s_activeFb) {
s_activeFb = &fb; s_activeFb = &fb;
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0, 0, fb.width, fb.height); glViewport(0, 0, fb.width, fb.height);
@ -64,15 +64,15 @@ FrameBufferBind::~FrameBufferBind() noexcept {
} }
} }
void bind(FrameBuffer const &fb) noexcept { void bind(const FrameBuffer &fb) noexcept {
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0, 0, fb.width, fb.height); glViewport(0, 0, fb.width, fb.height);
} }
static ox::Result<GLShader> buildShader( static ox::Result<GLShader> buildShader(
GLuint const shaderType, GLuint shaderType,
GLchar const *src, const GLchar *src,
ox::StringViewCR shaderName) noexcept { ox::StringViewCR shaderName) noexcept {
GLShader shader(glCreateShader(shaderType)); GLShader shader(glCreateShader(shaderType));
glShaderSource(shader, 1, &src, nullptr); glShaderSource(shader, 1, &src, nullptr);
@ -88,8 +88,8 @@ static ox::Result<GLShader> buildShader(
return shader; return shader;
} }
ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept { ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
OX_REQUIRE_M(program, buildShaderProgram( oxRequireM(program, buildShaderProgram(
src.vertShader, src.vertShader,
src.fragShader, src.fragShader,
src.geomShader)); src.geomShader));
@ -98,11 +98,11 @@ ox::Result<GLProgram> buildShaderProgram(ProgramSource const &src) noexcept {
} }
void setupShaderParams( void setupShaderParams(
GLProgram const &shader, GLProgram const&shader,
ox::Vector<ShaderVarSet> const &vars, ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept { GLsizei vertexRowLen) noexcept {
// setup vars // setup vars
for (size_t lenWritten = 0; auto const &v : vars) { for (size_t lenWritten = 0; auto const&v : vars) {
auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str())); auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
glEnableVertexAttribArray(attr); glEnableVertexAttribArray(attr);
glVertexAttribPointer( glVertexAttribPointer(
@ -113,27 +113,27 @@ void setupShaderParams(
} }
} }
void setupShaderParams(GLProgram const &shader, ox::Vector<ShaderVarSet> const &vars) noexcept { void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept {
// get row len // get row len
GLsizei vertexRowLen{}; GLsizei vertexRowLen{};
for (auto const &v : vars) { for (auto const&v : vars) {
vertexRowLen += v.len; vertexRowLen += v.len;
} }
setupShaderParams(shader, vars, vertexRowLen); setupShaderParams(shader, vars, vertexRowLen);
} }
ox::Result<GLProgram> buildShaderProgram( ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const &vert, ox::CStringView const&vert,
ox::CStringView const &frag, ox::CStringView const&frag,
ox::CStringView const &geo) noexcept { ox::CStringView const&geo) noexcept {
GLProgram prgm(glCreateProgram()); GLProgram prgm(glCreateProgram());
OX_REQUIRE(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad")); oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
glAttachShader(prgm, vs); glAttachShader(prgm, vs);
if (geo.c_str() && geo.bytes() != 0) { if (geo.c_str() && geo.bytes() != 0) {
OX_REQUIRE(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad")); oxRequire(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad"));
glAttachShader(prgm, gs); glAttachShader(prgm, gs);
} }
OX_REQUIRE(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad")); oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad"));
glAttachShader(prgm, fs); glAttachShader(prgm, fs);
glLinkProgram(prgm); glLinkProgram(prgm);
return prgm; return prgm;
@ -162,30 +162,16 @@ FrameBuffer generateFrameBuffer(int width, int height) noexcept {
// color texture // color texture
glGenTextures(1, &fb.color.id); glGenTextures(1, &fb.color.id);
glBindTexture(GL_TEXTURE_2D, fb.color); glBindTexture(GL_TEXTURE_2D, fb.color);
glTexImage2D( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
GL_TEXTURE_2D,
0,
GL_RGB,
width,
height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glFramebufferTexture2D( glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.color, 0);
// depth texture // depth texture
glGenRenderbuffers(1, &fb.depth.id); glGenRenderbuffers(1, &fb.depth.id);
glBindRenderbuffer(GL_RENDERBUFFER, fb.depth); glBindRenderbuffer(GL_RENDERBUFFER, fb.depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.depth);
GL_FRAMEBUFFER,
GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER,
fb.depth);
// verify FBO // verify FBO
oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete"); oxAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Frame Buffer is incomplete");
// restore primary FB // restore primary FB
@ -203,16 +189,7 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
// color texture // color texture
glBindTexture(GL_TEXTURE_2D, fb.color); glBindTexture(GL_TEXTURE_2D, fb.color);
glTexImage2D( glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
GL_TEXTURE_2D,
0,
GL_RGB,
width,
height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// depth texture // depth texture
@ -224,7 +201,7 @@ void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
} }
void resizeInitFrameBuffer(FrameBuffer &fb, int const width, int const height) noexcept { void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
if (!fb) { if (!fb) {
fb = generateFrameBuffer(width, height); fb = generateFrameBuffer(width, height);
return; return;
@ -232,18 +209,18 @@ void resizeInitFrameBuffer(FrameBuffer &fb, int const width, int const height) n
resizeFrameBuffer(fb, width, height); resizeFrameBuffer(fb, width, height);
} }
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const &sz) noexcept { void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept {
resizeInitFrameBuffer(fb, sz.width, sz.height); resizeInitFrameBuffer(fb, sz.width, sz.height);
} }
void sendVbo(BufferSet const &bs) noexcept { void sendVbo(BufferSet const&bs) noexcept {
auto const bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size()); const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.vertices)::value_type) * bs.vertices.size());
glBindBuffer(GL_ARRAY_BUFFER, bs.vbo); glBindBuffer(GL_ARRAY_BUFFER, bs.vbo);
glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, bufferSize, bs.vertices.data(), GL_DYNAMIC_DRAW);
} }
void sendEbo(BufferSet const &bs) noexcept { void sendEbo(BufferSet const&bs) noexcept {
auto const bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size()); const auto bufferSize = static_cast<GLsizeiptr>(sizeof(decltype(bs.elements)::value_type) * bs.elements.size());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bs.ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferSize, bs.elements.data(), GL_STATIC_DRAW);
} }

View File

@ -6,7 +6,7 @@ endif()
# DrinkingTea: end # DrinkingTea: end
add_library( add_library(
imgui imgui OBJECT
imgui.cpp imgui.cpp
imgui_demo.cpp imgui_demo.cpp
imgui_draw.cpp imgui_draw.cpp
@ -20,11 +20,3 @@ target_include_directories(
imgui SYSTEM PUBLIC imgui SYSTEM PUBLIC
. .
) )
install(
TARGETS
imgui
DESTINATION
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.19) cmake_minimum_required(VERSION 3.5)
project(nativefiledialog-extended VERSION 1.1.1) project(nativefiledialog-extended VERSION 1.1.1)
set(nfd_ROOT_PROJECT OFF) set(nfd_ROOT_PROJECT OFF)
@ -10,11 +10,7 @@ if(NOT DEFINED BUILD_SHARED_LIBS)
option(BUILD_SHARED_LIBS "Build a shared library instead of static" OFF) option(BUILD_SHARED_LIBS "Build a shared library instead of static" OFF)
endif() endif()
option(NFD_BUILD_TESTS "Build tests for nfd" ${nfd_ROOT_PROJECT}) option(NFD_BUILD_TESTS "Build tests for nfd" ${nfd_ROOT_PROJECT})
# DrinkingTea: begin option(NFD_INSTALL "Generate install target for nfd" ${nfd_ROOT_PROJECT})
if(NOT DEFINED NFD_INSTALL)
option(NFD_INSTALL "Generate install target for nfd" ${nfd_ROOT_PROJECT})
endif()
# DrinkingTea: end
set(nfd_PLATFORM Undefined) set(nfd_PLATFORM Undefined)
if(WIN32) if(WIN32)
@ -25,9 +21,7 @@ elseif(UNIX AND NOT APPLE)
set(nfd_PLATFORM PLATFORM_UNIX) set(nfd_PLATFORM PLATFORM_UNIX)
endif() endif()
# DrinkingTea: begin message("nfd Platform: ${nfd_PLATFORM}")
#message("nfd Platform: ${nfd_PLATFORM}")
# DrinkingTea: end
set(nfd_COMPILER Undefined) set(nfd_COMPILER Undefined)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
@ -39,9 +33,7 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "C
set(nfd_COMPILER COMPILER_GNU) set(nfd_COMPILER COMPILER_GNU)
endif() endif()
# DrinkingTea: begin message("nfd Compiler: ${nfd_COMPILER}")
#message("nfd Compiler: ${nfd_COMPILER}")
# DrinkingTea: end
# Use latest C++ by default (should be the best one), but let user override it # Use latest C++ by default (should be the best one), but let user override it
if(NOT DEFINED CMAKE_CXX_STANDARD) if(NOT DEFINED CMAKE_CXX_STANDARD)

2
deps/ox/.liccor.yml vendored
View File

@ -2,7 +2,7 @@
source: source:
- src - src
copyright_notice: |- copyright_notice: |-
Copyright 2015 - 2025 gary@drinkingtea.net Copyright 2015 - 2024 gary@drinkingtea.net
This Source Code Form is subject to the terms of the Mozilla Public 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 License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -12,7 +12,7 @@
# CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will # CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will
# continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:" # continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:"
# #
set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.13.2") set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.8.0")
set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2") set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2")
cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION}) cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION})
if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}")

82
deps/ox/ox-docs.md vendored
View File

@ -97,12 +97,12 @@ ox::Result<uint64_t> caller8(int i) {
``` ```
Lastly, there are a few macros available to help in passing ```ox::Error```s Lastly, there are a few macros available to help in passing ```ox::Error```s
back up the call stack, ```OX_RETURN_ERROR```, ```OX_THROW_ERROR```, and back up the call stack, ```oxReturnError```, ```oxThrowError```, and
```OX_REQUIRE```. ```oxRequire```.
```OX_RETURN_ERROR``` is by far the more helpful of the two. ```oxReturnError``` is by far the more helpful of the two.
```OX_RETURN_ERROR``` will return an ```ox::Error``` if it is not 0 and ```oxReturnError``` will return an ```ox::Error``` if it is not 0 and
```OX_THROW_ERROR``` will throw an ```ox::Error``` if it is not 0. ```oxThrowError``` will throw an ```ox::Error``` if it is not 0.
Since ```ox::Error``` is always nodiscard, you must do something with them. Since ```ox::Error``` is always nodiscard, you must do something with them.
In rare cases, you may not have anything you can do with them or you may know In rare cases, you may not have anything you can do with them or you may know
@ -113,13 +113,13 @@ This should be used sparingly.
```cpp ```cpp
void studioCode() { void studioCode() {
auto [val, err] = foo(1); auto [val, err] = foo(1);
OX_THROW_ERROR(err); oxThrowError(err);
doStuff(val); doStuff(val);
} }
ox::Error engineCode() noexcept { ox::Error engineCode() noexcept {
auto [val, err] = foo(1); auto [val, err] = foo(1);
OX_RETURN_ERROR(err); oxReturnError(err);
doStuff(val); doStuff(val);
return {}; return {};
} }
@ -136,19 +136,19 @@ Both macros will also take the ```ox::Result``` directly:
```cpp ```cpp
void studioCode() { void studioCode() {
auto valerr = foo(1); auto valerr = foo(1);
OX_THROW_ERROR(valerr); oxThrowError(valerr);
doStuff(valerr.value); doStuff(valerr.value);
} }
ox::Error engineCode() noexcept { ox::Error engineCode() noexcept {
auto valerr = foo(1); auto valerr = foo(1);
OX_RETURN_ERROR(valerr); oxReturnError(valerr);
doStuff(valerr.value); doStuff(valerr.value);
return {}; return {};
} }
``` ```
Ox also has the ```OX_REQUIRE``` macro, which will initialize a value if there is no error, and return if there is. Ox also has the ```oxRequire``` macro, which will initialize a value if there is no error, and return if there is.
It aims to somewhat emulate the ```?``` operator in Rust and Swift. It aims to somewhat emulate the ```?``` operator in Rust and Swift.
Rust ```?``` operator: Rust ```?``` operator:
@ -163,23 +163,23 @@ fn f2() -> Result<i32, i32> {
} }
``` ```
```OX_REQUIRE```: ```oxRequire```:
```cpp ```cpp
ox::Result<int> f() noexcept { ox::Result<int> f() noexcept {
// do stuff // do stuff
} }
ox::Result<int> f2() noexcept { ox::Result<int> f2() noexcept {
OX_REQUIRE(i, f()); // const auto [out, OX_CONCAT(oxRequire_err_, __LINE__)] = x; OX_RETURN_ERROR(OX_CONCAT(oxRequire_err_, __LINE__)) oxRequire(i, f()); // const auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__))
return i + 4; return i + 4;
} }
``` ```
```OX_REQUIRE``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code. ```oxRequire``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code.
```OX_REQUIRE``` by default creates a const, but there is also an ```OX_REQUIRE_M``` (OX_REQUIRE Mutable) ```oxRequire``` by default creates a const, but there is also an ```oxRequireM``` (oxRequire Mutable)
variant for creating a non-const value. variant for creating a non-const value.
* ```OX_REQUIRE_M``` - OX_REQUIRE Mutable * ```oxRequireM``` - oxRequire Mutable
### Logging and Output ### Logging and Output
@ -268,19 +268,19 @@ constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaPalette> auto *pal) n
h->template setTypeInfo<NostalgiaPalette>(); h->template setTypeInfo<NostalgiaPalette>();
// it is also possible to provide the type name and type version as function arguments // it is also possible to provide the type name and type version as function arguments
//h->setTypeInfo("net.drinkingtea.nostalgia.core.NostalgiaPalette", 1); //h->setTypeInfo("net.drinkingtea.nostalgia.core.NostalgiaPalette", 1);
OX_RETURN_ERROR(h->field("colors", &pal->colors)); oxReturnError(h->field("colors", &pal->colors));
return {}; return {};
} }
template<typename T> template<typename T>
constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaGraphic> auto *ng) noexcept { constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaGraphic> auto *ng) noexcept {
h->template setTypeInfo<NostalgiaGraphic>(); h->template setTypeInfo<NostalgiaGraphic>();
OX_RETURN_ERROR(h->field("bpp", &ng->bpp)); oxReturnError(h->field("bpp", &ng->bpp));
OX_RETURN_ERROR(h->field("rows", &ng->rows)); oxReturnError(h->field("rows", &ng->rows));
OX_RETURN_ERROR(h->field("columns", &ng->columns)); oxReturnError(h->field("columns", &ng->columns));
OX_RETURN_ERROR(h->field("defaultPalette", &ng->defaultPalette)); oxReturnError(h->field("defaultPalette", &ng->defaultPalette));
OX_RETURN_ERROR(h->field("pal", &ng->pal)); oxReturnError(h->field("pal", &ng->pal));
OX_RETURN_ERROR(h->field("pixels", &ng->pixels)); oxReturnError(h->field("pixels", &ng->pixels));
return {}; return {};
} }
``` ```
@ -315,9 +315,9 @@ class FileAddress {
template<typename T> template<typename T>
constexpr Error model(T *h, ox::CommonPtrWith<FileAddress::Data> auto *obj) noexcept { constexpr Error model(T *h, ox::CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
h->template setTypeInfo<FileAddress::Data>(); h->template setTypeInfo<FileAddress::Data>();
OX_RETURN_ERROR(h->fieldCString("path", &obj->path)); oxReturnError(h->fieldCString("path", &obj->path));
OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path)); oxReturnError(h->fieldCString("constPath", &obj->path));
OX_RETURN_ERROR(h->field("inode", &obj->inode)); oxReturnError(h->field("inode", &obj->inode));
return {}; return {};
} }
@ -327,13 +327,13 @@ constexpr Error model(T *io, ox::CommonPtrWith<FileAddress> auto *fa) noexcept {
// cannot read from object in Reflect operation // cannot read from object in Reflect operation
if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) { if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
int8_t type = 0; int8_t type = 0;
OX_RETURN_ERROR(io->field("type", &type)); oxReturnError(io->field("type", &type));
OX_RETURN_ERROR(io->field("data", UnionView(&fa->m_data, 0))); oxReturnError(io->field("data", UnionView(&fa->m_data, 0)));
} else { } else {
auto type = static_cast<int8_t>(fa->m_type); auto type = static_cast<int8_t>(fa->m_type);
OX_RETURN_ERROR(io->field("type", &type)); oxReturnError(io->field("type", &type));
fa->m_type = static_cast<FileAddressType>(type); fa->m_type = static_cast<FileAddressType>(type);
OX_RETURN_ERROR(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type)))); oxReturnError(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
} }
return {}; return {};
} }
@ -343,13 +343,13 @@ constexpr Error model(T *io, ox::CommonPtrWith<FileAddress> auto *fa) noexcept {
There are also macros in ```<ox/model/def.hpp>``` for simplifying the declaration of models: There are also macros in ```<ox/model/def.hpp>``` for simplifying the declaration of models:
```cpp ```cpp
OX_MODEL_BEGIN(NostalgiaGraphic) oxModelBegin(NostalgiaGraphic)
OX_MODEL_FIELD(bpp) oxModelField(bpp)
OX_MODEL_FIELD(rows) oxModelField(rows)
OX_MODEL_FIELD(columns) oxModelField(columns)
OX_MODEL_FIELD(defaultPalette) oxModelField(defaultPalette)
OX_MODEL_FIELD(pal) oxModelField(pal)
OX_MODEL_FIELD(pixels) oxModelField(pixels)
oxModelEnd() oxModelEnd()
``` ```
@ -392,7 +392,7 @@ ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept { ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
NostalgiaPalette pal; NostalgiaPalette pal;
OX_RETURN_ERROR(ox::readMC(buff, pal)); oxReturnError(ox::readMC(buff, pal));
return pal; return pal;
} }
``` ```
@ -405,7 +405,7 @@ ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept { ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept {
ox::Buffer buffer(ox::units::MB); ox::Buffer buffer(ox::units::MB);
std::size_t sz = 0; std::size_t sz = 0;
OX_RETURN_ERROR(ox::writeMC(buffer.data(), buffer.size(), pal, &sz)); oxReturnError(ox::writeMC(buffer.data(), buffer.size(), pal, &sz));
buffer.resize(sz); buffer.resize(sz);
return buffer; return buffer;
} }
@ -428,7 +428,7 @@ ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept { ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
NostalgiaPalette pal; NostalgiaPalette pal;
OX_RETURN_ERROR(ox::readOC(buff, &pal)); oxReturnError(ox::readOC(buff, &pal));
return pal; return pal;
} }
``` ```
@ -440,7 +440,7 @@ ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept { ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept {
ox::Buffer buffer(ox::units::MB); ox::Buffer buffer(ox::units::MB);
OX_RETURN_ERROR(ox::writeOC(buffer.data(), buffer.size(), pal)); oxReturnError(ox::writeOC(buffer.data(), buffer.size(), pal));
return buffer; return buffer;
} }
@ -462,7 +462,7 @@ ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept { ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
NostalgiaPalette pal; NostalgiaPalette pal;
OX_RETURN_ERROR(ox::readClaw(buff, pal)); oxReturnError(ox::readClaw(buff, pal));
return pal; return pal;
} }
``` ```

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -29,7 +29,7 @@ ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
m_bools[arg] = false; m_bools[arg] = false;
} }
m_strings[arg] = val; m_strings[arg] = val;
if (auto r = ox::strToInt(val); r.error == 0) { if (auto r = ox::atoi(val.c_str()); r.error == 0) {
m_ints[arg] = r.value; m_ints[arg] = r.value;
} }
++i; ++i;
@ -55,17 +55,17 @@ int ClArgs::getInt(ox::StringViewCR arg, int defaultValue) const noexcept {
} }
Result<bool> ClArgs::getBool(ox::StringViewCR arg) const noexcept { Result<bool> ClArgs::getBool(ox::StringViewCR arg) const noexcept {
OX_REQUIRE(out, m_bools.at(arg)); oxRequire(out, m_bools.at(arg));
return *out; return *out;
} }
Result<String> ClArgs::getString(ox::StringViewCR argName) const noexcept { Result<String> ClArgs::getString(ox::StringViewCR argName) const noexcept {
OX_REQUIRE(out, m_strings.at(argName)); oxRequire(out, m_strings.at(argName));
return *out; return *out;
} }
Result<int> ClArgs::getInt(ox::StringViewCR arg) const noexcept { Result<int> ClArgs::getInt(ox::StringViewCR arg) const noexcept {
OX_REQUIRE(out, m_ints.at(arg)); oxRequire(out, m_ints.at(arg));
return *out; return *out;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -81,33 +81,33 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
return ox::Error(4, "Claw format does not match any supported format/version combo"); return ox::Error(4, "Claw format does not match any supported format/version combo");
} }
hdr.typeName = typeName; hdr.typeName = typeName;
std::ignore = ox::strToInt(versionStr).copyTo(hdr.typeVersion); std::ignore = ox::atoi(versionStr).copyTo(hdr.typeVersion);
hdr.data = buffRaw; hdr.data = buffRaw;
hdr.dataSize = buffLen; hdr.dataSize = buffLen;
return hdr; return hdr;
} }
Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept { Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept {
OX_REQUIRE(header, readClawHeader(buff)); oxRequire(header, readClawHeader(buff));
return {{header.data, header.dataSize}}; return {{header.data, header.dataSize}};
} }
Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept { Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
OX_REQUIRE(header, readClawHeader(buff)); oxRequire(header, readClawHeader(buff));
auto const [t, tdErr] = ts.getLoad( auto const [t, tdErr] = ts.getLoad(
header.typeName, header.typeVersion, header.typeParams); header.typeName, header.typeVersion, header.typeParams);
if (tdErr) { if (tdErr) {
return ox::Error(3, "Could not load type descriptor"); return ox::Error(3, "Could not load type descriptor");
} }
ModelObject obj; ModelObject obj;
OX_RETURN_ERROR(obj.setType(t)); oxReturnError(obj.setType(t));
switch (header.fmt) { switch (header.fmt) {
case ClawFormat::Metal: case ClawFormat::Metal:
{ {
ox::BufferReader br({header.data, header.dataSize}); ox::BufferReader br({header.data, header.dataSize});
MetalClawReader reader(br); MetalClawReader reader(br);
ModelHandlerInterface handler(&reader); ModelHandlerInterface handler(&reader);
OX_RETURN_ERROR(model(&handler, &obj)); oxReturnError(model(&handler, &obj));
return obj; return obj;
} }
case ClawFormat::Organic: case ClawFormat::Organic:
@ -115,7 +115,7 @@ Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
OrganicClawReader reader({header.data, header.dataSize}); OrganicClawReader reader({header.data, header.dataSize});
ModelHandlerInterface handler(&reader); ModelHandlerInterface handler(&reader);
OX_RETURN_ERROR(model(&handler, &obj)); oxReturnError(model(&handler, &obj));
return obj; return obj;
#else #else
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -40,7 +40,7 @@ Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept;
template<typename T> template<typename T>
Error readClaw(ox::BufferView buff, T &val) { Error readClaw(ox::BufferView buff, T &val) {
OX_REQUIRE(header, readClawHeader(buff)); oxRequire(header, readClawHeader(buff));
if (header.typeName != getModelTypeName<T>()) { if (header.typeName != getModelTypeName<T>()) {
return ox::Error(Error_ClawTypeMismatch, "Claw Read: Type mismatch"); return ox::Error(Error_ClawTypeMismatch, "Claw Read: Type mismatch");
} }
@ -73,7 +73,7 @@ Error readClaw(ox::BufferView buff, T &val) {
template<typename T> template<typename T>
Result<T> readClaw(ox::BufferView buff) { Result<T> readClaw(ox::BufferView buff) {
Result<T> val; Result<T> val;
OX_RETURN_ERROR(readClaw(buff, val.value)); oxReturnError(readClaw(buff, val.value));
return val; return val;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -62,44 +62,44 @@ struct TestStruct {
template<typename T> template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) { constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) {
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>()); oxReturnError(io->template setTypeInfo<TestUnion>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->fieldCString("String", &obj->String)); oxReturnError(io->fieldCString("String", &obj->String));
return ox::Error(0); return ox::Error(0);
} }
template<typename T> template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) { constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) {
OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>()); oxReturnError(io->template setTypeInfo<TestStructNest>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("String", &obj->String)); oxReturnError(io->field("String", &obj->String));
return ox::Error(0); return ox::Error(0);
} }
template<typename T> template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) { constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) {
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>()); oxReturnError(io->template setTypeInfo<TestStruct>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("Int1", &obj->Int1)); oxReturnError(io->field("Int1", &obj->Int1));
OX_RETURN_ERROR(io->field("Int2", &obj->Int2)); oxReturnError(io->field("Int2", &obj->Int2));
OX_RETURN_ERROR(io->field("Int3", &obj->Int3)); oxReturnError(io->field("Int3", &obj->Int3));
OX_RETURN_ERROR(io->field("Int4", &obj->Int4)); oxReturnError(io->field("Int4", &obj->Int4));
OX_RETURN_ERROR(io->field("Int5", &obj->Int5)); oxReturnError(io->field("Int5", &obj->Int5));
OX_RETURN_ERROR(io->field("Int6", &obj->Int6)); oxReturnError(io->field("Int6", &obj->Int6));
OX_RETURN_ERROR(io->field("Int7", &obj->Int7)); oxReturnError(io->field("Int7", &obj->Int7));
OX_RETURN_ERROR(io->field("Int8", &obj->Int8)); oxReturnError(io->field("Int8", &obj->Int8));
int unionIdx = 0; int unionIdx = 0;
if constexpr(T::opType() != ox::OpType::Reflect) { if constexpr(T::opType() != ox::OpType::Reflect) {
unionIdx = obj->unionIdx; unionIdx = obj->unionIdx;
} }
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, unionIdx})); oxReturnError(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
OX_RETURN_ERROR(io->field("String", &obj->String)); oxReturnError(io->field("String", &obj->String));
OX_RETURN_ERROR(io->field("List", obj->List, 4)); oxReturnError(io->field("List", obj->List, 4));
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct)); oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
OX_RETURN_ERROR(io->field("Struct", &obj->Struct)); oxReturnError(io->field("Struct", &obj->Struct));
return ox::Error(0); return ox::Error(0);
} }
@ -134,7 +134,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
[] { [] {
constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf"); constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf");
constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3"); constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3");
OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1})); oxRequire(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1}));
oxExpect(actual, expected); oxExpect(actual, expected);
return ox::Error{}; return ox::Error{};
} }
@ -145,7 +145,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
// This test doesn't confirm much, but it does show that the writer // This test doesn't confirm much, but it does show that the writer
// doesn't segfault // doesn't segfault
TestStruct ts; TestStruct ts;
OX_RETURN_ERROR(ox::writeClaw(ts, ox::ClawFormat::Metal)); oxReturnError(ox::writeClaw(ts, ox::ClawFormat::Metal));
return ox::Error(0); return ox::Error(0);
} }
}, },

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -39,7 +39,7 @@ struct TypeInfoCatcher {
} }
constexpr Error field(...) noexcept { constexpr Error field(...) noexcept {
return {}; return ox::Error(0);
} }
static constexpr auto opType() { static constexpr auto opType() {
@ -76,21 +76,21 @@ template<typename T>
ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noexcept { ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noexcept {
switch (fmt) { switch (fmt) {
case ClawFormat::Metal: case ClawFormat::Metal:
OX_RETURN_ERROR(write(writer, "M2;")); oxReturnError(write(writer, "M2;"));
break; break;
case ClawFormat::Organic: case ClawFormat::Organic:
OX_RETURN_ERROR(write(writer, "O1;")); oxReturnError(write(writer, "O1;"));
break; break;
default: default:
return ox::Error(1); return ox::Error(1);
} }
OX_RETURN_ERROR(write(writer, detail::getTypeName(t))); oxReturnError(write(writer, detail::getTypeName(t)));
OX_RETURN_ERROR(writer.put(';')); oxReturnError(writer.put(';'));
const auto tn = detail::getTypeVersion(t); const auto tn = detail::getTypeVersion(t);
if (tn > -1) { if (tn > -1) {
OX_RETURN_ERROR(ox::writeItoa(tn, writer)); oxReturnError(ox::writeItoa(tn, writer));
} }
OX_RETURN_ERROR(writer.put(';')); oxReturnError(writer.put(';'));
return {}; return {};
} }
@ -102,19 +102,19 @@ Result<Buffer> writeClaw(
std::size_t buffReserveSz = 2 * units::KB) noexcept { std::size_t buffReserveSz = 2 * units::KB) noexcept {
Buffer out(buffReserveSz); Buffer out(buffReserveSz);
BufferWriter bw(&out, 0); BufferWriter bw(&out, 0);
OX_RETURN_ERROR(detail::writeClawHeader(bw, &t, fmt)); oxReturnError(detail::writeClawHeader(bw, &t, fmt));
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
if (fmt == ClawFormat::Metal) { if (fmt == ClawFormat::Metal) {
OX_RETURN_ERROR(writeMC(bw, t)); oxReturnError(writeMC(bw, t));
} else if (fmt == ClawFormat::Organic) { } else if (fmt == ClawFormat::Organic) {
OX_REQUIRE(data, writeOC(t)); oxRequire(data, writeOC(t));
OX_RETURN_ERROR(bw.write(data.data(), data.size())); oxReturnError(bw.write(data.data(), data.size()));
} }
#else #else
if (fmt != ClawFormat::Metal) { if (fmt != ClawFormat::Metal) {
return ox::Error(1, "OC is not supported in this build"); return ox::Error(1, "OC is not supported in this build");
} }
OX_RETURN_ERROR(writeMC(bw, t)); oxReturnError(writeMC(bw, t));
#endif #endif
out.resize(bw.tellp()); out.resize(bw.tellp());
return out; return out;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -57,7 +57,7 @@ class Signal {
void call(Args... args) final { void call(Args... args) final {
if constexpr(detail::isError<decltype(f(args...))>::value) { if constexpr(detail::isError<decltype(f(args...))>::value) {
OX_THROW_ERROR(f(args...)); oxThrowError(f(args...));
} else { } else {
f(args...); f(args...);
} }
@ -76,7 +76,7 @@ class Signal {
void call(Args... args) final { void call(Args... args) final {
if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) { if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
OX_THROW_ERROR((m_receiver->*(m_methodPtr))(args...)); oxThrowError((m_receiver->*(m_methodPtr))(args...));
} else { } else {
f(args...); f(args...);
} }
@ -107,7 +107,7 @@ class Signal {
void call(Args... args) final { void call(Args... args) final {
if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) { if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
OX_THROW_ERROR((m_receiver->*(m_methodPtr))(args...)); oxThrowError((m_receiver->*(m_methodPtr))(args...));
} else { } else {
(m_receiver->*(m_methodPtr))(args...); (m_receiver->*(m_methodPtr))(args...);
} }
@ -143,11 +143,6 @@ class Signal {
Error disconnectObject(const void *receiver) const noexcept; Error disconnectObject(const void *receiver) const noexcept;
[[nodiscard]]
size_t connectionCnt() const noexcept {
return m_slots.size();
}
void emit(Args... args) const; void emit(Args... args) const;
Error emitCheckError(Args... args) const noexcept; Error emitCheckError(Args... args) const noexcept;
@ -198,7 +193,7 @@ Error Signal<Args...>::disconnectObject(const void *receiver) const noexcept {
for (auto i = 0u; i < m_slots.size(); ++i) { for (auto i = 0u; i < m_slots.size(); ++i) {
const auto &slot = m_slots[i]; const auto &slot = m_slots[i];
if (slot->receiver() == receiver) { if (slot->receiver() == receiver) {
OX_RETURN_ERROR(m_slots.erase(i)); oxReturnError(m_slots.erase(i));
--i; --i;
} }
} }
@ -218,9 +213,9 @@ Error Signal<Args...>::emitCheckError(Args... args) const noexcept {
for (auto &f : m_slots) { for (auto &f : m_slots) {
f->call(args...); f->call(args...);
} }
return {}; return ox::Error(0);
} catch (const ox::Exception &ex) { } catch (const ox::Exception &ex) {
return ox::Error(ex.errCode, ex.msg, ex.src); return ox::Error(ex.file, ex.line, ex.errCode, ex.msg);
} }
} }
@ -324,11 +319,6 @@ class Signal<Error(Args...)> {
Error disconnectObject(const void *receiver) const noexcept; Error disconnectObject(const void *receiver) const noexcept;
[[nodiscard]]
size_t connectionCnt() const noexcept {
return m_slots.size();
}
void emit(Args... args) const noexcept; void emit(Args... args) const noexcept;
Error emitCheckError(Args... args) const noexcept; Error emitCheckError(Args... args) const noexcept;
@ -391,7 +381,7 @@ Error Signal<Error(Args...)>::disconnectObject(const void *receiver) const noexc
for (auto i = 0u; i < m_slots.size(); ++i) { for (auto i = 0u; i < m_slots.size(); ++i) {
const auto &slot = m_slots[i]; const auto &slot = m_slots[i];
if (slot->receiver() == receiver) { if (slot->receiver() == receiver) {
OX_RETURN_ERROR(m_slots.erase(i)); oxReturnError(m_slots.erase(i));
--i; --i;
} }
} }
@ -408,9 +398,9 @@ void Signal<Error(Args...)>::emit(Args... args) const noexcept {
template<class... Args> template<class... Args>
Error Signal<Error(Args...)>::emitCheckError(Args... args) const noexcept { Error Signal<Error(Args...)>::emitCheckError(Args... args) const noexcept {
for (auto &f : m_slots) { for (auto &f : m_slots) {
OX_RETURN_ERROR(f->call(ox::forward<Args>(args)...)); oxReturnError(f->call(ox::forward<Args>(args)...));
} }
return {}; return ox::Error(0);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -31,8 +31,8 @@ std::map<ox::StringView, std::function<ox::Error()>> tests = {
}); });
TestStruct ts; TestStruct ts;
signal.connect(&ts, &TestStruct::method); signal.connect(&ts, &TestStruct::method);
OX_RETURN_ERROR(signal.emitCheckError(5)); oxReturnError(signal.emitCheckError(5));
OX_RETURN_ERROR(ox::Error(ts.value != 5)); oxReturnError(ox::Error(ts.value != 5));
return ox::Error(0); return ox::Error(0);
} }
}, },

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -228,19 +228,19 @@ Error FileStoreTemplate<size_t>::setSize(std::size_t size) {
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::incLinks(uint64_t id) { Error FileStoreTemplate<size_t>::incLinks(uint64_t id) {
OX_REQUIRE_M(item, find(static_cast<size_t>(id)).validate()); oxRequireM(item, find(static_cast<size_t>(id)).validate());
++item->links; ++item->links;
return {}; return ox::Error(0);
} }
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::decLinks(uint64_t id) { Error FileStoreTemplate<size_t>::decLinks(uint64_t id) {
OX_REQUIRE_M(item, find(static_cast<size_t>(id)).validate()); oxRequireM(item, find(static_cast<size_t>(id)).validate());
--item->links; --item->links;
if (item->links == 0) { if (item->links == 0) {
OX_RETURN_ERROR(remove(item)); oxReturnError(remove(item));
} }
return {}; return ox::Error(0);
} }
template<typename size_t> template<typename size_t>
@ -249,7 +249,7 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
oxTracef("ox.fs.FileStoreTemplate.write", "Attempting to write to inode {}", id); oxTracef("ox.fs.FileStoreTemplate.write", "Attempting to write to inode {}", id);
auto existing = find(id); auto existing = find(id);
if (!canWrite(existing, dataSize)) { if (!canWrite(existing, dataSize)) {
OX_RETURN_ERROR(compact()); oxReturnError(compact());
existing = find(id); existing = find(id);
} }
@ -269,7 +269,7 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
// if first malloc failed, compact and try again // if first malloc failed, compact and try again
if (!dest.valid()) { if (!dest.valid()) {
oxTrace("ox.fs.FileStoreTemplate.write", "Allocation failed, compacting"); oxTrace("ox.fs.FileStoreTemplate.write", "Allocation failed, compacting");
OX_RETURN_ERROR(compact()); oxReturnError(compact());
dest = m_buffer->malloc(dataSize).value; dest = m_buffer->malloc(dataSize).value;
} }
if (dest.valid()) { if (dest.valid()) {
@ -298,14 +298,14 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
dest->id.get(), dest.offset(), destData.size()); dest->id.get(), dest.offset(), destData.size());
fsData->rootNode = dest.offset(); fsData->rootNode = dest.offset();
oxTracef("ox.fs.FileStoreTemplate.write", "Root inode: {}", dest->id.get()); oxTracef("ox.fs.FileStoreTemplate.write", "Root inode: {}", dest->id.get());
return {}; return ox::Error(0);
} }
} else { } else {
oxTrace("ox.fs.FileStoreTemplate.write.fail", "Could not place item due to absence of FileStore header."); oxTrace("ox.fs.FileStoreTemplate.write.fail", "Could not place item due to absence of FileStore header.");
} }
} }
} }
OX_RETURN_ERROR(m_buffer->free(dest)); oxReturnError(m_buffer->free(dest));
} }
return ox::Error(1); return ox::Error(1);
} }
@ -422,30 +422,30 @@ ptrarith::Ptr<uint8_t, std::size_t> FileStoreTemplate<size_t>::read(uint64_t id)
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::resize() { Error FileStoreTemplate<size_t>::resize() {
OX_RETURN_ERROR(compact()); oxReturnError(compact());
const auto newSize = static_cast<std::size_t>(size() - available()); const auto newSize = static_cast<std::size_t>(size() - available());
oxTracef("ox.fs.FileStoreTemplate.resize", "resize to: {}", newSize); oxTracef("ox.fs.FileStoreTemplate.resize", "resize to: {}", newSize);
OX_RETURN_ERROR(m_buffer->setSize(newSize)); oxReturnError(m_buffer->setSize(newSize));
oxTracef("ox.fs.FileStoreTemplate.resize", "resized to: {}", m_buffer->size()); oxTracef("ox.fs.FileStoreTemplate.resize", "resized to: {}", m_buffer->size());
return {}; return ox::Error(0);
} }
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) { Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) {
if (m_buffer->size() > size) { if (m_buffer->size() > size) {
return ox::Error{1, "new buffer is too small for existing data"}; return ox::Error(1);
} }
m_buffSize = static_cast<size_t>(size); m_buffSize = static_cast<size_t>(size);
if (newBuff) { if (newBuff) {
m_buffer = static_cast<Buffer*>(newBuff); m_buffer = reinterpret_cast<Buffer*>(newBuff);
OX_RETURN_ERROR(m_buffer->setSize(static_cast<size_t>(size))); oxReturnError(m_buffer->setSize(static_cast<size_t>(size)));
} }
return {}; return ox::Error(0);
} }
template<typename size_t> template<typename size_t>
Result<StatInfo> FileStoreTemplate<size_t>::stat(uint64_t id) const { Result<StatInfo> FileStoreTemplate<size_t>::stat(uint64_t id) const {
OX_REQUIRE(inode, find(static_cast<size_t>(id)).validate()); oxRequire(inode, find(static_cast<size_t>(id)).validate());
return StatInfo { return StatInfo {
id, id,
inode->links, inode->links,
@ -477,9 +477,9 @@ char *FileStoreTemplate<size_t>::buff() {
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) { Error FileStoreTemplate<size_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) {
for (auto i = m_buffer->iterator(); i.valid(); i.next()) { for (auto i = m_buffer->iterator(); i.valid(); i.next()) {
OX_RETURN_ERROR(cb(i->fileType, i.ptr().offset(), i.ptr().end())); oxReturnError(cb(i->fileType, i.ptr().offset(), i.ptr().end()));
} }
return {}; return ox::Error(0);
} }
template<typename size_t> template<typename size_t>
@ -503,7 +503,7 @@ Error FileStoreTemplate<size_t>::compact() {
return m_buffer->compact([this, &isFirstItem](uint64_t oldAddr, ItemPtr item) -> Error { return m_buffer->compact([this, &isFirstItem](uint64_t oldAddr, ItemPtr item) -> Error {
if (isFirstItem) { if (isFirstItem) {
isFirstItem = false; isFirstItem = false;
return {}; return ox::Error(0);
} }
if (!item.valid()) { if (!item.valid()) {
return ox::Error(1); return ox::Error(1);
@ -524,7 +524,7 @@ Error FileStoreTemplate<size_t>::compact() {
parent->right = item; parent->right = item;
} }
} }
return {}; return ox::Error(0);
}); });
} }
@ -546,13 +546,13 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr item) {
if (!fsData) { if (!fsData) {
return ox::Error(1); return ox::Error(1);
} }
OX_REQUIRE_M(root, m_buffer->ptr(fsData->rootNode).validate()); oxRequireM(root, m_buffer->ptr(fsData->rootNode).validate());
if (root->id == item->id) { if (root->id == item->id) {
fsData->rootNode = item; fsData->rootNode = item;
item->left = root->left; item->left = root->left;
item->right = root->right; item->right = root->right;
oxTracef("ox.fs.FileStoreTemplate.placeItem", "Overwrote Root Item: {}", item->id.get()); oxTracef("ox.fs.FileStoreTemplate.placeItem", "Overwrote Root Item: {}", item->id.get());
return {}; return ox::Error(0);
} else { } else {
return placeItem(root, item); return placeItem(root, item);
} }
@ -573,7 +573,7 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
item->right = right->right; item->right = right->right;
} }
oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get()); oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
return {}; return ox::Error(0);
} else { } else {
return placeItem(right, item, depth + 1); return placeItem(right, item, depth + 1);
} }
@ -586,7 +586,7 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
item->right = left->right; item->right = left->right;
} }
oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get()); oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
return {}; return ox::Error(0);
} else { } else {
return placeItem(left, item, depth + 1); return placeItem(left, item, depth + 1);
} }
@ -602,7 +602,7 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
if (!fsData) { if (!fsData) {
return ox::Error(1); return ox::Error(1);
} }
OX_REQUIRE_M(root, m_buffer->ptr(fsData->rootNode).validate()); oxRequireM(root, m_buffer->ptr(fsData->rootNode).validate());
if (root->id == item->id) { if (root->id == item->id) {
item->left = root->left; item->left = root->left;
item->right = root->right; item->right = root->right;
@ -624,7 +624,7 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
} else { } else {
fsData->rootNode = 0; fsData->rootNode = 0;
} }
return {}; return ox::Error(0);
} else { } else {
return unplaceItem(root, item); return unplaceItem(root, item);
} }
@ -656,20 +656,20 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int dep
return ox::Error(1); return ox::Error(1);
} }
if (item->right) { if (item->right) {
OX_RETURN_ERROR(placeItem(m_buffer->ptr(item->right))); oxReturnError(placeItem(m_buffer->ptr(item->right)));
} }
if (item->left) { if (item->left) {
OX_RETURN_ERROR(placeItem(m_buffer->ptr(item->left))); oxReturnError(placeItem(m_buffer->ptr(item->left)));
} }
return {}; return ox::Error(0);
} }
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::remove(ItemPtr item) { Error FileStoreTemplate<size_t>::remove(ItemPtr item) {
if (item.valid()) { if (item.valid()) {
OX_RETURN_ERROR(unplaceItem(item)); oxReturnError(unplaceItem(item));
OX_RETURN_ERROR(m_buffer->free(item)); oxReturnError(m_buffer->free(item));
return {}; return ox::Error(0);
} }
return ox::Error(1); return ox::Error(1);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -141,7 +141,7 @@ template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::init() noexcept { Error Directory<FileStore, InodeId_t>::init() noexcept {
constexpr auto Size = sizeof(Buffer); constexpr auto Size = sizeof(Buffer);
oxTracef("ox.fs.Directory.init", "Initializing Directory with Inode ID: {}", m_inodeId); oxTracef("ox.fs.Directory.init", "Initializing Directory with Inode ID: {}", m_inodeId);
OX_RETURN_ERROR(m_fs.write(m_inodeId, nullptr, Size, static_cast<uint8_t>(FileType::Directory))); oxReturnError(m_fs.write(m_inodeId, nullptr, Size, static_cast<uint8_t>(FileType::Directory)));
auto buff = m_fs.read(m_inodeId).template to<Buffer>(); auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (!buff.valid()) { if (!buff.valid()) {
m_size = 0; m_size = 0;
@ -158,7 +158,7 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
oxTrace("ox.fs.Directory.mkdir", path.fullPath()); oxTrace("ox.fs.Directory.mkdir", path.fullPath());
// determine if already exists // determine if already exists
ox::StringView name; ox::StringView name;
OX_RETURN_ERROR(path.get(name)); oxReturnError(path.get(name));
auto childInode = find(PathIterator(name)); auto childInode = find(PathIterator(name));
if (!childInode.ok()) { if (!childInode.ok()) {
// if this is not the last item in the path and parents is disabled, // if this is not the last item in the path and parents is disabled,
@ -169,10 +169,10 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
childInode = m_fs.generateInodeId(); childInode = m_fs.generateInodeId();
oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value); oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value);
oxLogError(childInode.error); oxLogError(childInode.error);
OX_RETURN_ERROR(childInode.error); oxReturnError(childInode.error);
// initialize the directory // initialize the directory
Directory<FileStore, InodeId_t> child(m_fs, childInode.value); Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
OX_RETURN_ERROR(child.init()); oxReturnError(child.init());
auto err = write(PathIterator(name), childInode.value); auto err = write(PathIterator(name), childInode.value);
if (err) { if (err) {
oxLogError(err); oxLogError(err);
@ -183,7 +183,7 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
} }
Directory<FileStore, InodeId_t> child(m_fs, childInode.value); Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
if (path.hasNext()) { if (path.hasNext()) {
OX_RETURN_ERROR(child.mkdir(path.next(), parents)); oxReturnError(child.mkdir(path.next(), parents));
} }
} }
return {}; return {};
@ -196,8 +196,8 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
if (path.next().hasNext()) { // not yet at target directory, recurse to next one if (path.next().hasNext()) { // not yet at target directory, recurse to next one
oxTracef("ox.fs.Directory.write", "Attempting to write to next sub-Directory: {} of {}", oxTracef("ox.fs.Directory.write", "Attempting to write to next sub-Directory: {} of {}",
name, path.fullPath()); name, path.fullPath());
OX_RETURN_ERROR(path.get(name)); oxReturnError(path.get(name));
OX_REQUIRE(nextChild, findEntry(name)); oxRequire(nextChild, findEntry(name));
oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild); oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild);
if (nextChild) { if (nextChild) {
return Directory(m_fs, nextChild).write(path.next(), inode); return Directory(m_fs, nextChild).write(path.next(), inode);
@ -207,12 +207,12 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
} }
} else { } else {
oxTrace("ox.fs.Directory.write", path.fullPath()); oxTrace("ox.fs.Directory.write", path.fullPath());
OX_RETURN_ERROR(path.next(name)); oxReturnError(path.next(name));
// insert the new entry on this directory // insert the new entry on this directory
// get the name // get the name
// find existing version of directory // find existing version of directory
oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId); oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId);
OX_REQUIRE(oldStat, m_fs.stat(m_inodeId)); oxRequire(oldStat, m_fs.stat(m_inodeId));
oxTracef("ox.fs.Directory.write", "Found existing directory of size {}", oldStat.size); oxTracef("ox.fs.Directory.write", "Found existing directory of size {}", oldStat.size);
auto old = m_fs.read(m_inodeId).template to<Buffer>(); auto old = m_fs.read(m_inodeId).template to<Buffer>();
if (!old.valid()) { if (!old.valid()) {
@ -227,14 +227,14 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory"); oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory");
return ox::Error(1, "Could not allocate memory for copy of Directory"); return ox::Error(1, "Could not allocate memory for copy of Directory");
} }
OX_RETURN_ERROR(cpy->setSize(newSize)); oxReturnError(cpy->setSize(newSize));
auto val = cpy->malloc(entryDataSize).value; auto val = cpy->malloc(entryDataSize).value;
if (!val.valid()) { if (!val.valid()) {
oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry"); oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry");
return ox::Error(1, "Could not allocate memory for new directory entry"); return ox::Error(1, "Could not allocate memory for new directory entry");
} }
oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name); oxTracef("ox.fs.Directory.write", "Attempting to write Directory entry: {}", name);
OX_RETURN_ERROR(val->init(inode, name, val.size())); oxReturnError(val->init(inode, name, val.size()));
return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast<uint8_t>(FileType::Directory)); return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast<uint8_t>(FileType::Directory));
} }
} }
@ -242,7 +242,7 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
template<typename FileStore, typename InodeId_t> template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept { Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
ox::StringView name; ox::StringView name;
OX_RETURN_ERROR(path.get(name)); oxReturnError(path.get(name));
oxTrace("ox.fs.Directory.remove", name); oxTrace("ox.fs.Directory.remove", name);
auto buff = m_fs.read(m_inodeId).template to<Buffer>(); auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (buff.valid()) { if (buff.valid()) {
@ -251,7 +251,7 @@ Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
auto data = i->data(); auto data = i->data();
if (data.valid()) { if (data.valid()) {
if (name == data->name) { if (name == data->name) {
OX_RETURN_ERROR(buff->free(i)); oxReturnError(buff->free(i));
} }
} else { } else {
oxTrace("ox.fs.Directory.remove", "INVALID DIRECTORY ENTRY"); oxTrace("ox.fs.Directory.remove", "INVALID DIRECTORY ENTRY");
@ -277,7 +277,7 @@ Error Directory<FileStore, InodeId_t>::ls(F cb) noexcept {
for (auto i = buff->iterator(); i.valid(); i.next()) { for (auto i = buff->iterator(); i.valid(); i.next()) {
auto data = i->data(); auto data = i->data();
if (data.valid()) { if (data.valid()) {
OX_RETURN_ERROR(cb(data->name, data->inode)); oxReturnError(cb(data->name, data->inode));
} else { } else {
oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY"); oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY");
} }
@ -314,8 +314,8 @@ template<typename FileStore, typename InodeId_t>
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path) const noexcept { Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path) const noexcept {
// determine if already exists // determine if already exists
ox::StringView name; ox::StringView name;
OX_RETURN_ERROR(path.get(name)); oxReturnError(path.get(name));
OX_REQUIRE(v, findEntry(name)); oxRequire(v, findEntry(name));
// recurse if not at end of path // recurse if not at end of path
if (auto p = path.next(); p.valid()) { if (auto p = path.next(); p.valid()) {
Directory dir(m_fs, v); Directory dir(m_fs, v);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -31,10 +31,10 @@ FileAddress::FileAddress(uint64_t inode) noexcept {
FileAddress::FileAddress(ox::StringViewCR path) noexcept { FileAddress::FileAddress(ox::StringViewCR path) noexcept {
auto pathSize = path.bytes(); auto pathSize = path.bytes();
m_data.path = new char[pathSize + 1]; m_data.path = new char[pathSize + 1];
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
memcpy(m_data.path, path.data(), pathSize); memcpy(m_data.path, path.data(), pathSize);
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
m_data.path[pathSize] = 0; m_data.path[pathSize] = 0;
OX_ALLOW_UNSAFE_BUFFERS_END OX_CLANG_NOWARN_END
m_type = FileAddressType::Path; m_type = FileAddressType::Path;
} }
@ -48,11 +48,9 @@ FileAddress &FileAddress::operator=(const FileAddress &other) noexcept {
case FileAddressType::Path: case FileAddressType::Path:
{ {
if (other.m_data.path) { if (other.m_data.path) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
auto strSize = ox::strlen(other.m_data.path) + 1; auto strSize = ox::strlen(other.m_data.path) + 1;
m_data.path = new char[strSize]; m_data.path = new char[strSize];
ox::memcpy(m_data.path, other.m_data.path, strSize); ox::memcpy(m_data.path, other.m_data.path, strSize);
OX_ALLOW_UNSAFE_BUFFERS_END
} else { } else {
m_data.constPath = ""; m_data.constPath = "";
m_type = FileAddressType::ConstPath; m_type = FileAddressType::ConstPath;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -24,6 +24,9 @@ enum class FileAddressType: int8_t {
Inode, Inode,
}; };
template<typename T>
constexpr Error model(T *h, CommonPtrWith<class FileAddress> auto *fa) noexcept;
class FileAddress { class FileAddress {
template<typename T> template<typename T>
@ -151,29 +154,29 @@ constexpr const char *getModelTypeName<FileAddress>() noexcept {
template<typename T> template<typename T>
constexpr Error model(T *h, CommonPtrWith<FileAddress::Data> auto *obj) noexcept { constexpr Error model(T *h, CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
OX_RETURN_ERROR(h->template setTypeInfo<FileAddress::Data>()); oxReturnError(h->template setTypeInfo<FileAddress::Data>());
OX_RETURN_ERROR(h->fieldCString("path", &obj->path)); oxReturnError(h->fieldCString("path", &obj->path));
OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path)); oxReturnError(h->fieldCString("constPath", &obj->path));
OX_RETURN_ERROR(h->field("inode", &obj->inode)); oxReturnError(h->field("inode", &obj->inode));
return {}; return {};
} }
template<typename T> template<typename T>
constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept { constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
OX_RETURN_ERROR(h->template setTypeInfo<FileAddress>()); oxReturnError(h->template setTypeInfo<FileAddress>());
if constexpr(T::opType() == OpType::Reflect) { if constexpr(T::opType() == OpType::Reflect) {
int8_t type = -1; int8_t type = -1;
OX_RETURN_ERROR(h->field("type", &type)); oxReturnError(h->field("type", &type));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, type))); oxReturnError(h->field("data", UnionView(&fa->m_data, type)));
} else if constexpr(T::opType() == OpType::Read) { } else if constexpr(T::opType() == OpType::Read) {
auto type = static_cast<int8_t>(fa->m_type); auto type = static_cast<int8_t>(fa->m_type);
OX_RETURN_ERROR(h->field("type", &type)); oxReturnError(h->field("type", &type));
fa->m_type = static_cast<FileAddressType>(type); fa->m_type = static_cast<FileAddressType>(type);
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type)))); oxReturnError(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
} else if constexpr(T::opType() == OpType::Write) { } else if constexpr(T::opType() == OpType::Write) {
auto const type = static_cast<int8_t>(fa->m_type); auto const type = static_cast<int8_t>(fa->m_type);
OX_RETURN_ERROR(h->field("type", &type)); oxReturnError(h->field("type", &type));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type)))); oxReturnError(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
} }
return {}; return {};
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -37,69 +37,42 @@ Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size)
} }
} }
Result<Buffer> FileSystem::read(FileAddress const &addr, size_t const size) noexcept {
Result<Buffer> out;
out.value.resize(size);
switch (addr.type()) {
case FileAddressType::Inode:
OX_RETURN_ERROR(readFileInode(addr.getInode().value, out.value.data(), size));
break;
case FileAddressType::ConstPath:
case FileAddressType::Path:
OX_RETURN_ERROR(readFilePath(StringView{addr.getPath().value}, out.value.data(), size));
break;
default:
return ox::Error{1};
}
return out;
}
Result<Buffer> FileSystem::read(StringViewCR path, size_t const size) noexcept {
Result<Buffer> out;
out.value.resize(size);
OX_RETURN_ERROR(readFilePath(path, out.value.data(), size));
return out;
}
Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept { Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
OX_REQUIRE(s, stat(addr)); oxRequire(s, stat(addr));
Buffer buff(static_cast<std::size_t>(s.size)); Buffer buff(static_cast<std::size_t>(s.size));
OX_RETURN_ERROR(read(addr, buff.data(), buff.size())); oxReturnError(read(addr, buff.data(), buff.size()));
return buff; return buff;
} }
Result<Buffer> FileSystem::read(StringViewCR path) noexcept { Result<Buffer> FileSystem::read(StringViewCR path) noexcept {
OX_REQUIRE(s, statPath(path)); oxRequire(s, statPath(path));
Buffer buff(static_cast<std::size_t>(s.size)); Buffer buff(static_cast<std::size_t>(s.size));
OX_RETURN_ERROR(readFilePath(path, buff.data(), buff.size())); oxReturnError(readFilePath(path, buff.data(), buff.size()));
return buff; return buff;
} }
Error FileSystem::read( Error FileSystem::read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept {
FileAddress const &addr,
std::size_t const readStart,
std::size_t const readSize,
void *buffer,
std::size_t *size) noexcept {
switch (addr.type()) { switch (addr.type()) {
case FileAddressType::Inode: case FileAddressType::Inode:
return readFileInodeRange(addr.getInode().value, readStart, readSize, buffer, size); return read(addr.getInode().value, readStart, readSize, buffer, size);
case FileAddressType::ConstPath: case FileAddressType::ConstPath:
case FileAddressType::Path: case FileAddressType::Path:
return readFilePathRange(addr.getPath().value, readStart, readSize, buffer, size); return ox::Error(2, "Unsupported for path lookups");
default: default:
return ox::Error(1); return ox::Error(1);
} }
} }
Result<size_t> FileSystem::read( Error FileSystem::remove(const FileAddress &addr, bool recursive) noexcept {
StringViewCR path, switch (addr.type()) {
std::size_t const readStart, case FileAddressType::Inode:
std::size_t const readSize, return remove(addr.getInode().value, recursive);
Span<char> buff) noexcept { case FileAddressType::ConstPath:
size_t szOut{buff.size()}; case FileAddressType::Path:
OX_RETURN_ERROR(readFilePathRange(path, readStart, readSize, buff.data(), &szOut)); return remove(StringView(addr.getPath().value), recursive);
return szOut; default:
return ox::Error(1);
}
} }
Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept { Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -20,7 +20,7 @@
namespace ox { namespace ox {
namespace detail { namespace detail {
inline void fsBuffFree(char *buff) noexcept { static inline void fsBuffFree(char *buff) noexcept {
safeDelete(buff); safeDelete(buff);
} }
} }
@ -41,45 +41,25 @@ class FileSystem {
Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept; Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept;
Result<Buffer> read(FileAddress const &addr, size_t size) noexcept;
Result<Buffer> read(StringViewCR path, size_t size) noexcept;
Result<Buffer> read(const FileAddress &addr) noexcept; Result<Buffer> read(const FileAddress &addr) noexcept;
Result<Buffer> read(StringViewCR path) noexcept; Result<Buffer> read(StringViewCR path) noexcept;
Error read(StringViewCR path, void *buffer, std::size_t buffSize) noexcept { inline Error read(StringViewCR path, void *buffer, std::size_t buffSize) noexcept {
return readFilePath(path, buffer, buffSize); return readFilePath(path, buffer, buffSize);
} }
Error read(uint64_t inode, void *buffer, std::size_t buffSize) noexcept { inline Error read(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
return readFileInode(inode, buffer, buffSize); return readFileInode(inode, buffer, buffSize);
} }
Error read( Error read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept;
FileAddress const &addr,
size_t readStart,
size_t readSize,
void *buffer,
size_t *size) noexcept;
/**
*
* @param path
* @param readStart
* @param readSize
* @param buff
* @return error or number of bytes read
*/
Result<size_t> read(
StringViewCR path, size_t readStart, size_t readSize, ox::Span<char> buff) noexcept;
virtual Result<Vector<String>> ls(StringViewCR dir) const noexcept = 0; virtual Result<Vector<String>> ls(StringViewCR dir) const noexcept = 0;
Error remove(StringViewCR path, bool recursive = false) noexcept { virtual Error remove(StringViewCR path, bool recursive) noexcept = 0;
return removePath(path, recursive);
} Error remove(const FileAddress &addr, bool recursive = false) noexcept;
virtual Error resize(uint64_t size, void *buffer) noexcept = 0; virtual Error resize(uint64_t size, void *buffer) noexcept = 0;
@ -101,36 +81,36 @@ class FileSystem {
Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept; Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept;
Error write(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept { inline Error write(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept {
return writeFilePath(path, buffer, size, fileType); return writeFilePath(path, buffer, size, fileType);
} }
Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept { inline Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
return writeFileInode(inode, buffer, size, fileType); return writeFileInode(inode, buffer, size, fileType);
} }
Result<FileStat> stat(uint64_t inode) const noexcept { inline Result<FileStat> stat(uint64_t inode) const noexcept {
return statInode(inode); return statInode(inode);
} }
Result<FileStat> stat(StringViewCR path) const noexcept { inline Result<FileStat> stat(StringViewCR path) const noexcept {
return statPath(path); return statPath(path);
} }
Result<FileStat> stat(const FileAddress &addr) const noexcept; Result<FileStat> stat(const FileAddress &addr) const noexcept;
[[nodiscard]] [[nodiscard]]
bool exists(uint64_t inode) const noexcept { inline bool exists(uint64_t inode) const noexcept {
return statInode(inode).ok(); return statInode(inode).ok();
} }
[[nodiscard]] [[nodiscard]]
bool exists(ox::StringView path) const noexcept { inline bool exists(ox::StringView path) const noexcept {
return statPath(path).ok(); return statPath(path).ok();
} }
[[nodiscard]] [[nodiscard]]
bool exists(FileAddress const&addr) const noexcept { inline bool exists(FileAddress const&addr) const noexcept {
return stat(addr).ok(); return stat(addr).ok();
} }
@ -160,12 +140,7 @@ class FileSystem {
virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0; virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0;
virtual Error readFilePathRange( virtual Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept = 0;
StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept = 0;
virtual Error readFileInodeRange(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) noexcept = 0;
virtual Error removePath(StringViewCR path, bool recursive) noexcept = 0;
virtual Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0; virtual Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
@ -177,11 +152,11 @@ class MemFS: public FileSystem {
public: public:
Result<const char*> directAccess(const FileAddress &addr) const noexcept; Result<const char*> directAccess(const FileAddress &addr) const noexcept;
Result<const char*> directAccess(StringViewCR path) const noexcept { inline Result<const char*> directAccess(StringViewCR path) const noexcept {
return directAccessPath(path); return directAccessPath(path);
} }
Result<const char*> directAccess(uint64_t inode) const noexcept { inline Result<const char*> directAccess(uint64_t inode) const noexcept {
return directAccessInode(inode); return directAccessInode(inode);
} }
@ -234,11 +209,6 @@ class FileSystemTemplate: public MemFS {
Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
Error readFilePathRange(
StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override;
Error removePath(StringViewCR path, bool recursive) noexcept override;
Result<const char*> directAccessInode(uint64_t) const noexcept override; Result<const char*> directAccessInode(uint64_t) const noexcept override;
Result<Vector<String>> ls(StringViewCR dir) const noexcept override; Result<Vector<String>> ls(StringViewCR dir) const noexcept override;
@ -246,6 +216,8 @@ class FileSystemTemplate: public MemFS {
template<typename F> template<typename F>
Error ls(StringViewCR path, F cb) const; Error ls(StringViewCR path, F cb) const;
Error remove(StringViewCR path, bool recursive) noexcept override;
/** /**
* Resizes FileSystem to minimum possible size. * Resizes FileSystem to minimum possible size.
*/ */
@ -312,49 +284,49 @@ FileSystemTemplate<FileStore, Directory>::~FileSystemTemplate() noexcept {
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::format(void *buff, uint64_t buffSize) noexcept { Error FileSystemTemplate<FileStore, Directory>::format(void *buff, uint64_t buffSize) noexcept {
OX_RETURN_ERROR(FileStore::format(buff, static_cast<size_t>(buffSize))); oxReturnError(FileStore::format(buff, static_cast<size_t>(buffSize)));
FileStore fs(buff, static_cast<size_t>(buffSize)); FileStore fs(buff, static_cast<size_t>(buffSize));
constexpr auto rootDirInode = MaxValue<typename FileStore::InodeId_t> / 2; constexpr auto rootDirInode = MaxValue<typename FileStore::InodeId_t> / 2;
Directory rootDir(fs, rootDirInode); Directory rootDir(fs, rootDirInode);
OX_RETURN_ERROR(rootDir.init()); oxReturnError(rootDir.init());
FileSystemData fd; FileSystemData fd;
fd.rootDirInode = rootDirInode; fd.rootDirInode = rootDirInode;
oxTracef("ox.fs.FileSystemTemplate.format", "rootDirInode: {}", fd.rootDirInode.get()); oxTracef("ox.fs.FileSystemTemplate.format", "rootDirInode: {}", fd.rootDirInode.get());
OX_RETURN_ERROR(fs.write(InodeFsData, &fd, sizeof(fd))); oxReturnError(fs.write(InodeFsData, &fd, sizeof(fd)));
if (!fs.read(fd.rootDirInode).valid()) { if (!fs.read(fd.rootDirInode).valid()) {
oxTrace("ox.fs.FileSystemTemplate.format.error", "FileSystemTemplate::format did not correctly create root directory"); oxTrace("ox.fs.FileSystemTemplate.format.error", "FileSystemTemplate::format did not correctly create root directory");
return ox::Error(1); return ox::Error(1);
} }
return {}; return ox::Error(0);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::mkdir(StringViewCR path, bool recursive) noexcept { Error FileSystemTemplate<FileStore, Directory>::mkdir(StringViewCR path, bool recursive) noexcept {
oxTracef("ox.fs.FileSystemTemplate.mkdir", "path: {}, recursive: {}", path, recursive); oxTracef("ox.fs.FileSystemTemplate.mkdir", "path: {}, recursive: {}", path, recursive);
OX_REQUIRE_M(rootDir, this->rootDir()); oxRequireM(rootDir, this->rootDir());
return rootDir.mkdir(path, recursive); return rootDir.mkdir(path, recursive);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::move(StringViewCR src, StringViewCR dest) noexcept { Error FileSystemTemplate<FileStore, Directory>::move(StringViewCR src, StringViewCR dest) noexcept {
OX_REQUIRE(fd, fileSystemData()); oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode); Directory rootDir(m_fs, fd.rootDirInode);
OX_REQUIRE_M(inode, rootDir.find(src)); oxRequireM(inode, rootDir.find(src));
OX_RETURN_ERROR(rootDir.write(dest, inode)); oxReturnError(rootDir.write(dest, inode));
OX_RETURN_ERROR(rootDir.remove(src)); oxReturnError(rootDir.remove(src));
return {}; return ox::Error(0);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept { Error FileSystemTemplate<FileStore, Directory>::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept {
oxTrace("ox.fs.FileSystemTemplate.readFilePath", path); oxTrace("ox.fs.FileSystemTemplate.readFilePath", path);
OX_REQUIRE(fd, fileSystemData()); oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode); Directory rootDir(m_fs, fd.rootDirInode);
OX_REQUIRE(s, stat(path)); oxRequire(s, stat(path));
if (s.size > buffSize) { if (s.size > buffSize) {
return ox::Error(1, "Buffer to small to load file"); return ox::Error(1, "Buffer to small to load file");
} }
@ -363,16 +335,16 @@ Error FileSystemTemplate<FileStore, Directory>::readFilePath(StringViewCR path,
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessPath(StringViewCR path) const noexcept { Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessPath(StringViewCR path) const noexcept {
OX_REQUIRE(fd, fileSystemData()); oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode); Directory rootDir(m_fs, fd.rootDirInode);
OX_REQUIRE(inode, rootDir.find(path)); oxRequire(inode, rootDir.find(path));
return directAccessInode(inode); return directAccessInode(inode);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept { Error FileSystemTemplate<FileStore, Directory>::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
oxTracef("ox.fs.FileSystemTemplate.readFileInode", "{}", inode); oxTracef("ox.fs.FileSystemTemplate.readFileInode", "{}", inode);
OX_REQUIRE(s, stat(inode)); oxRequire(s, stat(inode));
if (s.size > buffSize) { if (s.size > buffSize) {
return ox::Error(1, "Buffer to small to load file"); return ox::Error(1, "Buffer to small to load file");
} }
@ -384,32 +356,6 @@ Error FileSystemTemplate<FileStore, Directory>::readFileInodeRange(uint64_t inod
return m_fs.read(inode, readStart, readSize, reinterpret_cast<uint8_t*>(buffer), size); return m_fs.read(inode, readStart, readSize, reinterpret_cast<uint8_t*>(buffer), size);
} }
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::readFilePathRange(
StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept {
OX_REQUIRE(s, stat(path));
return readFileInodeRange(s.inode, readStart, readSize, buffer, buffSize);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::removePath(StringViewCR path, bool recursive) noexcept {
OX_REQUIRE(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
OX_REQUIRE(inode, rootDir.find(path));
OX_REQUIRE(st, statInode(inode));
if (st.fileType == FileType::NormalFile || recursive) {
if (auto err = rootDir.remove(path)) {
// removal failed, try putting the index back
oxLogError(rootDir.write(path, inode));
return err;
}
} else {
oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting.");
return ox::Error(1);
}
return {};
}
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept { Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept {
auto data = m_fs.read(inode); auto data = m_fs.read(inode);
@ -422,9 +368,9 @@ Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<Vector<String>> FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path) const noexcept { Result<Vector<String>> FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path) const noexcept {
Vector<String> out; Vector<String> out;
OX_RETURN_ERROR(ls(path, [&out](StringViewCR name, typename FileStore::InodeId_t) { oxReturnError(ls(path, [&out](StringViewCR name, typename FileStore::InodeId_t) {
out.emplace_back(name); out.emplace_back(name);
return ox::Error{}; return ox::Error(0);
})); }));
return out; return out;
} }
@ -433,11 +379,30 @@ template<typename FileStore, typename Directory>
template<typename F> template<typename F>
Error FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path, F cb) const { Error FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path, F cb) const {
oxTracef("ox.fs.FileSystemTemplate.ls", "path: {}", path); oxTracef("ox.fs.FileSystemTemplate.ls", "path: {}", path);
OX_REQUIRE(s, stat(path)); oxRequire(s, stat(path));
Directory dir(m_fs, s.inode); Directory dir(m_fs, s.inode);
return dir.ls(cb); return dir.ls(cb);
} }
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::remove(StringViewCR path, bool recursive) noexcept {
oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(inode, rootDir.find(path));
oxRequire(st, statInode(inode));
if (st.fileType == FileType::NormalFile || recursive) {
if (auto err = rootDir.remove(path)) {
// removal failed, try putting the index back
oxLogError(rootDir.write(path, inode));
return err;
}
} else {
oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting.");
return ox::Error(1);
}
return ox::Error(0);
}
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::resize() noexcept { Error FileSystemTemplate<FileStore, Directory>::resize() noexcept {
return m_fs.resize(); return m_fs.resize();
@ -445,7 +410,7 @@ Error FileSystemTemplate<FileStore, Directory>::resize() noexcept {
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::resize(uint64_t size, void *buffer) noexcept { Error FileSystemTemplate<FileStore, Directory>::resize(uint64_t size, void *buffer) noexcept {
OX_RETURN_ERROR(m_fs.resize(static_cast<size_t>(size), buffer)); oxReturnError(m_fs.resize(static_cast<size_t>(size), buffer));
return {}; return {};
} }
@ -458,23 +423,23 @@ Error FileSystemTemplate<FileStore, Directory>::writeFilePath(
oxTrace("ox.fs.FileSystemTemplate.writeFilePath", path); oxTrace("ox.fs.FileSystemTemplate.writeFilePath", path);
auto [inode, err] = find(path); auto [inode, err] = find(path);
if (err) { if (err) {
OX_RETURN_ERROR(m_fs.generateInodeId().moveTo(inode)); oxReturnError(m_fs.generateInodeId().moveTo(inode));
OX_REQUIRE_M(rootDir, this->rootDir()); oxRequireM(rootDir, this->rootDir());
OX_RETURN_ERROR(rootDir.write(path, inode)); oxReturnError(rootDir.write(path, inode));
} }
OX_RETURN_ERROR(writeFileInode(inode, buffer, size, fileType)); oxReturnError(writeFileInode(inode, buffer, size, fileType));
return {}; return {};
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept { Error FileSystemTemplate<FileStore, Directory>::writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
oxTrace("ox.fs.FileSystemTemplate.writeFileInode", ox::intToStr(inode)); oxTrace("ox.fs.FileSystemTemplate.writeFileInode", ox::itoa(inode));
return m_fs.write(inode, buffer, static_cast<size_t>(size), static_cast<uint8_t>(fileType)); return m_fs.write(inode, buffer, static_cast<size_t>(size), static_cast<uint8_t>(fileType));
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t inode) const noexcept { Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t inode) const noexcept {
OX_REQUIRE(s, m_fs.stat(inode)); oxRequire(s, m_fs.stat(inode));
FileStat out; FileStat out;
out.inode = s.inode; out.inode = s.inode;
out.links = s.links; out.links = s.links;
@ -485,7 +450,7 @@ Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t in
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<FileStat> FileSystemTemplate<FileStore, Directory>::statPath(StringViewCR path) const noexcept { Result<FileStat> FileSystemTemplate<FileStore, Directory>::statPath(StringViewCR path) const noexcept {
OX_REQUIRE(inode, find(path)); oxRequire(inode, find(path));
return stat(inode); return stat(inode);
} }
@ -522,25 +487,25 @@ bool FileSystemTemplate<FileStore, Directory>::valid() const noexcept {
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<typename FileSystemTemplate<FileStore, Directory>::FileSystemData> FileSystemTemplate<FileStore, Directory>::fileSystemData() const noexcept { Result<typename FileSystemTemplate<FileStore, Directory>::FileSystemData> FileSystemTemplate<FileStore, Directory>::fileSystemData() const noexcept {
FileSystemData fd; FileSystemData fd;
OX_RETURN_ERROR(m_fs.read(InodeFsData, &fd, sizeof(fd))); oxReturnError(m_fs.read(InodeFsData, &fd, sizeof(fd)));
return fd; return fd;
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<uint64_t> FileSystemTemplate<FileStore, Directory>::find(StringViewCR path) const noexcept { Result<uint64_t> FileSystemTemplate<FileStore, Directory>::find(StringViewCR path) const noexcept {
OX_REQUIRE(fd, fileSystemData()); oxRequire(fd, fileSystemData());
// return root as a special case // return root as a special case
if (path == "/") { if (path == "/") {
return static_cast<uint64_t>(fd.rootDirInode); return static_cast<uint64_t>(fd.rootDirInode);
} }
Directory rootDir(m_fs, fd.rootDirInode); Directory rootDir(m_fs, fd.rootDirInode);
OX_REQUIRE(out, rootDir.find(path)); oxRequire(out, rootDir.find(path));
return static_cast<uint64_t>(out); return static_cast<uint64_t>(out);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<Directory> FileSystemTemplate<FileStore, Directory>::rootDir() const noexcept { Result<Directory> FileSystemTemplate<FileStore, Directory>::rootDir() const noexcept {
OX_REQUIRE(fd, fileSystemData()); oxRequire(fd, fileSystemData());
return Directory(m_fs, fd.rootDirInode); return Directory(m_fs, fd.rootDirInode);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -39,7 +39,7 @@ Error PassThroughFS::mkdir(StringViewCR path, bool recursive) noexcept {
success = true; success = true;
} else { } else {
success = std::filesystem::create_directories(p, ec); success = std::filesystem::create_directories(p, ec);
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed")); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
} }
} else { } else {
std::error_code ec; std::error_code ec;
@ -48,7 +48,7 @@ Error PassThroughFS::mkdir(StringViewCR path, bool recursive) noexcept {
success = true; success = true;
} else { } else {
success = std::filesystem::create_directory(p, ec); success = std::filesystem::create_directory(p, ec);
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed")); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
} }
} }
return ox::Error(success ? 0 : 1); return ox::Error(success ? 0 : 1);
@ -60,14 +60,14 @@ Error PassThroughFS::move(StringViewCR src, StringViewCR dest) noexcept {
if (ec.value()) { if (ec.value()) {
return ox::Error(1); return ox::Error(1);
} }
return {}; return ox::Error(0);
} }
Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept { Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept {
Vector<String> out; Vector<String> out;
std::error_code ec; std::error_code ec;
const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec); const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed")); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
for (const auto &p : di) { for (const auto &p : di) {
const auto u8p = p.path().filename().u8string(); const auto u8p = p.path().filename().u8string();
out.emplace_back(reinterpret_cast<const char*>(u8p.c_str())); out.emplace_back(reinterpret_cast<const char*>(u8p.c_str()));
@ -75,6 +75,14 @@ Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept {
return out; return out;
} }
Error PassThroughFS::remove(StringViewCR path, bool recursive) noexcept {
if (recursive) {
return ox::Error(std::filesystem::remove_all(m_path / stripSlash(path)) != 0);
} else {
return ox::Error(std::filesystem::remove(m_path / stripSlash(path)) != 0);
}
}
Error PassThroughFS::resize(uint64_t, void*) noexcept { Error PassThroughFS::resize(uint64_t, void*) noexcept {
// unsupported // unsupported
return ox::Error(1, "resize is not supported by PassThroughFS"); return ox::Error(1, "resize is not supported by PassThroughFS");
@ -93,9 +101,7 @@ Result<FileStat> PassThroughFS::statPath(StringViewCR path) const noexcept {
oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path); oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path);
const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec); const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size); oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size);
if (auto err = ec.value()) { oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: stat failed"));
return ox::Error{static_cast<ox::ErrorCode>(err), "PassThroughFS: stat failed"};
}
return FileStat{0, 0, size, type}; return FileStat{0, 0, size, type};
} }
@ -106,14 +112,14 @@ uint64_t PassThroughFS::spaceNeeded(uint64_t size) const noexcept {
Result<uint64_t> PassThroughFS::available() const noexcept { Result<uint64_t> PassThroughFS::available() const noexcept {
std::error_code ec; std::error_code ec;
const auto s = std::filesystem::space(m_path, ec); const auto s = std::filesystem::space(m_path, ec);
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size")); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
return s.available; return s.available;
} }
Result<uint64_t> PassThroughFS::size() const noexcept { Result<uint64_t> PassThroughFS::size() const noexcept {
std::error_code ec; std::error_code ec;
const auto s = std::filesystem::space(m_path, ec); const auto s = std::filesystem::space(m_path, ec);
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size")); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
return s.capacity; return s.capacity;
} }
@ -148,7 +154,7 @@ Error PassThroughFS::readFilePath(StringViewCR path, void *buffer, std::size_t b
oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what()); oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what());
return ox::Error(2); return ox::Error(2);
} }
return {}; return ox::Error(0);
} }
Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept { Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept {
@ -156,38 +162,11 @@ Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept {
return ox::Error(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS"); return ox::Error(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS");
} }
Error PassThroughFS::readFilePathRange(
StringViewCR path, size_t const readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept {
try {
std::ifstream file(m_path / stripSlash(path), std::ios::binary | std::ios::ate);
auto const size = static_cast<size_t>(file.tellg());
readSize = ox::min(readSize, size);
file.seekg(static_cast<off_t>(readStart), std::ios::beg);
if (readSize > *buffSize) {
oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path);
return ox::Error{1};
}
file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(readSize));
return {};
} catch (std::fstream::failure const &f) {
oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what());
return ox::Error{2};
}
}
Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept { Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
// unsupported // unsupported
return ox::Error(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS"); return ox::Error(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS");
} }
Error PassThroughFS::removePath(StringViewCR path, bool const recursive) noexcept {
if (recursive) {
return ox::Error{std::filesystem::remove_all(m_path / stripSlash(path)) == 0};
} else {
return ox::Error{!std::filesystem::remove(m_path / stripSlash(path))};
}
}
Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept { Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept {
const auto p = (m_path / stripSlash(path)); const auto p = (m_path / stripSlash(path));
try { try {
@ -197,7 +176,7 @@ Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64
oxTracef("ox.fs.PassThroughFS.read.error", "Write of {} failed: {}", path, f.what()); oxTracef("ox.fs.PassThroughFS.read.error", "Write of {} failed: {}", path, f.what());
return ox::Error(1); return ox::Error(1);
} }
return {}; return ox::Error(0);
} }
Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) noexcept { Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) noexcept {
@ -206,7 +185,8 @@ Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) n
} }
std::string_view PassThroughFS::stripSlash(StringView path) noexcept { std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
for (auto i = 0u; i < path.len() && path[0] == '/'; i++) { const auto pathLen = ox::strlen(path);
for (auto i = 0u; i < pathLen && path[0] == '/'; i++) {
path = substr(path, 1); path = substr(path, 1);
} }
return {path.data(), path.bytes()}; return {path.data(), path.bytes()};

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -45,6 +45,8 @@ class PassThroughFS: public FileSystem {
template<typename F> template<typename F>
Error ls(StringViewCR dir, F cb) const noexcept; Error ls(StringViewCR dir, F cb) const noexcept;
Error remove(StringViewCR path, bool recursive) noexcept override;
Error resize(uint64_t size, void *buffer) noexcept override; Error resize(uint64_t size, void *buffer) noexcept override;
Result<FileStat> statInode(uint64_t inode) const noexcept override; Result<FileStat> statInode(uint64_t inode) const noexcept override;
@ -71,13 +73,8 @@ class PassThroughFS: public FileSystem {
Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override; Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
Error readFilePathRange(
StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override;
Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
Error removePath(StringViewCR path, bool recursive) noexcept override;
Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override; Error writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override; Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
@ -95,11 +92,11 @@ template<typename F>
Error PassThroughFS::ls(StringViewCR dir, F cb) const noexcept { Error PassThroughFS::ls(StringViewCR dir, F cb) const noexcept {
std::error_code ec; std::error_code ec;
const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec); const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed")); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
for (auto &p : di) { for (auto &p : di) {
OX_RETURN_ERROR(cb(p.path().filename().c_str(), 0)); oxReturnError(cb(p.path().filename().c_str(), 0));
} }
return {}; return ox::Error(0);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -36,7 +36,7 @@ Error PathIterator::dirPath(char *out, std::size_t outSize) {
if (idx >= 0 && size < outSize) { if (idx >= 0 && size < outSize) {
ox::memcpy(out, m_path, size); ox::memcpy(out, m_path, size);
out[size] = 0; out[size] = 0;
return {}; return ox::Error(0);
} else { } else {
return ox::Error(1); return ox::Error(1);
} }
@ -85,7 +85,7 @@ Error PathIterator::next(StringView &fileName) {
std::size_t size = 0; std::size_t size = 0;
auto retval = ox::Error(1); auto retval = ox::Error(1);
if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) { if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
retval = {}; retval = ox::Error(0);
if (m_path[m_iterator] == '/') { if (m_path[m_iterator] == '/') {
m_iterator++; m_iterator++;
} }
@ -118,7 +118,7 @@ Result<std::size_t> PathIterator::nextSize() const {
auto retval = ox::Error(1); auto retval = ox::Error(1);
auto it = m_iterator; auto it = m_iterator;
if (it < m_maxSize && ox::strlen(&m_path[it])) { if (it < m_maxSize && ox::strlen(&m_path[it])) {
retval = {}; retval = ox::Error(0);
if (m_path[it] == '/') { if (m_path[it] == '/') {
it++; it++;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -354,7 +354,7 @@ Error NodeBuffer<size_t, Item>::free(ItemPtr item) noexcept {
} }
} }
m_header.bytesUsed -= item.size(); m_header.bytesUsed -= item.size();
return {}; return ox::Error(0);
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
@ -370,7 +370,7 @@ Error NodeBuffer<size_t, Item>::setSize(std::size_t size) noexcept {
m_header.size = static_cast<size_t>(size); m_header.size = static_cast<size_t>(size);
auto data = reinterpret_cast<uint8_t*>(this) + end; auto data = reinterpret_cast<uint8_t*>(this) + end;
ox::memset(data, 0, size - end); ox::memset(data, 0, size - end);
return {}; return ox::Error(0);
} }
} }
@ -408,7 +408,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
} }
// move node // move node
ox::memcpy(dest, src, src->fullSize()); ox::memcpy(dest, src, src->fullSize());
OX_RETURN_ERROR(cb(src, dest)); oxReturnError(cb(src, dest));
// update surrounding nodes // update surrounding nodes
auto prev = ptr(dest->prev); auto prev = ptr(dest->prev);
if (prev.valid()) { if (prev.valid()) {
@ -422,7 +422,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
src = ptr(dest->next); src = ptr(dest->next);
dest = uninitializedPtr(dest.offset() + dest->fullSize()); dest = uninitializedPtr(dest.offset() + dest->fullSize());
} }
return {}; return ox::Error(0);
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -119,9 +119,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag"); auto constexpr path = ox::StringLiteral("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path"); oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
OX_ALLOW_UNSAFE_BUFFERS_END
return ox::Error(0); return ox::Error(0);
} }
}, },
@ -129,9 +127,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
"PathIterator::hasNext", "PathIterator::hasNext",
[](ox::StringView) { [](ox::StringView) {
const auto path = "/file1"; const auto path = "/file1";
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
ox::PathIterator it(path, ox::strlen(path)); ox::PathIterator it(path, ox::strlen(path));
OX_ALLOW_UNSAFE_BUFFERS_END
oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext"); oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext");
oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext"); oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext");
return ox::Error(0); return ox::Error(0);
@ -167,11 +163,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
[](ox::StringView) { [](ox::StringView) {
constexpr auto buffLen = 5000; constexpr auto buffLen = 5000;
constexpr auto str1 = "Hello, World!"; constexpr auto str1 = "Hello, World!";
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
constexpr auto str1Len = ox::strlen(str1) + 1; constexpr auto str1Len = ox::strlen(str1) + 1;
constexpr auto str2 = "Hello, Moon!"; constexpr auto str2 = "Hello, Moon!";
constexpr auto str2Len = ox::strlen(str2) + 1; constexpr auto str2Len = ox::strlen(str2) + 1;
OX_ALLOW_UNSAFE_BUFFERS_END
auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen); auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen);
oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed."); oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed.");
ox::FileStore32 fileStore(list, buffLen); ox::FileStore32 fileStore(list, buffLen);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -35,7 +35,7 @@ static ox::Result<Buff> loadFsBuff(const char *path) noexcept {
} }
static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexcept { static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexcept {
OX_REQUIRE(buff, loadFsBuff(path)); oxRequire(buff, loadFsBuff(path));
return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)}; return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)};
} }
@ -44,11 +44,11 @@ static ox::Error runLs(ox::FileSystem *fs, ox::Span<const char*> args) noexcept
oxErr("Must provide a directory to ls\n"); oxErr("Must provide a directory to ls\n");
return ox::Error(1); return ox::Error(1);
} }
OX_REQUIRE(files, fs->ls(args[1])); oxRequire(files, fs->ls(args[1]));
for (const auto &file : files) { for (const auto &file : files) {
oxOutf("{}\n", file); oxOutf("{}\n", file);
} }
return {}; return ox::Error(0);
} }
static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcept { static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
@ -56,11 +56,9 @@ static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcep
oxErr("Must provide a path to a file to read\n"); oxErr("Must provide a path to a file to read\n");
return ox::Error(1); return ox::Error(1);
} }
OX_REQUIRE(buff, fs->read(ox::StringView(args[1]))); oxRequire(buff, fs->read(ox::StringView(args[1])));
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout); std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
OX_ALLOW_UNSAFE_BUFFERS_END return ox::Error(0);
return {};
} }
static ox::Error run(int argc, const char **argv) noexcept { static ox::Error run(int argc, const char **argv) noexcept {
@ -71,7 +69,7 @@ static ox::Error run(int argc, const char **argv) noexcept {
auto const args = ox::Span{argv, static_cast<size_t>(argc)}; auto const args = ox::Span{argv, static_cast<size_t>(argc)};
auto const fsPath = args[1]; auto const fsPath = args[1];
ox::String subCmd(args[2]); ox::String subCmd(args[2]);
OX_REQUIRE(fs, loadFs(fsPath)); oxRequire(fs, loadFs(fsPath));
if (subCmd == "ls") { if (subCmd == "ls") {
return runLs(fs.get(), args + 2); return runLs(fs.get(), args + 2);
} else if (subCmd == "read") { } else if (subCmd == "read") {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -14,7 +14,7 @@
{ \ { \
const auto loggerErr = (loggerName).initConn(appName); \ const auto loggerErr = (loggerName).initConn(appName); \
if (loggerErr) { \ if (loggerErr) { \
oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.src.file_name(), loggerErr.src.line()); \ oxErrf("Could not connect to logger: {} ({}:{})\n", toStr(loggerErr), loggerErr.file, loggerErr.line); \
} else { \ } else { \
ox::trace::setLogger(&(loggerName)); \ ox::trace::setLogger(&(loggerName)); \
} \ } \

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -64,7 +64,7 @@ ox::Error LoggerConn::initConn(ox::StringViewCR appName) noexcept {
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(5590); addr.sin_port = htons(5590);
m_socket = static_cast<int>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); m_socket = static_cast<int>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(connect(static_cast<Socket>(m_socket), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))))); oxReturnError(ox::Error(static_cast<ox::ErrorCode>(connect(static_cast<Socket>(m_socket), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
return sendInit({.appName = ox::BasicString<128>(appName)}); return sendInit({.appName = ox::BasicString<128>(appName)});
} }
@ -91,28 +91,23 @@ ox::Error LoggerConn::sendInit(const InitTraceMsg &msg) noexcept {
} }
void LoggerConn::msgSend() noexcept { void LoggerConn::msgSend() noexcept {
try { while (true) {
std::unique_lock lk(m_waitMut);
m_waitCond.wait(lk);
if (!m_running) {
break;
}
std::lock_guard const buffLk(m_buffMut);
while (true) { while (true) {
std::unique_lock lk(m_waitMut); Array<char, units::KB> tmp;
m_waitCond.wait(lk); const auto read = m_buff.read(tmp.data(), tmp.size());
if (!m_running) { if (!read) {
break; break;
} }
std::lock_guard const buffLk(m_buffMut); oxAssert(read <= tmp.size(), "logger trying to read too much data");
while (true) { //std::printf("LoggerConn: sending %lu bytes\n", read);
Array<char, units::KB> tmp; std::ignore = send(tmp.data(), read);
const auto read = m_buff.read(tmp.data(), tmp.size());
if (!read) {
break;
}
oxAssert(read <= tmp.size(), "logger trying to read too much data");
//std::printf("LoggerConn: sending %lu bytes\n", read);
std::ignore = send(tmp.data(), read);
}
} }
} catch (std::exception const &e) {
oxErrf("Exception in logger thread: {}\n", e.what());
oxAssert(false, "logger thread exception");
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -45,13 +45,13 @@ class LoggerConn: public trace::Logger {
ox::Error send(trace::MsgId msgId, const auto &msg) noexcept { ox::Error send(trace::MsgId msgId, const auto &msg) noexcept {
ox::Array<char, 10 * ox::units::KB> buff; ox::Array<char, 10 * ox::units::KB> buff;
std::size_t sz = 0; std::size_t sz = 0;
OX_RETURN_ERROR(ox::writeMC(&buff[0], buff.size(), msg, &sz)); oxReturnError(ox::writeMC(&buff[0], buff.size(), msg, &sz));
//std::printf("sz: %lu\n", sz); //std::printf("sz: %lu\n", sz);
OX_REQUIRE(szBuff, serialize(static_cast<uint32_t>(sz))); oxRequire(szBuff, serialize(static_cast<uint32_t>(sz)));
std::unique_lock buffLk(m_buffMut); std::unique_lock buffLk(m_buffMut);
OX_RETURN_ERROR(m_buff.put(static_cast<char>(msgId))); oxReturnError(m_buff.put(static_cast<char>(msgId)));
OX_RETURN_ERROR(m_buff.write(szBuff.data(), szBuff.size())); oxReturnError(m_buff.write(szBuff.data(), szBuff.size()));
OX_RETURN_ERROR(m_buff.write(buff.data(), sz)); oxReturnError(m_buff.write(buff.data(), sz));
buffLk.unlock(); buffLk.unlock();
m_waitCond.notify_one(); m_waitCond.notify_one();
return {}; return {};

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -71,9 +71,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
// move input to uint64_t to allow consistent bit manipulation, and to avoid // move input to uint64_t to allow consistent bit manipulation, and to avoid
// overflow concerns // overflow concerns
uint64_t val = 0; uint64_t val = 0;
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
ox::memcpy(&val, &input, sizeof(input)); ox::memcpy(&val, &input, sizeof(input));
OX_ALLOW_UNSAFE_BUFFERS_END
if (val) { if (val) {
// bits needed to represent number factoring in space possibly // bits needed to represent number factoring in space possibly
// needed for signed bit // needed for signed bit
@ -96,9 +94,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
} }
if (bytes == 9) { if (bytes == 9) {
out.data[0] = bytesIndicator; out.data[0] = bytesIndicator;
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
ox::memcpy(&out.data[1], &leVal, 8); ox::memcpy(&out.data[1], &leVal, 8);
OX_ALLOW_UNSAFE_BUFFERS_END
if (inputNegative) { if (inputNegative) {
out.data[1] |= 0b1000'0000; out.data[1] |= 0b1000'0000;
} }
@ -108,9 +104,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
auto intermediate = auto intermediate =
static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes | static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
static_cast<uint64_t>(bytesIndicator); static_cast<uint64_t>(bytesIndicator);
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate)); ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate));
OX_ALLOW_UNSAFE_BUFFERS_END
} }
out.length = bytes; out.length = bytes;
} }
@ -141,53 +135,49 @@ static_assert(countBytes(0b1111'1111) == 9);
template<typename I> template<typename I>
constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noexcept { constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noexcept {
uint8_t firstByte = 0; uint8_t firstByte = 0;
OX_RETURN_ERROR(rdr.read(&firstByte, 1)); oxReturnError(rdr.read(&firstByte, 1));
OX_RETURN_ERROR(rdr.seekg(-1, ox::ios_base::cur)); oxReturnError(rdr.seekg(-1, ox::ios_base::cur));
const auto bytes = countBytes(firstByte); const auto bytes = countBytes(firstByte);
if (bytes == 9) { if (bytes == 9) {
*bytesRead = bytes; *bytesRead = bytes;
I out = 0; I out = 0;
OX_RETURN_ERROR(rdr.seekg(1, ox::ios_base::cur)); oxReturnError(rdr.seekg(1, ox::ios_base::cur));
OX_RETURN_ERROR(rdr.read(&out, sizeof(I))); oxReturnError(rdr.read(&out, sizeof(I)));
return fromLittleEndian<I>(out); return fromLittleEndian<I>(out);
} }
*bytesRead = bytes; *bytesRead = bytes;
uint64_t decoded = 0; uint64_t decoded = 0;
OX_RETURN_ERROR(rdr.read(&decoded, bytes)); oxReturnError(rdr.read(&decoded, bytes));
decoded >>= bytes; decoded >>= bytes;
// move sign bit // move sign bit
if constexpr(is_signed_v<I>) { if constexpr(is_signed_v<I>) {
const auto negBit = bytes * 8 - bytes - 1; const auto negBit = bytes * 8 - bytes - 1;
// move sign // move sign
const auto negative = (decoded >> negBit) == 1; const auto negative = (decoded >> negBit) == 1;
if (negative) { if (negative) {
// fill in all bits between encoded sign and real sign with 1s // fill in all bits between encoded sign and real sign with 1s
// split it up because the 32-bit ARM can't shift more than 32 bits // split it up because the 32-bit ARM can't shift more than 32 bits
ox::Array<uint32_t, 2> d = {}; ox::Array<uint32_t, 2> d = {};
//d[0] = decoded & 0xffff'ffff; //d[0] = decoded & 0xffff'ffff;
//d[1] = decoded >> 32; //d[1] = decoded >> 32;
OX_ALLOW_UNSAFE_BUFFERS_BEGIN ox::memcpy(&d[0], &decoded, sizeof(decoded));
ox::memcpy(&d[0], &decoded, sizeof(decoded)); auto bit = negBit;
OX_ALLOW_UNSAFE_BUFFERS_END for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
auto bit = negBit; d[0] |= 1 << bit;
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) { }
d[0] |= 1 << bit; bit -= 32;
} for (; bit < Bits<I>; ++bit) {
bit -= 32; d[1] |= 1 << bit;
for (; bit < Bits<I>; ++bit) { }
d[1] |= 1 << bit; I out = 0;
} if constexpr(ox::defines::BigEndian) {
I out = 0; const auto d0Tmp = d[0];
if constexpr(ox::defines::BigEndian) { d[0] = d[1];
const auto d0Tmp = d[0]; d[1] = d0Tmp;
d[0] = d[1]; }
d[1] = d0Tmp; ox::memcpy(&out, &d[0], sizeof(out));
} return out;
OX_ALLOW_UNSAFE_BUFFERS_BEGIN }
ox::memcpy(&out, &d[0], sizeof(out));
OX_ALLOW_UNSAFE_BUFFERS_END
return out;
}
} }
return static_cast<I>(decoded); return static_cast<I>(decoded);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -47,7 +47,7 @@ constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noe
constexpr auto blockBits = sizeof(m_mapBlock); constexpr auto blockBits = sizeof(m_mapBlock);
auto const blockIdx = idx / blockBits; auto const blockIdx = idx / blockBits;
if (m_mapBlockIdx != blockIdx) [[unlikely]] { if (m_mapBlockIdx != blockIdx) [[unlikely]] {
OX_RETURN_ERROR(loadMapBlock(blockIdx)); oxReturnError(loadMapBlock(blockIdx));
} }
idx %= blockBits; idx %= blockBits;
return (m_mapBlock >> idx) & 1; return (m_mapBlock >> idx) & 1;
@ -55,12 +55,12 @@ constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noe
template<Reader_c Reader> template<Reader_c Reader>
constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept { constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept {
OX_REQUIRE(g, m_reader.tellg()); oxRequire(g, m_reader.tellg());
OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg)); oxReturnError(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
ox::Array<char, sizeof(m_mapBlock)> mapBlock{}; ox::Array<char, sizeof(m_mapBlock)> mapBlock{};
OX_RETURN_ERROR(m_reader.read(mapBlock.data(), sizeof(m_mapBlock))); oxReturnError(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
// Warning: narrow-conv // Warning: narrow-conv
OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg)); oxReturnError(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
m_mapBlock = 0; m_mapBlock = 0;
for (auto i = 0ull; auto b : mapBlock) { for (auto i = 0ull; auto b : mapBlock) {
m_mapBlock |= static_cast<uint64_t>(std::bit_cast<uint8_t>(b)) << i; m_mapBlock |= static_cast<uint64_t>(std::bit_cast<uint8_t>(b)) << i;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -194,10 +194,10 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, bool *val) n
if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field)); auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field));
*val = result.value; *val = result.value;
OX_RETURN_ERROR(result); oxReturnError(result);
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
// array handler // array handler
@ -207,15 +207,15 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead)); oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
// read the list // read the list
if (valLen >= len) { if (valLen >= len) {
auto reader = child({}); auto reader = child({});
auto &handler = *reader.interface(); auto &handler = *reader.interface();
OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len))); oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field({}, &val[i])); oxReturnError(handler.field({}, &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
} }
} else { } else {
@ -234,29 +234,29 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, HashMap<Stri
if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
OX_REQUIRE(g, m_reader.tellg()); oxRequire(g, m_reader.tellg());
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead)); oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
OX_RETURN_ERROR(m_reader.seekg(g)); oxReturnError(m_reader.seekg(g));
// read the list // read the list
auto reader = child(""); auto reader = child("");
auto &handler = *reader.interface(); auto &handler = *reader.interface();
OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len))); oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
// this loop body needs to be in a lambda because of the potential alloca call // this loop body needs to be in a lambda because of the potential alloca call
constexpr auto loopBody = [](auto &handler, auto &val) { constexpr auto loopBody = [](auto &handler, auto &val) {
OX_REQUIRE(keyLen, handler.stringLength(nullptr)); oxRequire(keyLen, handler.stringLength(nullptr));
auto wkey = ox_malloca(keyLen + 1, char, 0); auto wkey = ox_malloca(keyLen + 1, char, 0);
auto wkeyPtr = wkey.get(); auto wkeyPtr = wkey.get();
OX_RETURN_ERROR(handler.fieldCString("", &wkeyPtr, keyLen + 1)); oxReturnError(handler.fieldCString("", &wkeyPtr, keyLen + 1));
return handler.field("", &val[wkeyPtr]); return handler.field("", &val[wkeyPtr]);
}; };
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
OX_RETURN_ERROR(loopBody(handler, *val)); oxReturnError(loopBody(handler, *val));
} }
} }
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -266,11 +266,11 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
// set size of val if the field is present, don't worry about it if not // set size of val if the field is present, don't worry about it if not
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
OX_REQUIRE(len, arrayLength(name, false)); oxRequire(len, arrayLength(name, false));
OX_RETURN_ERROR(ox::resizeVector(*val, len)); oxReturnError(ox::resizeVector(*val, len));
return field(name, val->data(), val->size()); return field(name, val->data(), val->size());
} }
OX_RETURN_ERROR(ox::resizeVector(*val, 0)); oxReturnError(ox::resizeVector(*val, 0));
} }
++m_field; ++m_field;
return {}; return {};
@ -278,7 +278,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) { if (!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) {
// set size of val if the field is present, don't worry about it if not // set size of val if the field is present, don't worry about it if not
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
OX_REQUIRE(len, arrayLength(name, false)); oxRequire(len, arrayLength(name, false));
if (len > val->size()) { if (len > val->size()) {
return ox::Error(1, "Input array is too long"); return ox::Error(1, "Input array is too long");
} }
@ -291,7 +291,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val) { if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
auto reader = child(""); auto reader = child("");
OX_RETURN_ERROR(model(reader.interface(), val)); oxReturnError(model(reader.interface(), val));
} }
} }
++m_field; ++m_field;
@ -305,7 +305,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, UnionView<U,
if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val.get()) { if ((!m_unionIdx.has_value() || static_cast<std::size_t>(*m_unionIdx) == m_field) && val.get()) {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
auto reader = child("", ox::Optional<int>(ox::in_place, val.idx())); auto reader = child("", ox::Optional<int>(ox::in_place, val.idx()));
OX_RETURN_ERROR(model(reader.interface(), val.get())); oxReturnError(model(reader.interface(), val.get()));
} }
} }
++m_field; ++m_field;
@ -319,18 +319,18 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead)); oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
const auto cap = size; const auto cap = size;
*val = BasicString<SmallStringSize>(cap); *val = BasicString<SmallStringSize>(cap);
auto data = val->data(); auto data = val->data();
// read the string // read the string
OX_RETURN_ERROR(m_reader.read(data, size)); oxReturnError(m_reader.read(data, size));
} else { } else {
*val = ""; *val = "";
} }
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -340,12 +340,12 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, IString<L> *
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead)); oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
*val = IString<L>(); *val = IString<L>();
OX_RETURN_ERROR(val->resize(size)); oxReturnError(val->resize(size));
auto const data = val->data(); auto const data = val->data();
// read the string // read the string
OX_RETURN_ERROR(m_reader.read(data, size)); oxReturnError(m_reader.read(data, size));
} else { } else {
*val = ""; *val = "";
} }
@ -359,18 +359,18 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead)); oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
if (size > buffLen) { if (size > buffLen) {
return ox::Error(McOutputBuffEnded); return ox::Error(McOutputBuffEnded);
} }
// re-allocate in case too small // re-allocate in case too small
auto data = val; auto data = val;
// read the string // read the string
OX_RETURN_ERROR(m_reader.read(data, size)); oxReturnError(m_reader.read(data, size));
data[size] = 0; data[size] = 0;
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -378,17 +378,17 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead)); oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
// re-allocate in case too small // re-allocate in case too small
safeDelete(*val); safeDelete(*val);
*val = new char[size + 1]; *val = new char[size + 1];
auto data = ox::Span{*val, size + 1}; auto data = ox::Span{*val, size + 1};
// read the string // read the string
OX_RETURN_ERROR(m_reader.read(data.data(), size)); oxReturnError(m_reader.read(data.data(), size));
data[size] = 0; data[size] = 0;
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -397,7 +397,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead)); oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
// re-allocate if too small // re-allocate if too small
if (buffLen < size + 1) { if (buffLen < size + 1) {
safeDelete(*val); safeDelete(*val);
@ -406,7 +406,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
} }
auto data = ox::Span{*val, size + 1}; auto data = ox::Span{*val, size + 1};
// read the string // read the string
OX_RETURN_ERROR(m_reader.read(data.data(), size)); oxReturnError(m_reader.read(data.data(), size));
data[size] = 0; data[size] = 0;
} else { } else {
auto data = *val; auto data = *val;
@ -416,7 +416,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
} }
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -425,10 +425,10 @@ constexpr Result<ArrayLength> MetalClawReaderTemplate<Reader>::arrayLength(const
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(g, m_reader.tellg()); oxRequire(g, m_reader.tellg());
OX_REQUIRE(out, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead)); oxRequire(out, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
if (!pass) { if (!pass) {
OX_RETURN_ERROR(m_reader.seekg(g)); oxReturnError(m_reader.seekg(g));
} }
return out; return out;
} }
@ -443,7 +443,7 @@ constexpr Result<StringLength> MetalClawReaderTemplate<Reader>::stringLength(con
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
auto len = mc::decodeInteger<StringLength>(m_reader, &bytesRead); auto len = mc::decodeInteger<StringLength>(m_reader, &bytesRead);
OX_RETURN_ERROR(m_reader.seekg(-static_cast<int64_t>(bytesRead), ox::ios_base::cur)); oxReturnError(m_reader.seekg(-static_cast<int64_t>(bytesRead), ox::ios_base::cur));
return len; return len;
} }
} }
@ -457,14 +457,14 @@ constexpr Error MetalClawReaderTemplate<Reader>::readInteger(I *val) noexcept {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
auto const result = mc::decodeInteger<I>(m_reader, &bytesRead); auto const result = mc::decodeInteger<I>(m_reader, &bytesRead);
OX_RETURN_ERROR(result); oxReturnError(result);
*val = result.value; *val = result.value;
} else { } else {
*val = 0; *val = 0;
} }
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -474,20 +474,20 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, CB cb) noexc
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) { if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length // read the length
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead)); oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
// read the list // read the list
auto reader = child(""); auto reader = child("");
auto &handler = *reader.interface(); auto &handler = *reader.interface();
OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len))); oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
T val; T val;
OX_RETURN_ERROR(handler.field("", &val)); oxReturnError(handler.field("", &val));
OX_RETURN_ERROR(cb(i, &val)); oxReturnError(cb(i, &val));
} }
} }
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Reader_c Reader> template<Reader_c Reader>
@ -548,7 +548,7 @@ Error readMC(ox::BufferView buff, T &val) noexcept {
template<typename T> template<typename T>
Result<T> readMC(ox::BufferView buff) noexcept { Result<T> readMC(ox::BufferView buff) noexcept {
Result<T> val; Result<T> val;
OX_RETURN_ERROR(readMC(buff, val.value)); oxReturnError(readMC(buff, val.value));
return val; return val;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -62,46 +62,46 @@ struct TestStruct {
template<typename T> template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept { constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>()); oxReturnError(io->template setTypeInfo<TestUnion>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->fieldCString("CString", &obj->CString)); oxReturnError(io->fieldCString("CString", &obj->CString));
return ox::Error(0); return ox::Error(0);
} }
OX_MODEL_BEGIN(TestStructNest) oxModelBegin(TestStructNest)
OX_MODEL_FIELD(Bool) oxModelField(Bool)
OX_MODEL_FIELD(Int) oxModelField(Int)
OX_MODEL_FIELD(IString) oxModelField(IString)
OX_MODEL_END() oxModelEnd()
template<typename T> template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept { constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>()); oxReturnError(io->template setTypeInfo<TestStruct>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("Int1", &obj->Int1)); oxReturnError(io->field("Int1", &obj->Int1));
OX_RETURN_ERROR(io->field("Int2", &obj->Int2)); oxReturnError(io->field("Int2", &obj->Int2));
OX_RETURN_ERROR(io->field("Int3", &obj->Int3)); oxReturnError(io->field("Int3", &obj->Int3));
OX_RETURN_ERROR(io->field("Int4", &obj->Int4)); oxReturnError(io->field("Int4", &obj->Int4));
OX_RETURN_ERROR(io->field("Int5", &obj->Int5)); oxReturnError(io->field("Int5", &obj->Int5));
OX_RETURN_ERROR(io->field("Int6", &obj->Int6)); oxReturnError(io->field("Int6", &obj->Int6));
OX_RETURN_ERROR(io->field("Int7", &obj->Int7)); oxReturnError(io->field("Int7", &obj->Int7));
OX_RETURN_ERROR(io->field("Int8", &obj->Int8)); oxReturnError(io->field("Int8", &obj->Int8));
OX_RETURN_ERROR(io->field("unionIdx", &obj->unionIdx)); oxReturnError(io->field("unionIdx", &obj->unionIdx));
if constexpr(T::opType() == ox::OpType::Reflect) { if constexpr(T::opType() == ox::OpType::Reflect) {
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, 0})); oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
} else { } else {
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx})); oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
} }
OX_RETURN_ERROR(io->field("String", &obj->String)); oxReturnError(io->field("String", &obj->String));
OX_RETURN_ERROR(io->field("IString", &obj->IString)); oxReturnError(io->field("IString", &obj->IString));
OX_RETURN_ERROR(io->field("List", obj->List, 4)); oxReturnError(io->field("List", obj->List, 4));
OX_RETURN_ERROR(io->field("Vector", &obj->Vector)); oxReturnError(io->field("Vector", &obj->Vector));
OX_RETURN_ERROR(io->field("Vector2", &obj->Vector2)); oxReturnError(io->field("Vector2", &obj->Vector2));
OX_RETURN_ERROR(io->field("Map", &obj->Map)); oxReturnError(io->field("Map", &obj->Map));
OX_RETURN_ERROR(io->field("Struct", &obj->Struct)); oxReturnError(io->field("Struct", &obj->Struct));
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct)); oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
return ox::Error(0); return ox::Error(0);
} }
@ -114,8 +114,8 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
// doesn't segfault // doesn't segfault
ox::Array<char, 1024> buff; ox::Array<char, 1024> buff;
TestStruct ts; TestStruct ts;
OX_RETURN_ERROR(ox::writeMC(buff.data(), buff.size(), ts)); oxReturnError(ox::writeMC(buff.data(), buff.size(), ts));
OX_RETURN_ERROR(ox::writeMC(ts)); oxReturnError(ox::writeMC(ts));
return ox::Error(0); return ox::Error(0);
} }
}, },
@ -260,7 +260,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
using ox::mc::decodeInteger; using ox::mc::decodeInteger;
static constexpr auto check = [](auto val) { static constexpr auto check = [](auto val) {
auto result = decodeInteger<decltype(val)>(encodeInteger(val)); auto result = decodeInteger<decltype(val)>(encodeInteger(val));
OX_RETURN_ERROR(result.error); oxReturnError(result.error);
if (result.value != val) { if (result.value != val) {
std::cout << "Bad value: " << result.value << ", expected: " << val << '\n'; std::cout << "Bad value: " << result.value << ", expected: " << val << '\n';
return ox::Error(1); return ox::Error(1);
@ -319,7 +319,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn); const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn);
oxAssert(typeErr, "Descriptor write failed"); oxAssert(typeErr, "Descriptor write failed");
ox::ModelObject testOut; ox::ModelObject testOut;
OX_RETURN_ERROR(testOut.setType(type)); oxReturnError(testOut.setType(type));
oxAssert(ox::readMC(dataBuff, testOut), "Data read failed"); oxAssert(ox::readMC(dataBuff, testOut), "Data read failed");
oxAssert(testOut.at("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed"); oxAssert(testOut.at("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
oxAssert(testOut.at("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed"); oxAssert(testOut.at("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
@ -371,7 +371,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn); const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn);
oxAssert(typeErr, "Descriptor write failed"); oxAssert(typeErr, "Descriptor write failed");
ox::BufferReader br({dataBuff, dataBuffLen}); ox::BufferReader br({dataBuff, dataBuffLen});
OX_RETURN_ERROR(ox::walkModel<ox::MetalClawReader>(type, br, oxReturnError(ox::walkModel<ox::MetalClawReader>(type, br,
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error { [](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
//std::cout << f.fieldName.c_str() << '\n'; //std::cout << f.fieldName.c_str() << '\n';
auto fieldName = f.fieldName.c_str(); auto fieldName = f.fieldName.c_str();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -117,12 +117,12 @@ class MetalClawWriter {
bool fieldSet = false; bool fieldSet = false;
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
auto mi = mc::encodeInteger(val); auto mi = mc::encodeInteger(val);
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
fieldSet = true; fieldSet = true;
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
}; };
@ -181,10 +181,10 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const uint64_t *val)
template<Writer_c Writer> template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept { constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept {
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) { if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
} }
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Writer_c Writer> template<Writer_c Writer>
@ -194,14 +194,14 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<Sm
if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto strLen = mc::encodeInteger(val->len()); const auto strLen = mc::encodeInteger(val->len());
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
// write the string // write the string
OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len()))); oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
fieldSet = true; fieldSet = true;
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Writer_c Writer> template<Writer_c Writer>
@ -214,22 +214,17 @@ template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept { constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) { if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
// this strlen is tolerated because sometimes 0 gets passed to
// the size param, which is a lie
// this code should be cleaned up at some point...
const auto strLen = *val ? ox::strlen(*val) : 0; const auto strLen = *val ? ox::strlen(*val) : 0;
OX_ALLOW_UNSAFE_BUFFERS_END
// write the length // write the length
const auto strLenBuff = mc::encodeInteger(strLen); const auto strLenBuff = mc::encodeInteger(strLen);
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
// write the string // write the string
OX_RETURN_ERROR(m_writer.write(*val, static_cast<std::size_t>(strLen))); oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
fieldSet = true; fieldSet = true;
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Writer_c Writer> template<Writer_c Writer>
@ -248,14 +243,14 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *v
if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto strLenBuff = mc::encodeInteger(strLen); const auto strLenBuff = mc::encodeInteger(strLen);
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
// write the string // write the string
OX_RETURN_ERROR(m_writer.write(val, static_cast<std::size_t>(strLen))); oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
fieldSet = true; fieldSet = true;
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Writer_c Writer> template<Writer_c Writer>
@ -269,11 +264,11 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
auto const writeIdx = m_writer.tellp(); auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer); MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer}; ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
OX_RETURN_ERROR(model(&handler, val)); oxReturnError(model(&handler, val));
OX_RETURN_ERROR(writer.finalize()); oxReturnError(writer.finalize());
fieldSet = writeIdx != m_writer.tellp(); fieldSet = writeIdx != m_writer.tellp();
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return {};
} }
@ -287,11 +282,11 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force>
auto const writeIdx = m_writer.tellp(); auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx())); MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx()));
ModelHandlerInterface handler{&writer}; ModelHandlerInterface handler{&writer};
OX_RETURN_ERROR(model(&handler, val.get())); oxReturnError(model(&handler, val.get()));
OX_RETURN_ERROR(writer.finalize()); oxReturnError(writer.finalize());
fieldSet = writeIdx != m_writer.tellp(); fieldSet = writeIdx != m_writer.tellp();
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return {};
} }
@ -303,23 +298,23 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto arrLen = mc::encodeInteger(len); const auto arrLen = mc::encodeInteger(len);
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
auto const writeIdx = m_writer.tellp(); auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer); MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface handler{&writer}; ModelHandlerInterface handler{&writer};
OX_RETURN_ERROR(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len))); oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
// write the array // write the array
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field("", &val[i])); oxReturnError(handler.field("", &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
} }
OX_RETURN_ERROR(writer.finalize()); oxReturnError(writer.finalize());
fieldSet = writeIdx != m_writer.tellp(); fieldSet = writeIdx != m_writer.tellp();
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Writer_c Writer> template<Writer_c Writer>
@ -331,32 +326,32 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) { if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length // write the length
const auto arrLen = mc::encodeInteger(len); const auto arrLen = mc::encodeInteger(len);
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
// write map // write map
MetalClawWriter<Writer> writer(m_writer); MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface handler{&writer}; ModelHandlerInterface handler{&writer};
// double len for both key and value // double len for both key and value
OX_RETURN_ERROR(handler.setTypeInfo("Map", 0, {}, len * 2)); oxReturnError(handler.setTypeInfo("Map", 0, {}, len * 2));
// this loop body needs to be in a lambda because of the potential alloca call // this loop body needs to be in a lambda because of the potential alloca call
constexpr auto loopBody = [](auto &handler, auto const&key, auto const&val) -> ox::Error { constexpr auto loopBody = [](auto &handler, auto const&key, auto const&val) -> ox::Error {
const auto keyLen = key.len(); const auto keyLen = key.len();
auto wkey = ox_malloca(keyLen + 1, char, 0); auto wkey = ox_malloca(keyLen + 1, char, 0);
memcpy(wkey.get(), key.c_str(), keyLen + 1); memcpy(wkey.get(), key.c_str(), keyLen + 1);
OX_RETURN_ERROR(handler.fieldCString("", wkey.get(), keyLen)); oxReturnError(handler.fieldCString("", wkey.get(), keyLen));
OX_REQUIRE_M(value, val.at(key)); oxRequireM(value, val.at(key));
return handler.field("", value); return handler.field("", value);
}; };
// write the array // write the array
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
auto const&key = keys[i]; auto const&key = keys[i];
OX_RETURN_ERROR(loopBody(handler, key, *val)); oxReturnError(loopBody(handler, key, *val));
} }
OX_RETURN_ERROR(writer.finalize()); oxReturnError(writer.finalize());
fieldSet = true; fieldSet = true;
} }
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet)); oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field; ++m_field;
return {}; return ox::Error(0);
} }
template<Writer_c Writer> template<Writer_c Writer>
@ -367,7 +362,7 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
const Vector<String>&, const Vector<String>&,
std::size_t fields) noexcept { std::size_t fields) noexcept {
const auto fieldPresenceLen = (fields - 1) / 8 + 1; const auto fieldPresenceLen = (fields - 1) / 8 + 1;
OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen)); oxReturnError(m_writer.write(nullptr, fieldPresenceLen));
m_presenceMapBuff.resize(fieldPresenceLen); m_presenceMapBuff.resize(fieldPresenceLen);
m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size()); m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
m_fieldPresence.setFields(static_cast<int>(fields)); m_fieldPresence.setFields(static_cast<int>(fields));
@ -377,33 +372,33 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
template<Writer_c Writer> template<Writer_c Writer>
ox::Error MetalClawWriter<Writer>::finalize() noexcept { ox::Error MetalClawWriter<Writer>::finalize() noexcept {
const auto end = m_writer.tellp(); const auto end = m_writer.tellp();
OX_RETURN_ERROR(m_writer.seekp(m_writerBeginP)); oxReturnError(m_writer.seekp(m_writerBeginP));
OX_RETURN_ERROR(m_writer.write( oxReturnError(m_writer.write(
reinterpret_cast<const char*>(m_presenceMapBuff.data()), reinterpret_cast<const char*>(m_presenceMapBuff.data()),
m_presenceMapBuff.size())); m_presenceMapBuff.size()));
OX_RETURN_ERROR(m_writer.seekp(end)); oxReturnError(m_writer.seekp(end));
return {}; return {};
} }
Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept { Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
MetalClawWriter mcWriter(writer); MetalClawWriter mcWriter(writer);
ModelHandlerInterface handler{&mcWriter}; ModelHandlerInterface handler{&mcWriter};
OX_RETURN_ERROR(model(&handler, &val)); oxReturnError(model(&handler, &val));
OX_RETURN_ERROR(mcWriter.finalize()); oxReturnError(mcWriter.finalize());
return {}; return {};
} }
Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB) noexcept { Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB) noexcept {
Buffer buff(buffReserveSz); Buffer buff(buffReserveSz);
BufferWriter bw(&buff, 0); BufferWriter bw(&buff, 0);
OX_RETURN_ERROR(writeMC(bw, val)); oxReturnError(writeMC(bw, val));
buff.resize(bw.tellp()); buff.resize(bw.tellp());
return buff; return buff;
} }
Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept { Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
CharBuffWriter bw{{buff, buffLen}}; CharBuffWriter bw{{buff, buffLen}};
OX_RETURN_ERROR(writeMC(bw, val)); oxReturnError(writeMC(bw, val));
if (sizeOut) { if (sizeOut) {
*sizeOut = bw.tellp(); *sizeOut = bw.tellp();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -11,9 +11,9 @@
#include <ox/std/concepts.hpp> #include <ox/std/concepts.hpp>
// oxModelFwdDecl is necessary because Apple-Clang is broken... // oxModelFwdDecl is necessary because Apple-Clang is broken...
#define OX_MODEL_FWD_DECL(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept #define oxModelFwdDecl(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
#define OX_MODEL_BEGIN(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { OX_RETURN_ERROR(io->template setTypeInfo<modelName>()); #define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { oxReturnError(io->template setTypeInfo<modelName>());
#define OX_MODEL_END() return {}; } #define oxModelEnd() return ox::Error(0); }
#define OX_MODEL_FIELD(fieldName) OX_RETURN_ERROR(io->field(#fieldName, &o->fieldName)); #define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
#define OX_MODEL_FIELD_RENAME(objFieldName, serFieldName) OX_RETURN_ERROR(io->field(#serFieldName, &o->objFieldName)); #define oxModelFieldRename(objFieldName, serFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
#define OX_MODEL_FRIEND(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept #define oxModelFriend(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -76,20 +76,20 @@ struct Subscript {
template<typename T> template<typename T>
constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept { constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<Subscript>()); oxReturnError(io->template setTypeInfo<Subscript>());
if constexpr(T::opType() == OpType::Reflect) { if constexpr(T::opType() == OpType::Reflect) {
uint32_t st = 0; uint32_t st = 0;
OX_RETURN_ERROR(io->field("subscriptType", &st)); oxReturnError(io->field("subscriptType", &st));
} else if constexpr(T::opType() == OpType::Write) { } else if constexpr(T::opType() == OpType::Write) {
auto pt = type ? static_cast<uint8_t>(type->subscriptType) : 0; auto pt = type ? static_cast<uint8_t>(type->subscriptType) : 0;
OX_RETURN_ERROR(io->field("subscriptType", &pt)); oxReturnError(io->field("subscriptType", &pt));
} else { } else {
auto pt = type ? static_cast<uint32_t>(type->subscriptType) : 0; auto pt = type ? static_cast<uint32_t>(type->subscriptType) : 0;
OX_RETURN_ERROR(io->field("subscriptType", &pt)); oxReturnError(io->field("subscriptType", &pt));
type->subscriptType = static_cast<Subscript::SubscriptType>(pt); type->subscriptType = static_cast<Subscript::SubscriptType>(pt);
} }
OX_RETURN_ERROR(io->field("length", &type->length)); oxReturnError(io->field("length", &type->length));
OX_RETURN_ERROR(io->field("smallSzLen", &type->smallSzLen)); oxReturnError(io->field("smallSzLen", &type->smallSzLen));
return {}; return {};
} }
@ -185,37 +185,37 @@ constexpr auto buildTypeId(const DescriptorType &t) noexcept {
template<typename T> template<typename T>
constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept { constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<DescriptorType>()); oxReturnError(io->template setTypeInfo<DescriptorType>());
OX_RETURN_ERROR(io->field("typeName", &type->typeName)); oxReturnError(io->field("typeName", &type->typeName));
OX_RETURN_ERROR(io->field("typeVersion", &type->typeVersion)); oxReturnError(io->field("typeVersion", &type->typeVersion));
if constexpr(T::opType() == OpType::Reflect) { if constexpr(T::opType() == OpType::Reflect) {
uint8_t pt = 0; uint8_t pt = 0;
OX_RETURN_ERROR(io->field("primitiveType", &pt)); oxReturnError(io->field("primitiveType", &pt));
} else if constexpr(T::opType() == OpType::Write) { } else if constexpr(T::opType() == OpType::Write) {
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0; auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
OX_RETURN_ERROR(io->field("primitiveType", &pt)); oxReturnError(io->field("primitiveType", &pt));
} else { } else {
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0; auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
OX_RETURN_ERROR(io->field("primitiveType", &pt)); oxReturnError(io->field("primitiveType", &pt));
type->primitiveType = static_cast<PrimitiveType>(pt); type->primitiveType = static_cast<PrimitiveType>(pt);
} }
OX_RETURN_ERROR(io->field("typeParams", &type->typeParams)); oxReturnError(io->field("typeParams", &type->typeParams));
OX_RETURN_ERROR(io->field("fieldList", &type->fieldList)); oxReturnError(io->field("fieldList", &type->fieldList));
OX_RETURN_ERROR(io->field("length", &type->length)); oxReturnError(io->field("length", &type->length));
OX_RETURN_ERROR(io->field("preloadable", &type->preloadable)); oxReturnError(io->field("preloadable", &type->preloadable));
return {}; return {};
} }
template<typename T> template<typename T>
constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcept { constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<DescriptorField>()); oxReturnError(io->template setTypeInfo<DescriptorField>());
OX_RETURN_ERROR(io->field("typeId", &field->typeId)); oxReturnError(io->field("typeId", &field->typeId));
OX_RETURN_ERROR(io->field("fieldName", &field->fieldName)); oxReturnError(io->field("fieldName", &field->fieldName));
OX_RETURN_ERROR(io->field("subscriptLevels", &field->subscriptLevels)); oxReturnError(io->field("subscriptLevels", &field->subscriptLevels));
OX_RETURN_ERROR(io->field("subscriptStack", &field->subscriptStack)); oxReturnError(io->field("subscriptStack", &field->subscriptStack));
// defaultValue is unused now, but leave placeholder for backwards compatibility // defaultValue is unused now, but leave placeholder for backwards compatibility
int defaultValue = 0; int defaultValue = 0;
OX_RETURN_ERROR(io->field("defaultValue", &defaultValue)); oxReturnError(io->field("defaultValue", &defaultValue));
return {}; return {};
} }
@ -244,7 +244,7 @@ constexpr Error model(TypeDescReader<T> *io, CommonPtrWith<DescriptorField> auto
// defaultValue is unused now, but placeholder for backwards compatibility // defaultValue is unused now, but placeholder for backwards compatibility
int defaultValue = 0; int defaultValue = 0;
oxReturnError(io->field("defaultValue", &defaultValue)); oxReturnError(io->field("defaultValue", &defaultValue));
return {}; return ox::Error(0);
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -205,7 +205,7 @@ constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t,
const auto t = type(p); const auto t = type(p);
oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated"); oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
m_type->fieldList.emplace_back(t, String(name), detail::indirectionLevels_v<T> + 1, subscriptStack, buildTypeId(*t)); m_type->fieldList.emplace_back(t, String(name), detail::indirectionLevels_v<T> + 1, subscriptStack, buildTypeId(*t));
return {}; return ox::Error(0);
} }
return ox::Error(1); return ox::Error(1);
} }
@ -220,7 +220,7 @@ constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t)
auto const lvls = detail::indirectionLevels_v<T> + 1; auto const lvls = detail::indirectionLevels_v<T> + 1;
SubscriptStack subscriptStack{lvls}; SubscriptStack subscriptStack{lvls};
m_type->fieldList.emplace_back(t, String(name), lvls, subscriptStack, buildTypeId(*t)); m_type->fieldList.emplace_back(t, String(name), lvls, subscriptStack, buildTypeId(*t));
return {}; return ox::Error(0);
} }
return ox::Error(1); return ox::Error(1);
} }
@ -231,7 +231,7 @@ constexpr Error TypeDescWriter::field(StringViewCR name, UnionView<T, force> val
const auto t = type(val); const auto t = type(val);
oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated"); oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated");
m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName)); m_type->fieldList.emplace_back(t, String(name), 0, SubscriptStack{}, ox::String(t->typeName));
return {}; return ox::Error(0);
} }
return ox::Error(1); return ox::Error(1);
} }
@ -384,11 +384,11 @@ constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore) noexcept {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
std::allocator<T> a; std::allocator<T> a;
T *t = a.allocate(1); T *t = a.allocate(1);
OX_RETURN_ERROR(model(&handler, t)); oxReturnError(model(&handler, t));
a.deallocate(t, 1); a.deallocate(t, 1);
} else { } else {
auto t = ox_malloca(sizeof(T), T); auto t = ox_malloca(sizeof(T), T);
OX_RETURN_ERROR(model(&handler, t.get())); oxReturnError(model(&handler, t.get()));
} }
return writer.definition(); return writer.definition();
} }
@ -397,7 +397,7 @@ template<typename T>
constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore, T &val) noexcept { constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore, T &val) noexcept {
TypeDescWriter writer(&typeStore); TypeDescWriter writer(&typeStore);
ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer); ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer);
OX_RETURN_ERROR(model(&handler, &val)); oxReturnError(model(&handler, &val));
return writer.definition(); return writer.definition();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -31,25 +31,25 @@ class FieldCounter {
template<typename U> template<typename U>
constexpr ox::Error field(StringViewCR, U) noexcept { constexpr ox::Error field(StringViewCR, U) noexcept {
++fields; ++fields;
return {}; return ox::Error(0);
} }
template<typename U> template<typename U>
constexpr ox::Error field(StringViewCR, U, std::size_t) noexcept { constexpr ox::Error field(StringViewCR, U, std::size_t) noexcept {
++fields; ++fields;
return {}; return ox::Error(0);
} }
template<typename U, typename Handler> template<typename U, typename Handler>
constexpr Error field(StringViewCR, Handler) { constexpr Error field(StringViewCR, Handler) {
++fields; ++fields;
return {}; return ox::Error(0);
} }
template<typename ...Args> template<typename ...Args>
constexpr Error fieldCString(Args&&...) noexcept { constexpr Error fieldCString(Args&&...) noexcept {
++fields; ++fields;
return {}; return ox::Error(0);
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -56,19 +56,19 @@ class MemberList {
template<typename T> template<typename T>
constexpr Error field(const char*, T *v) noexcept { constexpr Error field(const char*, T *v) noexcept {
vars[m_i++] = static_cast<void*>(v); vars[m_i++] = static_cast<void*>(v);
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
constexpr Error field(const char*, T *v, int) noexcept { constexpr Error field(const char*, T *v, int) noexcept {
vars[m_i++] = static_cast<void*>(v); vars[m_i++] = static_cast<void*>(v);
return {}; return ox::Error(0);
} }
template<typename U, bool force = false> template<typename U, bool force = false>
constexpr Error field(const char*, UnionView<U, force> u) noexcept { constexpr Error field(const char*, UnionView<U, force> u) noexcept {
vars[m_i++] = static_cast<void*>(u.get()); vars[m_i++] = static_cast<void*>(u.get());
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
@ -107,7 +107,7 @@ class Copier {
auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]); auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
dst = src; dst = src;
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
} }
@ -119,7 +119,7 @@ class Copier {
dst = src; dst = src;
} }
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
template<typename U, bool force = false> template<typename U, bool force = false>
@ -128,7 +128,7 @@ class Copier {
auto &src = *u.get(); auto &src = *u.get();
dst = src; dst = src;
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
template<typename T = void> template<typename T = void>
@ -168,7 +168,7 @@ class Mover {
dst = std::move(src); dst = std::move(src);
src = FT{}; src = FT{};
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
} }
@ -181,7 +181,7 @@ class Mover {
src = FT{}; src = FT{};
} }
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
template<typename U, bool force = false> template<typename U, bool force = false>
@ -190,7 +190,7 @@ class Mover {
auto &src = *u.get(); auto &src = *u.get();
dst = std::move(src); dst = std::move(src);
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
template<typename T = void> template<typename T = void>
@ -228,7 +228,7 @@ class Equals {
const auto &dst = std::bit_cast<FT>(*m_other->vars[m_i]); const auto &dst = std::bit_cast<FT>(*m_other->vars[m_i]);
++m_i; ++m_i;
if (dst == src) { if (dst == src) {
return {}; return ox::Error(0);
} else { } else {
this->value = false; this->value = false;
return ox::Error(1); return ox::Error(1);
@ -246,7 +246,7 @@ class Equals {
} }
} }
++m_i; ++m_i;
return {}; return ox::Error(0);
} }
template<typename U, bool force = false> template<typename U, bool force = false>
@ -255,7 +255,7 @@ class Equals {
const auto &src = *u.get(); const auto &src = *u.get();
++m_i; ++m_i;
if (dst == src) { if (dst == src) {
return {}; return ox::Error(0);
} else { } else {
this->value = false; this->value = false;
return ox::Error(1); return ox::Error(1);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -12,12 +12,12 @@ namespace ox {
static_assert([]() -> ox::Error { static_assert([]() -> ox::Error {
ox::ModelValue v; ox::ModelValue v;
OX_RETURN_ERROR(v.setType<int32_t>()); oxReturnError(v.setType<int32_t>());
if (v.type() != ModelValue::Type::SignedInteger32) { if (v.type() != ModelValue::Type::SignedInteger32) {
return ox::Error(1, "type is wrong"); return ox::Error(1, "type is wrong");
} }
//oxReturnError(v.set<int32_t>(5)); //oxReturnError(v.set<int32_t>(5));
return {}; return {};
}() == ox::Error{}); }() == ox::Error(0));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -242,7 +242,7 @@ class ModelValueArray {
m_vec.resize(sz); m_vec.resize(sz);
if (sz > oldSz) { if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) { for (auto i = oldSz; i < sz; ++i) {
OX_RETURN_ERROR(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels)); oxReturnError(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
} }
} }
return {}; return {};
@ -401,7 +401,7 @@ class ModelValueVector {
m_vec.resize(sz); m_vec.resize(sz);
if (sz > oldSz) { if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) { for (auto i = oldSz; i < sz; ++i) {
OX_RETURN_ERROR(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels)); oxReturnError(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
} }
} }
return {}; return {};
@ -519,7 +519,7 @@ class ModelObject {
ModelValue value; ModelValue value;
}; };
protected: protected:
OX_MODEL_FRIEND(ModelObject); oxModelFriend(ModelObject);
friend ModelValue; friend ModelValue;
Vector<UniquePtr<Field>> m_fieldsOrder; Vector<UniquePtr<Field>> m_fieldsOrder;
HashMap<String, ModelValue*> m_fields; HashMap<String, ModelValue*> m_fields;
@ -639,13 +639,13 @@ class ModelObject {
template<typename T> template<typename T>
constexpr Error set(const String &k, T &&val) noexcept { constexpr Error set(const String &k, T &&val) noexcept {
OX_REQUIRE(t, m_fields.at(k)); oxRequire(t, m_fields.at(k));
*t = ox::forward<T>(val); *t = ox::forward<T>(val);
return {}; return {};
} }
constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept { constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
OX_REQUIRE(v, m_fields.at(k)); oxRequire(v, m_fields.at(k));
return *v; return *v;
} }
@ -676,7 +676,7 @@ class ModelObject {
for (const auto &f : type->fieldList) { for (const auto &f : type->fieldList) {
auto field = make_unique<Field>(); auto field = make_unique<Field>();
field->name = f.fieldName; field->name = f.fieldName;
OX_RETURN_ERROR(field->value.setType(f.type, f.subscriptStack, f.subscriptLevels)); oxReturnError(field->value.setType(f.type, f.subscriptStack, f.subscriptLevels));
m_fields[field->name] = &field->value; m_fields[field->name] = &field->value;
m_fieldsOrder.emplace_back(std::move(field)); m_fieldsOrder.emplace_back(std::move(field));
} }
@ -722,7 +722,7 @@ class ModelUnion {
static constexpr Result<UniquePtr<ModelUnion>> make(const DescriptorType *type) noexcept { static constexpr Result<UniquePtr<ModelUnion>> make(const DescriptorType *type) noexcept {
UniquePtr<ModelUnion> out(new ModelUnion); UniquePtr<ModelUnion> out(new ModelUnion);
OX_RETURN_ERROR(out->setType(type)); oxReturnError(out->setType(type));
return out; return out;
} }
@ -731,7 +731,7 @@ class ModelUnion {
} }
constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept { constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
OX_REQUIRE(v, m_fields.at(k)); oxRequire(v, m_fields.at(k));
return &(*v)->value; return &(*v)->value;
} }
@ -763,7 +763,7 @@ class ModelUnion {
[[nodiscard]] [[nodiscard]]
constexpr Result<const ModelValue*> get(StringView const&k) const noexcept { constexpr Result<const ModelValue*> get(StringView const&k) const noexcept {
OX_REQUIRE(t, m_fields.at(k)); oxRequire(t, m_fields.at(k));
return &(*t)->value; return &(*t)->value;
} }
@ -799,7 +799,7 @@ class ModelUnion {
auto field = make_unique<Field>(); auto field = make_unique<Field>();
field->name = f.fieldName; field->name = f.fieldName;
field->idx = i; field->idx = i;
OX_RETURN_ERROR(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels)); oxReturnError(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels));
m_fields[field->name] = field.get(); m_fields[field->name] = field.get();
m_fieldsOrder.emplace_back(std::move(field)); m_fieldsOrder.emplace_back(std::move(field));
++i; ++i;
@ -967,21 +967,21 @@ constexpr std::size_t alignOf(const ModelValue &t) noexcept {
} }
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept { constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
OX_RETURN_ERROR(h->template setTypeInfo<ModelObject>( oxReturnError(h->template setTypeInfo<ModelObject>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) { for (auto &f : obj->m_fieldsOrder) {
OX_RETURN_ERROR(h->field(f->name.c_str(), &f->value)); oxReturnError(h->field(f->name.c_str(), &f->value));
} }
return {}; return ox::Error(0);
} }
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept { constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
OX_RETURN_ERROR(h->template setTypeInfo<ModelUnion>( oxReturnError(h->template setTypeInfo<ModelUnion>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) { for (auto &f : obj->m_fieldsOrder) {
OX_RETURN_ERROR(h->field(f->name.c_str(), &f->value)); oxReturnError(h->field(f->name.c_str(), &f->value));
} }
return {}; return ox::Error(0);
} }
constexpr ModelValue::ModelValue(const ModelValue &other) noexcept { constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
@ -997,7 +997,7 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
m_data = other.m_data; ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = new String(other.get<String>()); m_data.str = new String(other.get<String>());
@ -1030,8 +1030,8 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
m_data = other.m_data; ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
other.m_data.ui64 = 0; ox::memset(&other.m_data, 0, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = other.m_data.str; m_data.str = other.m_data.str;
@ -1087,12 +1087,12 @@ constexpr Error ModelValue::setType(
if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) { if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
m_type = Type::InlineArray; m_type = Type::InlineArray;
m_data.array = new ModelValueArray; m_data.array = new ModelValueArray;
OX_RETURN_ERROR(m_data.array->setType(type, subscriptStack, subscriptLevels - 1)); oxReturnError(m_data.array->setType(type, subscriptStack, subscriptLevels - 1));
OX_RETURN_ERROR(m_data.array->setSize(static_cast<size_t>(subscript.length))); oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
} else { } else {
m_type = Type::Vector; m_type = Type::Vector;
m_data.vec = new ModelValueVector; m_data.vec = new ModelValueVector;
OX_RETURN_ERROR(m_data.vec->setType(type, subscriptStack, subscriptLevels - 1)); oxReturnError(m_data.vec->setType(type, subscriptStack, subscriptLevels - 1));
} }
return {}; return {};
} else if (type->typeName == types::Bool) { } else if (type->typeName == types::Bool) {
@ -1121,15 +1121,15 @@ constexpr Error ModelValue::setType(
} else if (type->primitiveType == PrimitiveType::Struct) { } else if (type->primitiveType == PrimitiveType::Struct) {
m_type = Type::Object; m_type = Type::Object;
m_data.obj = new ModelObject; m_data.obj = new ModelObject;
OX_RETURN_ERROR(m_data.obj->setType(type)); oxReturnError(m_data.obj->setType(type));
} else if (type->primitiveType == PrimitiveType::Union) { } else if (type->primitiveType == PrimitiveType::Union) {
m_type = Type::Union; m_type = Type::Union;
OX_REQUIRE_M(u, ModelUnion::make(type)); oxRequireM(u, ModelUnion::make(type));
m_data.uni = u.release(); m_data.uni = u.release();
OX_RETURN_ERROR(m_data.uni->setType(type)); oxReturnError(m_data.uni->setType(type));
} }
oxAssert(m_type != Type::Undefined, "No type set"); oxAssert(m_type != Type::Undefined, "No type set");
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
@ -1141,11 +1141,11 @@ constexpr Error ModelValue::setType() noexcept {
// rather than using getValue<type>() // rather than using getValue<type>()
if constexpr(type == Type::Object) { if constexpr(type == Type::Object) {
m_data.obj = new ModelObject; m_data.obj = new ModelObject;
OX_RETURN_ERROR(m_data.obj->setType(type)); oxReturnError(m_data.obj->setType(type));
} else if constexpr(type == Type::Union) { } else if constexpr(type == Type::Union) {
OX_REQUIRE_M(u, ModelUnion::make(type)); oxRequireM(u, ModelUnion::make(type));
m_data.uni = u.release(); m_data.uni = u.release();
OX_RETURN_ERROR(m_data.uni->setType(type)); oxReturnError(m_data.uni->setType(type));
} else if constexpr(type == Type::String) { } else if constexpr(type == Type::String) {
m_data.str = new String; m_data.str = new String;
} else if constexpr(type == Type::Vector) { } else if constexpr(type == Type::Vector) {
@ -1184,7 +1184,7 @@ constexpr Error ModelValue::set(const T &v) noexcept {
safeDelete(&value); safeDelete(&value);
} }
value = v; value = v;
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
@ -1199,7 +1199,7 @@ constexpr Error ModelValue::set(T &&v) noexcept {
safeDelete(&value); safeDelete(&value);
} }
value = std::move(v); value = std::move(v);
return {}; return ox::Error(0);
} }
constexpr ModelValue &ModelValue::operator=(ModelValue &other) noexcept { constexpr ModelValue &ModelValue::operator=(ModelValue &other) noexcept {
@ -1223,7 +1223,7 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
m_data = other.m_data; ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = new String(other.get<String>()); m_data.str = new String(other.get<String>());
@ -1261,8 +1261,8 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
m_data = other.m_data; ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
other.m_data = {}; ox::memset(&other.m_data, 0, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = other.m_data.str; m_data.str = other.m_data.str;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -17,8 +17,8 @@ struct TestType {
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 1;
}; };
OX_MODEL_BEGIN(TestType) oxModelBegin(TestType)
OX_MODEL_END() oxModelEnd()
struct TestType2 { struct TestType2 {
}; };
@ -38,12 +38,12 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
"ModelValue", "ModelValue",
[] { [] {
ox::ModelValue v; ox::ModelValue v;
OX_RETURN_ERROR(v.setType<int32_t>()); oxReturnError(v.setType<int32_t>());
//v.m_type = ox::ModelValue::getType<int32_t>(); //v.m_type = ox::ModelValue::getType<int32_t>();
if (v.type() != ox::ModelValue::Type::SignedInteger32) { if (v.type() != ox::ModelValue::Type::SignedInteger32) {
return ox::Error(1, "type is wrong"); return ox::Error(1, "type is wrong");
} }
OX_RETURN_ERROR(v.set<int32_t>(5)); oxReturnError(v.set<int32_t>(5));
return ox::Error{}; return ox::Error{};
} }
}, },

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -38,17 +38,17 @@ struct TypeNameCatcher {
template<typename T> template<typename T>
constexpr Error field(const char*, T*, std::size_t) noexcept { constexpr Error field(const char*, T*, std::size_t) noexcept {
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
constexpr Error field(const char*, T) noexcept { constexpr Error field(const char*, T) noexcept {
return {}; return ox::Error(0);
} }
template<typename ...Args> template<typename ...Args>
constexpr Error fieldCString(Args&&...) noexcept { constexpr Error fieldCString(Args&&...) noexcept {
return {}; return ox::Error(0);
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {
@ -77,17 +77,17 @@ struct TypeInfoCatcher {
template<typename T> template<typename T>
constexpr Error field(const char*, T*, std::size_t) noexcept { constexpr Error field(const char*, T*, std::size_t) noexcept {
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
constexpr Error field(const char*, T) noexcept { constexpr Error field(const char*, T) noexcept {
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
constexpr Error fieldCString(const char*, T) noexcept { constexpr Error fieldCString(const char*, T) noexcept {
return {}; return ox::Error(0);
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {
@ -140,16 +140,16 @@ constexpr Str getModelTypeName() noexcept {
return out; return out;
} }
template<typename T, typename Str = const char*> template<typename T>
[[nodiscard]] [[nodiscard]]
consteval auto requireModelTypeName() noexcept { consteval auto requireModelTypeName() noexcept {
constexpr auto name = getModelTypeName<T, Str>(); constexpr auto name = getModelTypeName<T>();
static_assert(ox::StringView{name}.len(), "Type lacks required TypeName"); static_assert(ox::StringView{name}.len(), "Type lacks required TypeName");
return name; return name;
} }
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr auto ModelTypeName_v = requireModelTypeName<T, Str>(); constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>(); constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -31,7 +31,7 @@ class TypeStore {
constexpr Result<const DescriptorType*> get(const auto &name, int typeVersion, constexpr Result<const DescriptorType*> get(const auto &name, int typeVersion,
const TypeParamPack &typeParams) const noexcept { const TypeParamPack &typeParams) const noexcept {
const auto typeId = buildTypeId(name, typeVersion, typeParams); const auto typeId = buildTypeId(name, typeVersion, typeParams);
OX_REQUIRE(out, m_cache.at(typeId)); oxRequire(out, m_cache.at(typeId));
return out->get(); return out->get();
} }
@ -40,7 +40,7 @@ class TypeStore {
constexpr auto typeName = ModelTypeName_v<T>; constexpr auto typeName = ModelTypeName_v<T>;
constexpr auto typeVersion = ModelTypeVersion_v<T>; constexpr auto typeVersion = ModelTypeVersion_v<T>;
const auto typeId = buildTypeId(typeName, typeVersion, {}); const auto typeId = buildTypeId(typeName, typeVersion, {});
OX_REQUIRE(out, m_cache.at(typeId)); oxRequire(out, m_cache.at(typeId));
return out->get(); return out->get();
} }
@ -56,13 +56,9 @@ class TypeStore {
auto [val, err] = m_cache.at(typeId); auto [val, err] = m_cache.at(typeId);
if (err) { if (err) {
if (!std::is_constant_evaluated()) { if (!std::is_constant_evaluated()) {
OX_REQUIRE_M(dt, loadDescriptor(typeId)); oxRequireM(dt, loadDescriptor(typeId));
for (auto &f : dt->fieldList) { for (auto &f : dt->fieldList) {
if (typeId == f.typeId) { oxReturnError(this->getLoad(f.typeId).moveTo(f.type));
f.type = dt.get();
} else {
OX_RETURN_ERROR(this->getLoad(f.typeId).moveTo(f.type));
}
} }
auto &out = m_cache[typeId]; auto &out = m_cache[typeId];
out = std::move(dt); out = std::move(dt);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -50,7 +50,7 @@ constexpr DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler
template<typename Reader, typename T> template<typename Reader, typename T>
constexpr Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept { constexpr Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept {
OX_REQUIRE(out, m_typeStack.back()); oxRequire(out, m_typeStack.back());
return *out; return *out;
} }
@ -87,9 +87,9 @@ static constexpr Error parseField(const DescriptorField &field, Reader *rdr, Dat
walker->pushNamePath(field.fieldName); walker->pushNamePath(field.fieldName);
if (field.subscriptLevels) { if (field.subscriptLevels) {
// add array handling // add array handling
OX_REQUIRE(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true)); oxRequire(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true));
auto child = rdr->child(field.fieldName.c_str()); auto child = rdr->child(field.fieldName.c_str());
OX_RETURN_ERROR(child.setTypeInfo(field.type->typeName.c_str(), field.type->typeVersion, field.type->typeParams, arrayLen)); oxReturnError(child.setTypeInfo(field.type->typeName.c_str(), field.type->typeVersion, field.type->typeParams, arrayLen));
DescriptorField f(field); // create mutable copy DescriptorField f(field); // create mutable copy
--f.subscriptLevels; --f.subscriptLevels;
String subscript; String subscript;
@ -98,7 +98,7 @@ static constexpr Error parseField(const DescriptorField &field, Reader *rdr, Dat
subscript += static_cast<uint64_t>(i); subscript += static_cast<uint64_t>(i);
subscript += "]"; subscript += "]";
walker->pushNamePath(subscript); walker->pushNamePath(subscript);
OX_RETURN_ERROR(parseField(f, &child, walker)); oxReturnError(parseField(f, &child, walker));
walker->popNamePath(); walker->popNamePath();
} }
rdr->nextField(); rdr->nextField();
@ -108,40 +108,40 @@ static constexpr Error parseField(const DescriptorField &field, Reader *rdr, Dat
case PrimitiveType::SignedInteger: case PrimitiveType::SignedInteger:
case PrimitiveType::Bool: case PrimitiveType::Bool:
case PrimitiveType::String: case PrimitiveType::String:
OX_RETURN_ERROR(walker->read(field, rdr)); oxReturnError(walker->read(field, rdr));
break; break;
case PrimitiveType::Struct: case PrimitiveType::Struct:
case PrimitiveType::Union: case PrimitiveType::Union:
if (rdr->fieldPresent(field.fieldName.c_str())) { if (rdr->fieldPresent(field.fieldName.c_str())) {
auto child = rdr->child(field.fieldName.c_str()); auto child = rdr->child(field.fieldName.c_str());
walker->pushType(field.type); walker->pushType(field.type);
OX_RETURN_ERROR(model(&child, walker)); oxReturnError(model(&child, walker));
walker->popType(); walker->popType();
rdr->nextField(); rdr->nextField();
} else { } else {
// skip and discard absent field // skip and discard absent field
int discard; int discard;
OX_RETURN_ERROR(rdr->field(field.fieldName.c_str(), &discard)); oxReturnError(rdr->field(field.fieldName.c_str(), &discard));
} }
break; break;
} }
} }
walker->popNamePath(); walker->popNamePath();
return {}; return ox::Error(0);
} }
template<typename Reader, typename FH> template<typename Reader, typename FH>
constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept { constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
OX_REQUIRE(type, walker->type()); oxRequire(type, walker->type());
auto typeName = type->typeName.c_str(); auto typeName = type->typeName.c_str();
auto typeVersion = type->typeVersion; auto typeVersion = type->typeVersion;
auto typeParams = type->typeParams; auto typeParams = type->typeParams;
auto &fields = type->fieldList; auto &fields = type->fieldList;
OX_RETURN_ERROR(rdr->setTypeInfo(typeName, typeVersion, typeParams, fields.size())); oxReturnError(rdr->setTypeInfo(typeName, typeVersion, typeParams, fields.size()));
for (const auto &field : fields) { for (const auto &field : fields) {
OX_RETURN_ERROR(parseField(field, rdr, walker)); oxReturnError(parseField(field, rdr, walker));
} }
return {}; return ox::Error(0);
} }
template<typename Reader, typename Handler> template<typename Reader, typename Handler>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -15,7 +15,7 @@ namespace ox {
OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) { OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
auto json = reinterpret_cast<const char*>(buff); auto json = reinterpret_cast<const char*>(buff);
auto jsonLen = ox::strnlen_s(json, buffSize); auto jsonLen = ox::strnlen(json, buffSize);
Json::CharReaderBuilder parserBuilder; Json::CharReaderBuilder parserBuilder;
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader()); auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) { if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
@ -37,7 +37,7 @@ OrganicClawReader::OrganicClawReader(Json::Value json, int unionIdx) noexcept:
} }
Error OrganicClawReader::field(const char *key, bool *val) noexcept { Error OrganicClawReader::field(const char *key, bool *val) noexcept {
ox::Error err{}; auto err = ox::Error(0);
if (targetValid()) { if (targetValid()) {
const auto &jv = value(key); const auto &jv = value(key);
if (jv.empty()) { if (jv.empty()) {
@ -53,7 +53,7 @@ Error OrganicClawReader::field(const char *key, bool *val) noexcept {
} }
Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept { Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t buffLen) noexcept {
ox::Error err{}; auto err = ox::Error(0);
const char *begin = nullptr, *end = nullptr; const char *begin = nullptr, *end = nullptr;
const auto &jv = value(key); const auto &jv = value(key);
if (targetValid()) { if (targetValid()) {
@ -81,7 +81,7 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu
} }
Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept { Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
ox::Error err{}; auto err = ox::Error(0);
const char *begin = nullptr, *end = nullptr; const char *begin = nullptr, *end = nullptr;
const auto &jv = value(key); const auto &jv = value(key);
auto &data = *val; auto &data = *val;
@ -106,7 +106,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
} }
Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t buffLen) noexcept { Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t buffLen) noexcept {
ox::Error err{}; auto err = ox::Error(0);
const char *begin = nullptr, *end = nullptr; const char *begin = nullptr, *end = nullptr;
const auto &jv = value(key); const auto &jv = value(key);
if (targetValid()) { if (targetValid()) {
@ -135,7 +135,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
Error OrganicClawReader::field(const char *key, UUID *val) noexcept { Error OrganicClawReader::field(const char *key, UUID *val) noexcept {
UUIDStr str; UUIDStr str;
OX_RETURN_ERROR(field(key, &str)); oxReturnError(field(key, &str));
return UUID::fromString(str).moveTo(*val); return UUID::fromString(str).moveTo(*val);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -8,11 +8,7 @@
#pragma once #pragma once
#include <ox/std/def.hpp>
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
#include <json/json.h> #include <json/json.h>
OX_ALLOW_UNSAFE_BUFFERS_END
#include <ox/model/fieldcounter.hpp> #include <ox/model/fieldcounter.hpp>
#include <ox/model/modelhandleradaptor.hpp> #include <ox/model/modelhandleradaptor.hpp>
@ -137,7 +133,7 @@ class OrganicClawReader {
template<typename T> template<typename T>
Error OrganicClawReader::field(const char *key, T *val) noexcept { Error OrganicClawReader::field(const char *key, T *val) noexcept {
ox::Error err{}; auto err = ox::Error(0);
try { try {
if constexpr (is_integer_v<T>) { if constexpr (is_integer_v<T>) {
if (targetValid()) { if (targetValid()) {
@ -148,11 +144,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
if (jv.empty()) { if (jv.empty()) {
*val = 0; *val = 0;
} else if (rightType) { } else if (rightType) {
if constexpr(ox::is_signed_v<T>) { *val = static_cast<T>(jv.asUInt());
*val = static_cast<T>(jv.asInt64());
} else {
*val = static_cast<T>(jv.asUInt64());
}
} else { } else {
err = ox::Error(1, "Type mismatch"); err = ox::Error(1, "Type mismatch");
} }
@ -160,7 +152,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
} else if constexpr (isVector_v<T>) { } else if constexpr (isVector_v<T>) {
const auto&srcVal = value(key); const auto&srcVal = value(key);
const auto srcSize = srcVal.size(); const auto srcSize = srcVal.size();
OX_RETURN_ERROR(ox::resizeVector(*val, srcSize)); oxReturnError(ox::resizeVector(*val, srcSize));
err = field(key, val->data(), val->size()); err = field(key, val->data(), val->size());
} else if constexpr (isArray_v<T>) { } else if constexpr (isArray_v<T>) {
const auto&srcVal = value(key); const auto&srcVal = value(key);
@ -180,8 +172,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
err = ox::Error(1, "Type mismatch"); err = ox::Error(1, "Type mismatch");
} }
} }
} catch (Json::LogicError const&e) { } catch (Json::LogicError const&) {
oxDebugf("JSON error: {}", e.what());
err = ox::Error(1, "error reading JSON data"); err = ox::Error(1, "error reading JSON data");
} }
++m_fieldIt; ++m_fieldIt;
@ -190,7 +181,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
template<typename U, bool force> template<typename U, bool force>
Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcept { Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcept {
ox::Error err{}; auto err = ox::Error(0);
if (targetValid()) { if (targetValid()) {
const auto &jv = value(key); const auto &jv = value(key);
if (jv.empty() || jv.isObject()) { if (jv.empty() || jv.isObject()) {
@ -207,7 +198,7 @@ Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcep
template<std::size_t L> template<std::size_t L>
Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept { Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
ox::Error err{}; auto err = ox::Error(0);
if (targetValid()) { if (targetValid()) {
const auto &jv = value(key); const auto &jv = value(key);
if (jv.empty()) { if (jv.empty()) {
@ -224,7 +215,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
template<std::size_t L> template<std::size_t L>
Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept { Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
ox::Error err{}; auto err = ox::Error(0);
if (targetValid()) { if (targetValid()) {
const auto &jv = value(key); const auto &jv = value(key);
if (jv.empty()) { if (jv.empty()) {
@ -254,10 +245,10 @@ Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noex
ModelHandlerInterface handler{&r}; ModelHandlerInterface handler{&r};
for (decltype(srcSize) i = 0; i < srcSize; ++i) { for (decltype(srcSize) i = 0; i < srcSize; ++i) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field("", &val[i])); oxReturnError(handler.field("", &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
} }
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
@ -272,9 +263,9 @@ Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcep
ModelHandlerInterface handler{&r}; ModelHandlerInterface handler{&r};
for (decltype(srcSize) i = 0; i < srcSize; ++i) { for (decltype(srcSize) i = 0; i < srcSize; ++i) {
const auto k = keys[i].c_str(); const auto k = keys[i].c_str();
OX_RETURN_ERROR(handler.field(k, &val->operator[](k))); oxReturnError(handler.field(k, &val->operator[](k)));
} }
return {}; return ox::Error(0);
} }
Error readOC(BufferView buff, auto &val) noexcept { Error readOC(BufferView buff, auto &val) noexcept {
@ -301,7 +292,7 @@ OX_ALLOW_UNSAFE_BUFFERS_END
template<typename T> template<typename T>
Result<T> readOC(BufferView buff) noexcept { Result<T> readOC(BufferView buff) noexcept {
Result<T> val; Result<T> val;
OX_RETURN_ERROR(readOC(buff, val.value)); oxReturnError(readOC(buff, val.value));
return val; return val;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -74,44 +74,44 @@ struct TestStruct {
}; };
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept { constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>()); oxReturnError(io->template setTypeInfo<TestUnion>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->fieldCString("String", &obj->String)); oxReturnError(io->fieldCString("String", &obj->String));
return ox::Error(0); return ox::Error(0);
} }
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStructNest> auto *obj) noexcept { constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStructNest> auto *obj) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>()); oxReturnError(io->template setTypeInfo<TestStructNest>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("String", &obj->String)); oxReturnError(io->field("String", &obj->String));
return ox::Error(0); return ox::Error(0);
} }
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept { constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>()); oxReturnError(io->template setTypeInfo<TestStruct>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int)); oxReturnError(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("Int1", &obj->Int1)); oxReturnError(io->field("Int1", &obj->Int1));
OX_RETURN_ERROR(io->field("Int2", &obj->Int2)); oxReturnError(io->field("Int2", &obj->Int2));
OX_RETURN_ERROR(io->field("Int3", &obj->Int3)); oxReturnError(io->field("Int3", &obj->Int3));
OX_RETURN_ERROR(io->field("Int4", &obj->Int4)); oxReturnError(io->field("Int4", &obj->Int4));
OX_RETURN_ERROR(io->field("Int5", &obj->Int5)); oxReturnError(io->field("Int5", &obj->Int5));
OX_RETURN_ERROR(io->field("Int6", &obj->Int6)); oxReturnError(io->field("Int6", &obj->Int6));
OX_RETURN_ERROR(io->field("Int7", &obj->Int7)); oxReturnError(io->field("Int7", &obj->Int7));
OX_RETURN_ERROR(io->field("Int8", &obj->Int8)); oxReturnError(io->field("Int8", &obj->Int8));
OX_RETURN_ERROR(io->field("unionIdx", &obj->unionIdx)); oxReturnError(io->field("unionIdx", &obj->unionIdx));
if (io->opType() == ox::OpType::Reflect) { if (io->opType() == ox::OpType::Reflect) {
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, 0})); oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
} else { } else {
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx})); oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
} }
OX_RETURN_ERROR(io->field("String", &obj->String)); oxReturnError(io->field("String", &obj->String));
OX_RETURN_ERROR(io->field("List", obj->List, 4)); oxReturnError(io->field("List", obj->List, 4));
OX_RETURN_ERROR(io->field("Map", &obj->Map)); oxReturnError(io->field("Map", &obj->Map));
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct)); oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
OX_RETURN_ERROR(io->field("Struct", &obj->Struct)); oxReturnError(io->field("Struct", &obj->Struct));
return ox::Error(0); return ox::Error(0);
} }
@ -210,7 +210,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
auto type = ox::buildTypeDef(typeStore, testIn); auto type = ox::buildTypeDef(typeStore, testIn);
oxAssert(type.error, "Descriptor write failed"); oxAssert(type.error, "Descriptor write failed");
ox::ModelObject testOut; ox::ModelObject testOut;
OX_RETURN_ERROR(testOut.setType(type.value)); oxReturnError(testOut.setType(type.value));
oxAssert(ox::readOC(dataBuff, testOut), "Data read failed"); oxAssert(ox::readOC(dataBuff, testOut), "Data read failed");
oxAssert(testOut.get("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed"); oxAssert(testOut.get("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
oxAssert(testOut.get("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed"); oxAssert(testOut.get("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
@ -259,7 +259,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
ox::TypeStore typeStore; ox::TypeStore typeStore;
auto type = ox::buildTypeDef(typeStore, testIn); auto type = ox::buildTypeDef(typeStore, testIn);
oxAssert(type.error, "Descriptor write failed"); oxAssert(type.error, "Descriptor write failed");
OX_RETURN_ERROR(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(), oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(),
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, [](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f,
ox::OrganicClawReader *rdr) -> ox::Error { ox::OrganicClawReader *rdr) -> ox::Error {
auto fieldName = f.fieldName.c_str(); auto fieldName = f.fieldName.c_str();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -23,7 +23,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, in
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept { Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -8,11 +8,7 @@
#pragma once #pragma once
#include <ox/std/def.hpp>
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
#include <json/json.h> #include <json/json.h>
OX_ALLOW_UNSAFE_BUFFERS_END
#include <ox/model/fieldcounter.hpp> #include <ox/model/fieldcounter.hpp>
#include <ox/model/modelhandleradaptor.hpp> #include <ox/model/modelhandleradaptor.hpp>
@ -46,7 +42,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(const char *key, const int16_t *val) noexcept { Error field(const char *key, const int16_t *val) noexcept {
@ -54,7 +50,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(const char *key, const int32_t *val) noexcept { Error field(const char *key, const int32_t *val) noexcept {
@ -62,7 +58,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(const char *key, const int64_t *val) noexcept { Error field(const char *key, const int64_t *val) noexcept {
@ -70,7 +66,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
@ -79,7 +75,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(const char *key, const uint16_t *val) noexcept { Error field(const char *key, const uint16_t *val) noexcept {
@ -87,7 +83,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(const char *key, const uint32_t *val) noexcept { Error field(const char *key, const uint32_t *val) noexcept {
@ -95,7 +91,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(const char *key, const uint64_t *val) noexcept { Error field(const char *key, const uint64_t *val) noexcept {
@ -103,7 +99,7 @@ class OrganicClawWriter {
value(key) = *val; value(key) = *val;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error field(char const*key, bool const*val) noexcept { Error field(char const*key, bool const*val) noexcept {
@ -126,8 +122,8 @@ class OrganicClawWriter {
for (std::size_t i = 0; i < keys.size(); ++i) { for (std::size_t i = 0; i < keys.size(); ++i) {
const auto k = keys[i].c_str(); const auto k = keys[i].c_str();
if (k) [[likely]] { if (k) [[likely]] {
OX_REQUIRE_M(value, val->at(k)); oxRequireM(value, val->at(k));
OX_RETURN_ERROR(handler.field(k, value)); oxReturnError(handler.field(k, value));
} }
} }
value(key) = w.m_json; value(key) = w.m_json;
@ -151,7 +147,7 @@ class OrganicClawWriter {
value(key) = val->c_str(); value(key) = val->c_str();
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Error fieldCString(const char*, const char *const*val, int len) noexcept; Error fieldCString(const char*, const char *const*val, int len) noexcept;
@ -205,13 +201,13 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w}; ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field({}, &val[i])); oxReturnError(handler.field({}, &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END OX_ALLOW_UNSAFE_BUFFERS_END
} }
value(key) = w.m_json; value(key) = w.m_json;
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
template<typename T> template<typename T>
@ -231,13 +227,13 @@ Error OrganicClawWriter::field(const char *key, const T *val) noexcept {
} else if (val && targetValid()) { } else if (val && targetValid()) {
OrganicClawWriter w; OrganicClawWriter w;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w}; ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
OX_RETURN_ERROR(model(&handler, val)); oxReturnError(model(&handler, val));
if (!w.m_json.empty() || m_json.isArray()) { if (!w.m_json.empty() || m_json.isArray()) {
value(key) = w.m_json; value(key) = w.m_json;
} }
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
template<typename U, bool force> template<typename U, bool force>
@ -245,40 +241,36 @@ Error OrganicClawWriter::field(const char *key, UnionView<U, force> val) noexcep
if (targetValid()) { if (targetValid()) {
OrganicClawWriter w(val.idx()); OrganicClawWriter w(val.idx());
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w}; ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
OX_RETURN_ERROR(model(&handler, val.get())); oxReturnError(model(&handler, val.get()));
if (!w.m_json.isNull()) { if (!w.m_json.isNull()) {
value(key) = w.m_json; value(key) = w.m_json;
} }
} }
++m_fieldIt; ++m_fieldIt;
return {}; return ox::Error(0);
} }
Result<ox::Buffer> writeOC(const auto &val) noexcept { Result<ox::Buffer> writeOC(const auto &val) noexcept {
OrganicClawWriter writer; OrganicClawWriter writer;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer); ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
OX_RETURN_ERROR(model(&handler, &val)); oxReturnError(model(&handler, &val));
Json::StreamWriterBuilder const jsonBuilder; Json::StreamWriterBuilder const jsonBuilder;
const auto str = Json::writeString(jsonBuilder, writer.m_json); const auto str = Json::writeString(jsonBuilder, writer.m_json);
Result<Buffer> buff; Result<Buffer> buff;
buff.value.resize(str.size() + 1); buff.value.resize(str.size() + 1);
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
memcpy(buff.value.data(), str.data(), str.size() + 1); memcpy(buff.value.data(), str.data(), str.size() + 1);
OX_ALLOW_UNSAFE_BUFFERS_END
return buff; return buff;
} }
Result<ox::String> writeOCString(const auto &val) noexcept { Result<ox::String> writeOCString(const auto &val) noexcept {
OrganicClawWriter writer; OrganicClawWriter writer;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer); ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
OX_RETURN_ERROR(model(&handler, &val)); oxReturnError(model(&handler, &val));
Json::StreamWriterBuilder const jsonBuilder; Json::StreamWriterBuilder const jsonBuilder;
const auto str = Json::writeString(jsonBuilder, writer.m_json); const auto str = Json::writeString(jsonBuilder, writer.m_json);
Result<ox::String> buff; Result<ox::String> buff;
buff.value.resize(str.size()); buff.value.resize(str.size());
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
memcpy(buff.value.data(), str.data(), str.size() + 1); memcpy(buff.value.data(), str.data(), str.size() + 1);
OX_ALLOW_UNSAFE_BUFFERS_END
return buff; return buff;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -63,7 +63,7 @@ struct AlignmentCatcher: public ModelHandlerBase<AlignmentCatcher<PlatSpec>, OpT
template<typename T> template<typename T>
constexpr ox::Error field(StringViewCR, const T *val, std::size_t cnt) noexcept { constexpr ox::Error field(StringViewCR, const T *val, std::size_t cnt) noexcept {
for (std::size_t i = 0; i < cnt; ++i) { for (std::size_t i = 0; i < cnt; ++i) {
OX_RETURN_ERROR(field(nullptr, &val[i])); oxReturnError(field(nullptr, &val[i]));
} }
return {}; return {};
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -162,7 +162,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const ox::UnionView
if (!unionCheckAndIt()) { if (!unionCheckAndIt()) {
return {}; return {};
} }
OX_RETURN_ERROR(pad(val.get())); oxReturnError(pad(val.get()));
m_unionIdx.emplace_back(val.idx()); m_unionIdx.emplace_back(val.idx());
const auto err = preload<PlatSpec, U>(this, val.get()); const auto err = preload<PlatSpec, U>(this, val.get());
m_unionIdx.pop_back(); m_unionIdx.pop_back();
@ -175,13 +175,13 @@ constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR name, const T *val)
if (!unionCheckAndIt()) { if (!unionCheckAndIt()) {
return {}; return {};
} }
OX_RETURN_ERROR(pad(val)); oxReturnError(pad(val));
if constexpr(ox::is_integral_v<T>) { if constexpr(ox::is_integral_v<T>) {
return ox::serialize(m_writer, PlatSpec::correctEndianness(*val)); return ox::serialize(m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) { } else if constexpr(ox::is_pointer_v<T>) {
const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart; const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
OX_RETURN_ERROR(field(name, *val)); oxReturnError(field(name, *val));
OX_RETURN_ERROR(endAlloc()); oxReturnError(endAlloc());
return ox::serialize(m_writer, PlatSpec::correctEndianness(a)); return ox::serialize(m_writer, PlatSpec::correctEndianness(a));
} else if constexpr(ox::isVector_v<T>) { } else if constexpr(ox::isVector_v<T>) {
return fieldVector(name, val); return fieldVector(name, val);
@ -211,19 +211,19 @@ constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const ox::BasicStri
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)), .size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)), .cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(sz)),
}; };
OX_RETURN_ERROR(pad(&vecVal)); oxReturnError(pad(&vecVal));
const auto restore = m_writer.tellp(); const auto restore = m_writer.tellp();
std::size_t a = 0; std::size_t a = 0;
if (sz && sz >= SmallStringSize) { if (sz && sz >= SmallStringSize) {
OX_RETURN_ERROR(ox::allocate(m_writer, sz).moveTo(a)); oxReturnError(ox::allocate(m_writer, sz).moveTo(a));
} else { } else {
a = restore; a = restore;
} }
vecVal.items = PlatSpec::correctEndianness(static_cast<PtrType>(a) + PlatSpec::RomStart); vecVal.items = PlatSpec::correctEndianness(static_cast<PtrType>(a) + PlatSpec::RomStart);
OX_RETURN_ERROR(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
OX_RETURN_ERROR(m_writer.write(val->data(), sz)); oxReturnError(m_writer.write(val->data(), sz));
OX_RETURN_ERROR(m_writer.seekp(restore)); oxReturnError(m_writer.seekp(restore));
OX_RETURN_ERROR(serialize(m_writer, vecVal)); oxReturnError(serialize(m_writer, vecVal));
m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items); m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items);
return {}; return {};
} }
@ -234,12 +234,12 @@ constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR name, const ox::Arra
if (!unionCheckAndIt()) { if (!unionCheckAndIt()) {
return {}; return {};
} }
OX_RETURN_ERROR(pad(&(*val)[0])); oxReturnError(pad(&(*val)[0]));
// serialize the Array elements // serialize the Array elements
if constexpr(sz) { if constexpr(sz) {
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < val->size(); ++i) { for (std::size_t i = 0; i < val->size(); ++i) {
OX_RETURN_ERROR(this->interface()->field(name, &(*val)[i])); oxReturnError(this->interface()->field(name, &(*val)[i]));
} }
m_unionIdx.pop_back(); m_unionIdx.pop_back();
} }
@ -253,11 +253,11 @@ constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const T **val, std:
return {}; return {};
} }
if (cnt) { if (cnt) {
OX_RETURN_ERROR(pad(*val)); oxReturnError(pad(*val));
// serialize the array // serialize the array
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < cnt; ++i) { for (std::size_t i = 0; i < cnt; ++i) {
OX_RETURN_ERROR(this->interface()->field(nullptr, &val[i])); oxReturnError(this->interface()->field(nullptr, &val[i]));
} }
m_unionIdx.pop_back(); m_unionIdx.pop_back();
} }
@ -267,11 +267,11 @@ constexpr ox::Error Preloader<PlatSpec>::field(StringViewCR, const T **val, std:
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept { constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept {
m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp())); m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp()));
OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
auto const padding = calcPadding(align); auto const padding = calcPadding(align);
OX_REQUIRE_M(a, ox::allocate(m_writer, sz + padding)); oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding; a += padding;
OX_RETURN_ERROR(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a); m_allocStart.push_back(a);
return a; return a;
} }
@ -280,11 +280,11 @@ template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc( constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(
std::size_t sz, size_t align, std::size_t restore) noexcept { std::size_t sz, size_t align, std::size_t restore) noexcept {
m_allocStack.emplace_back(restore, ox::ios_base::beg); m_allocStack.emplace_back(restore, ox::ios_base::beg);
OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
auto const padding = calcPadding(align); auto const padding = calcPadding(align);
OX_REQUIRE_M(a, ox::allocate(m_writer, sz + padding)); oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding; a += padding;
OX_RETURN_ERROR(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a); m_allocStart.push_back(a);
return a; return a;
} }
@ -295,7 +295,7 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
return m_writer.seekp(0, ox::ios_base::end); return m_writer.seekp(0, ox::ios_base::end);
} }
const auto &si = *m_allocStack.back().unwrap(); const auto &si = *m_allocStack.back().unwrap();
OX_RETURN_ERROR(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir)); oxReturnError(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir));
m_allocStack.pop_back(); m_allocStack.pop_back();
m_allocStart.pop_back(); m_allocStart.pop_back();
return {}; return {};
@ -304,12 +304,12 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept { constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
for (const auto &p : m_ptrs) { for (const auto &p : m_ptrs) {
OX_RETURN_ERROR(m_writer.seekp(p.loc)); oxReturnError(m_writer.seekp(p.loc));
const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>( const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(
static_cast<typename PlatSpec::PtrType>(p.value + offset)); static_cast<typename PlatSpec::PtrType>(p.value + offset));
OX_RETURN_ERROR(ox::serialize(m_writer, val)); oxReturnError(ox::serialize(m_writer, val));
} }
OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
return {}; return {};
} }
@ -354,39 +354,39 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldVector( constexpr ox::Error Preloader<PlatSpec>::fieldVector(
StringViewCR, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept { StringViewCR, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept {
OX_RETURN_ERROR(pad(&vecVal)); oxReturnError(pad(&vecVal));
const auto vecValPt = m_writer.tellp(); const auto vecValPt = m_writer.tellp();
// serialize the Vector elements // serialize the Vector elements
if (val->size()) { if (val->size()) {
const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size(); const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
const auto align = alignOf<PlatSpec>((*val)[0]); const auto align = alignOf<PlatSpec>((*val)[0]);
OX_RETURN_ERROR(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
auto const padding = calcPadding(align); auto const padding = calcPadding(align);
OX_REQUIRE_M(p, ox::allocate(m_writer, sz + padding)); oxRequireM(p, ox::allocate(m_writer, sz + padding));
p += padding; p += padding;
OX_RETURN_ERROR(m_writer.seekp(p)); oxReturnError(m_writer.seekp(p));
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < val->size(); ++i) { for (std::size_t i = 0; i < val->size(); ++i) {
OX_RETURN_ERROR(this->interface()->field(nullptr, &val->operator[](i))); oxReturnError(this->interface()->field(nullptr, &val->operator[](i)));
} }
m_unionIdx.pop_back(); m_unionIdx.pop_back();
vecVal.items = PlatSpec::correctEndianness( vecVal.items = PlatSpec::correctEndianness(
static_cast<typename PlatSpec::size_t>(p + PlatSpec::RomStart)); static_cast<typename PlatSpec::size_t>(p + PlatSpec::RomStart));
OX_RETURN_ERROR(m_writer.seekp(vecValPt)); oxReturnError(m_writer.seekp(vecValPt));
} else { } else {
vecVal.items = 0; vecVal.items = 0;
} }
// serialize the Vector // serialize the Vector
OX_RETURN_ERROR(serialize(m_writer, vecVal)); oxReturnError(serialize(m_writer, vecVal));
m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items); m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items);
return {}; return {};
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldArray(StringViewCR, ox::ModelValueArray const*val) noexcept { constexpr ox::Error Preloader<PlatSpec>::fieldArray(StringViewCR, ox::ModelValueArray const*val) noexcept {
OX_RETURN_ERROR(pad(&(*val)[0])); oxReturnError(pad(&(*val)[0]));
for (auto const&v : *val) { for (auto const&v : *val) {
OX_RETURN_ERROR(this->interface()->field({}, &v)); oxReturnError(this->interface()->field({}, &v));
} }
return {}; return {};
} }
@ -405,7 +405,7 @@ constexpr size_t Preloader<PlatSpec>::calcPadding(size_t align) const noexcept {
template<typename PlatSpec, typename T> template<typename PlatSpec, typename T>
constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept { constexpr ox::Error preload(Preloader<PlatSpec> *pl, ox::CommonPtrWith<T> auto *obj) noexcept {
OX_RETURN_ERROR(model(pl->interface(), obj)); oxReturnError(model(pl->interface(), obj));
return pl->pad(obj); return pl->pad(obj);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -74,7 +74,7 @@ template<typename T, bool force>
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const UnionView<T, force> val) noexcept { constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const UnionView<T, force> val) noexcept {
pad(val.get()); pad(val.get());
UnionSizeCatcher<PlatSpec> sc; UnionSizeCatcher<PlatSpec> sc;
OX_RETURN_ERROR(model(sc.interface(), val.get())); oxReturnError(model(sc.interface(), val.get()));
m_size += sc.size(); m_size += sc.size();
return {}; return {};
} }
@ -91,7 +91,7 @@ template<typename PlatSpec>
template<typename T> template<typename T>
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const T **val, std::size_t cnt) noexcept { constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const T **val, std::size_t cnt) noexcept {
for (std::size_t i = 0; i < cnt; ++i) { for (std::size_t i = 0; i < cnt; ++i) {
OX_RETURN_ERROR(field("", &val[i])); oxReturnError(field("", &val[i]));
} }
return {}; return {};
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -43,7 +43,7 @@ class UnionSizeCatcher: public ModelHandlerBase<UnionSizeCatcher<PlatSpec>, OpTy
template<typename T, bool force> template<typename T, bool force>
constexpr ox::Error field(StringViewCR, const UnionView<T, force> val) noexcept { constexpr ox::Error field(StringViewCR, const UnionView<T, force> val) noexcept {
UnionSizeCatcher<PlatSpec> sc; UnionSizeCatcher<PlatSpec> sc;
OX_RETURN_ERROR(model(sc.interface(), val.get())); oxReturnError(model(sc.interface(), val.get()));
m_size += sc.size(); m_size += sc.size();
return {}; return {};
} }
@ -80,7 +80,7 @@ template<typename PlatSpec>
template<typename T> template<typename T>
constexpr ox::Error UnionSizeCatcher<PlatSpec>::field(StringViewCR, const T **val, std::size_t cnt) noexcept { constexpr ox::Error UnionSizeCatcher<PlatSpec>::field(StringViewCR, const T **val, std::size_t cnt) noexcept {
for (std::size_t i = 0; i < cnt; ++i) { for (std::size_t i = 0; i < cnt; ++i) {
OX_RETURN_ERROR(field("", &val[i])); oxReturnError(field("", &val[i]));
} }
return {}; return {};
} }

View File

@ -109,7 +109,6 @@ install(
error.hpp error.hpp
fmt.hpp fmt.hpp
hardware.hpp hardware.hpp
hash.hpp
hashmap.hpp hashmap.hpp
heapmgr.hpp heapmgr.hpp
ignore.hpp ignore.hpp

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -9,25 +9,13 @@
#pragma once #pragma once
#include "def.hpp" #include "def.hpp"
#include "error.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage) OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox { namespace ox {
template<typename It, typename T> template<typename It, typename T>
constexpr ox::Result<size_t> findIdx(It begin, It end, T const&value) { constexpr It find(It begin, It end, const T &value) {
auto it = begin;
for (; it != end; ++it) {
if (*it == value) {
return it.offset();
}
}
return ox::Error{1, "item not found"};
}
template<typename It, typename T>
constexpr It find(It begin, It end, T const&value) {
for (; begin != end; ++begin) { for (; begin != end; ++begin) {
if (*begin == value) { if (*begin == value) {
return begin; return begin;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -15,22 +15,18 @@
namespace ox { namespace ox {
namespace detail { class AnyPtr {
template<bool unique>
class AnyPtrT {
private: private:
struct WrapBase { struct WrapBase {
virtual constexpr ~WrapBase() = default; virtual constexpr ~WrapBase() = default;
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0; virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
virtual constexpr operator bool() const noexcept = 0; virtual constexpr operator bool() const noexcept = 0;
virtual void free() noexcept = 0;
}; };
template<typename T> template<typename T>
struct Wrap final: WrapBase { struct Wrap: public WrapBase {
T *data{}; T *data{};
explicit constexpr Wrap(T *pData) noexcept: data(pData) { constexpr Wrap(T *pData) noexcept: data(pData) {
} }
constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override { constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override {
oxAssert(s.size() >= sizeof(Wrap), "too small buffer"); oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
@ -43,60 +39,39 @@ class AnyPtrT {
constexpr operator bool() const noexcept override { constexpr operator bool() const noexcept override {
return data != nullptr; return data != nullptr;
} }
constexpr void free() noexcept override {
safeDelete(data);
data = {};
}
}; };
WrapBase *m_wrapPtr{}; WrapBase *m_wrapPtr{};
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData; ox::Array<char, sizeof(Wrap<void*>)> m_wrapData;
public: public:
constexpr AnyPtrT() noexcept = default; constexpr AnyPtr() noexcept = default;
template<typename T> template<typename T>
constexpr AnyPtrT(T *ptr) noexcept { constexpr AnyPtr(T *ptr) noexcept {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap<T>(ptr); m_wrapPtr = new Wrap(ptr);
} else { } else {
m_wrapPtr = new(m_wrapData.data()) Wrap<T>(ptr); m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
} }
} }
constexpr AnyPtrT(AnyPtrT const&other) noexcept requires(!unique) { constexpr AnyPtr(AnyPtr const&other) noexcept {
if (other) { if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
} }
} }
constexpr AnyPtrT(AnyPtrT &&other) noexcept { constexpr ~AnyPtr() noexcept {
if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
}
other.m_wrapPtr = {};
}
}
constexpr ~AnyPtrT() noexcept {
if constexpr(unique) {
free();
}
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_wrapPtr);
} }
} }
template<typename T> template<typename T>
constexpr AnyPtrT &operator=(T *ptr) noexcept { constexpr AnyPtr &operator=(T *ptr) noexcept {
if constexpr(unique) {
free();
} else if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
}
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
m_wrapPtr = new Wrap(ptr); m_wrapPtr = new Wrap(ptr);
} else { } else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
@ -104,33 +79,11 @@ class AnyPtrT {
return *this; return *this;
} }
constexpr AnyPtrT &operator=(AnyPtrT const&ptr) noexcept requires(!unique) { constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept {
if (this != &ptr) { if (this != &ptr) {
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
}
if (ptr) { if (ptr) {
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
} else {
m_wrapPtr = nullptr;
}
}
return *this;
}
constexpr AnyPtrT &operator=(AnyPtrT &&ptr) noexcept {
if (this != &ptr) {
if constexpr(unique) {
free();
} else if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_wrapPtr);
}
if (ptr) {
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
if (std::is_constant_evaluated()) {
ox::safeDelete(ptr.m_wrapPtr);
ptr.m_wrapPtr = nullptr;
}
} else { } else {
m_wrapPtr = nullptr; m_wrapPtr = nullptr;
} }
@ -142,16 +95,6 @@ class AnyPtrT {
return m_wrapPtr && *m_wrapPtr; return m_wrapPtr && *m_wrapPtr;
} }
constexpr void free() noexcept {
if (m_wrapPtr) {
m_wrapPtr->free();
}
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
}
m_wrapPtr = nullptr;
}
template<typename T> template<typename T>
[[nodiscard]] [[nodiscard]]
constexpr T *get() const noexcept { constexpr T *get() const noexcept {
@ -161,12 +104,6 @@ class AnyPtrT {
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data; return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
#endif #endif
} }
}; };
} }
using AnyPtr = detail::AnyPtrT<false>;
using UAnyPtr = detail::AnyPtrT<true>;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -181,13 +181,13 @@ constexpr Array<T, ArraySize> &Array<T, ArraySize>::operator=(Array &&other) noe
template<typename T, std::size_t ArraySize> template<typename T, std::size_t ArraySize>
constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept { constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept {
boundsCheck(__FILE__, __LINE__, i, size(), "Array access overflow"); ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
return m_items[i]; return m_items[i];
} }
template<typename T, std::size_t ArraySize> template<typename T, std::size_t ArraySize>
constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept { constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept {
boundsCheck(__FILE__, __LINE__, i, size(), "Array access overflow"); ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
return m_items[i]; return m_items[i];
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2025 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -7,7 +7,6 @@
*/ */
#include "fmt.hpp" #include "fmt.hpp"
#include "realstd.hpp"
#include "stacktrace.hpp" #include "stacktrace.hpp"
#include "trace.hpp" #include "trace.hpp"
@ -15,14 +14,14 @@
namespace ox { namespace ox {
void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const&err) noexcept { void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err) noexcept {
oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg); oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg);
if (err.msg) { if (err.msg) {
oxErrf("\tError Message:\t{}\n", err.msg); oxErrf("\tError Message:\t{}\n", err.msg);
} }
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err)); oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.src.file_name() != nullptr) { if (err.file != nullptr) {
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line()); oxErrf("\tError Location:\t{}:{}\n", err.file, err.line);
} }
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
printStackTrace(2); printStackTrace(2);
@ -33,19 +32,16 @@ void panic(StringViewCR file, int const line, StringViewCR panicMsg, Error const
#endif #endif
} }
void panic(const char *file, int const line, char const*panicMsg, Error const&err) noexcept { void panic(const char *file, int line, const char *panicMsg, const Error &err) noexcept {
panic(StringView{file}, line, StringView{panicMsg}, err); panic(StringView{file}, line, StringView{panicMsg}, err);
} }
void assertFailFuncRuntime( void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept {
StringViewCR file,
int const line,
StringViewCR assertTxt,
StringViewCR msg) noexcept {
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
auto const st = genStackTrace(2); auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]:\n{}", msg, assertTxt, file, line, st); output += genStackTrace(2);
abort(); oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
std::abort();
#else #else
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg); oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line); oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
@ -53,25 +49,20 @@ void assertFailFuncRuntime(
#endif #endif
} }
void assertFailFuncRuntime( void assertFailFuncRuntime(StringViewCR file, int line, [[maybe_unused]] const Error &err, StringViewCR, StringViewCR assertMsg) noexcept {
StringViewCR file,
int const line,
[[maybe_unused]] Error const&err,
StringViewCR,
StringViewCR assertMsg) noexcept {
#if defined(OX_USE_STDLIB) #if defined(OX_USE_STDLIB)
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg); auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
if (err.msg) { if (err.msg) {
msg += sfmt("\tError Message:\t{}\n", err.msg); msg += sfmt("\tError Message:\t{}\n", err.msg);
} }
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err)); msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.src.file_name() != nullptr) { if (err.file != nullptr) {
msg += sfmt("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line()); msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
} }
msg += genStackTrace(2); msg += genStackTrace(2);
oxErr(msg); oxErr(msg);
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line); oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
abort(); std::abort();
#else #else
constexprPanic(file, line, assertMsg); constexprPanic(file, line, assertMsg);
#endif #endif

Some files were not shown because too many files have changed in this diff Show More