Compare commits

...

98 Commits

Author SHA1 Message Date
1b32bdfcad [nostalgia/studio] Bump version to d2024.12.3
All checks were successful
Build / build (push) Successful in 3m14s
2025-01-17 21:45:37 -06:00
3544392fa8 [nostalgia/core/studio] Cleanup, fix possible TileSheet fill tool failure
All checks were successful
Build / build (push) Successful in 3m21s
2025-01-17 21:43:46 -06:00
144d234d09 [nostalgia/studio] Change version to release-d2024.12
All checks were successful
Build / build (push) Successful in 3m20s
2025-01-12 21:03:34 -06:00
465fb06f76 [nostalgia/core] Fix TileSheet validation/repair to ensure pixels gets cleared if there are subsheets
Some checks failed
Build / build (push) Has been cancelled
2025-01-12 20:58:19 -06:00
db953dd0d1 [studio] Fix new project menu to return an appropriately sized string for name 2025-01-12 20:58:19 -06:00
daab4dc4f5 [nostalgia/core/studio] Fix SubSheet editor to return an appropriately sized string 2025-01-12 20:58:19 -06:00
83cbac5cca [nostalgia/studio] Update version to d2024.12.1
All checks were successful
Build / build (push) Successful in 3m19s
2025-01-11 17:22:02 -06:00
74e518fee0 [nostalgia/core/studio/tilesheeteditor] Fix select all not to go beyond end 2025-01-11 17:07:50 -06:00
6b0ce40c02 [nostalgia/core/studio] Fix crash that occurs when a non-leaf node subsheet is selected 2025-01-11 17:07:50 -06:00
4f55964dd9 [nostalgia/core/studio] Fix tile insert to correct input when inserting past the last tile 2025-01-11 17:07:50 -06:00
cb597cf92e [nostalgia/core/studio] Fix tile insert to work on last tile 2025-01-11 17:07:50 -06:00
6906c66ba7 [keel] Fix reloadAsset 2025-01-11 17:07:50 -06:00
ba00d10dfc [nostalgia] Update liccor file 2025-01-11 17:07:50 -06:00
cdfbfe48b7 [ox] Update liccor file 2025-01-11 17:07:50 -06:00
21ae2a14e9 [ox] Run liccor 2025-01-11 17:07:50 -06:00
81b120b1ce [nostalgia,olympic] Run liccor 2025-01-11 17:07:50 -06:00
40938958de [turbine/glfw] Ensure window opens with a standard mandatory refresh period 2025-01-11 17:07:50 -06:00
df190c05a0 [studio] Make first tab not draw before selected tab when window opens 2025-01-11 17:07:50 -06:00
3fe3b08eca [ox/std] Add hash.hpp to install 2025-01-11 17:07:50 -06:00
ecc5ae6b2f [studio] Make selection tracker not go below 0 2025-01-11 17:07:50 -06:00
a863bfc181 [nostalgia/studio] Update version to d2024.12.0
All checks were successful
Build / build (push) Successful in 3m20s
2024-12-21 19:27:00 -06:00
a75c4a11d3 [nfde] Address CMake warning, remove unwanted logging
All checks were successful
Build / build (push) Successful in 2m45s
2024-12-21 17:07:23 -06:00
347a165762 [sample_project] Update type descriptors
All checks were successful
Build / build (push) Successful in 2m55s
2024-12-21 02:45:24 -06:00
fd64bfae13 [keel] Fix a use after free, cleanup
Some checks are pending
Build / build (push) Waiting to run
2024-12-21 02:42:19 -06:00
aaeec20ac9 [nostalgia/player] Fix build 2024-12-21 02:42:05 -06:00
37030f9c11 [keel] Cleanup pack tool 2024-12-21 02:41:56 -06:00
462f2bca4c [nostalgia,olympic] Change macro names to comply with broader conventions 2024-12-21 02:41:19 -06:00
dc72500b98 [glutils] Change macro names to comply with broader conventions 2024-12-18 22:04:39 -06:00
962fe8bc22 [ox] Change macro names to comply with broader conventions 2024-12-18 22:04:25 -06:00
305eb62647 [studio] Fix build
Some checks are pending
Build / build (push) Waiting to run
2024-12-18 21:41:15 -06:00
4754359a21 [ox/std] Cleanup Vec2
Some checks failed
Build / build (push) Has been cancelled
2024-12-15 01:26:41 -06:00
dc07f3d58b [studio] Change FilePicker consturctor to take StringParams 2024-12-15 01:20:29 -06:00
fcdcfd10d1 [ox/std] Run liccor
All checks were successful
Build / build (push) Successful in 2m52s
2024-12-14 14:33:43 -06:00
b74f6a7ace [studio,turbine] Run liccor 2024-12-14 14:33:06 -06:00
ac7e5be187 [ox] Remove OxException
All checks were successful
Build / build (push) Successful in 2m52s
2024-12-14 00:40:05 -06:00
ed910c0beb [nostalgia/core/studio/tilesheeteditor] Fix access overflow on out of bounds Fill command
All checks were successful
Build / build (push) Successful in 2m51s
2024-12-13 22:24:58 -06:00
345fb03857 [ox] Remove OxError 2024-12-13 22:06:47 -06:00
9881253f2a [glutils] Cleanup OxError 2024-12-13 22:06:26 -06:00
96d27eecd1 [nostalgia,olympic] Cleanup 2024-12-13 22:00:03 -06:00
28ebe93b77 [ox/std] Make source_location::current only init if valid
All checks were successful
Build / build (push) Successful in 2m52s
2024-12-12 23:13:39 -06:00
e849e7a3dd [ox/std] Add source_location
Some checks failed
Build / build (push) Has been cancelled
2024-12-12 23:09:01 -06:00
e6777b0ad7 [cityhash] Add install rule 2024-12-12 22:36:09 -06:00
c488c336de [turbine/glfw] Fix mandatoryRefreshPeriodEnd tracking
All checks were successful
Build / build (push) Successful in 2m54s
2024-12-11 22:13:28 -06:00
003f97201f [turbine/glfw] Move MandatoryRefreshPeriod to config.hpp
All checks were successful
Build / build (push) Successful in 2m45s
2024-12-10 23:29:50 -06:00
d85a10af84 [nostalgia/core/studio] Cleanup 2024-12-10 23:29:21 -06:00
ff05d860c4 [turbine/glfw] Replace uninterruptedRefreshes with mandatoryRefreshPeriodEnd
Some checks failed
Build / build (push) Has been cancelled
2024-12-10 01:49:20 -06:00
7679403742 [turbine] Add init wrapper that takes FS path 2024-12-06 23:20:30 -06:00
c51a45e1ba [olympic] Cleanup 2024-12-06 00:22:33 -06:00
a6e24ff2b6 [ox/std] Add CString type alias 2024-12-06 00:20:03 -06:00
e0ec9e0c5f [nostalgia,olympic] Move olympic::run to global namespace
All checks were successful
Build / build (push) Successful in 2m34s
2024-12-06 00:13:10 -06:00
9a42a9b9d9 [nfde] Fix Windows warnings 2024-12-06 00:12:38 -06:00
03a05c511e Merge commit '4ccdfc3a6e5bd501968903a01f7d8141b6f88375'
All checks were successful
Build / build (push) Successful in 2m31s
2024-12-04 19:55:17 -06:00
bd91137d27 [nostalgia,olympic] Fix pack tool build for Windows 2024-12-02 21:10:52 -06:00
161640fa11 [nostalgia] Cleanup
All checks were successful
Build / build (push) Successful in 2m46s
2024-12-02 19:58:05 -06:00
2b7d12945e [nostalgia/core/studio] Fix MSVC build 2024-12-01 19:42:29 -06:00
e42126c956 [nostalgia/core] Improve TileSheet validation, add repair
All checks were successful
Build / build (push) Successful in 2m40s
2024-12-01 15:47:49 -06:00
36942cca18 [nostalgia,olympic] Replace SpanView with Span<const T>
All checks were successful
Build / build (push) Successful in 2m36s
2024-12-01 08:41:20 -06:00
b14f1d5000 [ox] Replace SpanView with Span<const T> 2024-12-01 08:41:08 -06:00
1bf4f246c2 [applib] Make run take args as a SpanView 2024-11-28 00:51:42 -06:00
edda8e010e [ox/clargs] Add constructor that takes a SpanView 2024-11-28 00:51:02 -06:00
3308b4dd72 [ox/std] Add missing + and += operators to Span
All checks were successful
Build / build (push) Successful in 2m38s
2024-11-27 00:17:37 -06:00
27f4703a9a [teagba] Suppress warnings for unsafe buffers 2024-11-27 00:15:59 -06:00
6af00d9a2e [nostalgia] Enable warnings for unsafe buffers 2024-11-27 00:14:57 -06:00
86b9f9316e [olympic] Enable warnings for unsafe buffers 2024-11-26 23:58:11 -06:00
a0ed1b3f62 [ox/std] Fix Span raw array constructor 2024-11-26 23:57:41 -06:00
8dad624b21 [studio/applib] Cleanup 2024-11-26 23:32:32 -06:00
dc6605fd48 [keel] Add missing error checking to pack 2024-11-26 23:32:15 -06:00
c78d3cf638 [ox] Add more unsafe buffer exceptions 2024-11-26 23:31:34 -06:00
cee4f65d4a [ox/std] Replace an unsafe buffer
All checks were successful
Build / build (push) Successful in 2m38s
2024-11-26 22:31:20 -06:00
cd3eeeef14 [ox/fs] Suppress unsafe buffer warnings 2024-11-26 22:30:57 -06:00
287d42f2b9 [ox/clargs] Cleanup
All checks were successful
Build / build (push) Successful in 2m41s
2024-11-26 22:08:36 -06:00
dbbaaa46b9 [ox/clargs] Enable unsafe buffer warnings
Some checks failed
Build / build (push) Has been cancelled
2024-11-26 22:06:50 -06:00
9b8a8c4e46 [ox/std] Enable unsafe buffer warnings 2024-11-26 21:59:26 -06:00
e44fa288fd [cityhash] Add pragmas to ignore unsafe buffer warnings 2024-11-26 21:58:39 -06:00
e13c6e812b [ox/std] Remove raw char* CharBufferWriter constructor 2024-11-26 20:48:13 -06:00
cb55b31afa [ox/std] Cleanup 2024-11-26 20:43:43 -06:00
ab3f9e1627 [ox/std] Make Span access check message consistent with other messages 2024-11-26 20:43:20 -06:00
8f25ef96ff [ox/std] Make CharBufferWriter constructor take a Span 2024-11-26 20:42:33 -06:00
e13eebaf0b [ox/std] Cleanup an unsafe buffer 2024-11-26 20:38:00 -06:00
114f5c6685 [ox/std] Add overflow checking to SpanIterator
All checks were successful
Build / build (push) Successful in 2m36s
2024-11-19 01:09:48 -06:00
df44fe235b [keel] Cleanup
All checks were successful
Build / build (push) Successful in 2m42s
2024-11-15 19:59:42 -06:00
72f4db3d5e [nostalgia/core/studio] Fix paste command to never paste beyond target dimensions
All checks were successful
Build / build (push) Successful in 2m40s
2024-11-15 01:39:57 -06:00
8a9ff971a1 [nostalgia/core] Fix resizeSubsheet to work for both growing and shrinking 2024-11-15 01:09:48 -06:00
5a8da59df1 [keel] Fix readAsset to actually return asset 2024-11-15 01:01:31 -06:00
afa3a13d41 [keel] Cleanup 2024-11-14 21:23:42 -06:00
6522cf8a43 [keel] Add ensureValid call to readAsset 2024-11-14 21:17:41 -06:00
f772e48b36 [ox] Add Vector/Array/Span overflow checking 2024-11-14 21:08:38 -06:00
13bfe88195 [nostalgia/core] Fix resizeSubsheet array overflow 2024-11-14 19:59:58 -06:00
5025475414 Merge commit '9e11019b87ba27d1dac9e097dc212a126e404218' 2024-11-01 22:23:08 -05:00
3c7652efc2 [nostalgia/core/studio] Fix PaletteEditor to handle Palettes with 0 pages
All checks were successful
Build / build (push) Successful in 2m55s
2024-10-28 20:57:34 -05:00
941bc71348 [studio] Fix NewMenu name input 2024-10-28 20:57:34 -05:00
bfe890ae00 [ox] Fix typo in docs 2024-10-08 23:04:49 -05:00
ab5bc1adb6 [ox/std] Remove oxRequireT and oxRequireMT 2024-10-06 06:16:14 -05:00
abf7548ab5 [nostalgia/core] Add missing include 2024-10-04 21:36:26 -05:00
e2682b5ef7 [studio/modlib] Add missing include 2024-10-04 21:35:08 -05:00
792ad41499 [nostalgia] Remove .vs dir 2024-10-04 18:51:36 -05:00
e4ae23e114 [olympic/developer-handbook] Remove Ox submodules from project structure
All checks were successful
Build / build (push) Successful in 2m31s
2024-10-04 01:22:21 -05:00
67187d5ec5 [olympic/developer-handbook] Elaborate more on exception usage 2024-10-04 01:18:25 -05:00
403 changed files with 3736 additions and 3286 deletions

View File

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

View File

@ -1,44 +0,0 @@
{
"version": "0.2.1",
"defaults": {},
"configurations": [
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "nostalgia.exe (Install)",
"name": "nostalgia.exe (Install)",
"args": [
"${projectDir}/sample_project"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "nostalgia.exe",
"name": "nostalgia.exe",
"args": [
"${projectDir}/sample_project"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "nostalgia-studio.exe (Install)",
"name": "nostalgia-studio.exe (Install)",
"args": [
"-profile",
"${projectDir}/src/nostalgia/studio/nostalgia-studio-dev.json"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "nostalgia-studio.exe",
"name": "nostalgia-studio.exe",
"args": [
"-profile",
"${projectDir}/src/nostalgia/studio/nostalgia-studio-dev.json"
]
}
]
}

View File

@ -83,13 +83,13 @@ static ox::Result<GLShader> buildShader(
ox::Vector<char> errMsg(ox::units::KB);
glGetShaderInfoLog(shader, static_cast<GLsizei>(errMsg.size()), nullptr, errMsg.data());
oxErrorf("shader compile error in {}: {}", shaderName, errMsg.data());
return OxError(1, "shader compile error");
return ox::Error(1, "shader compile error");
}
return shader;
}
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
oxRequireM(program, buildShaderProgram(
OX_REQUIRE_M(program, buildShaderProgram(
src.vertShader,
src.fragShader,
src.geomShader));
@ -127,13 +127,13 @@ ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&frag,
ox::CStringView const&geo) noexcept {
GLProgram prgm(glCreateProgram());
oxRequire(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
OX_REQUIRE(vs, buildShader(GL_VERTEX_SHADER, vert.c_str(), "vshad"));
glAttachShader(prgm, vs);
if (geo.c_str() && geo.bytes() != 0) {
oxRequire(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad"));
OX_REQUIRE(gs, buildShader(GL_GEOMETRY_SHADER, geo.c_str(), "gshad"));
glAttachShader(prgm, gs);
}
oxRequire(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad"));
OX_REQUIRE(fs, buildShader(GL_FRAGMENT_SHADER, frag.c_str(), "fshad"));
glAttachShader(prgm, fs);
glLinkProgram(prgm);
return prgm;

View File

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

View File

@ -201,7 +201,7 @@ nfdresult_t SetDefaultExtension(::IFileDialog* fileOpenDialog,
}
if (*p_spec) {
// multiple file extensions for this type (need to allocate memory)
size_t numChars = p_spec - filterList[0].spec;
size_t numChars = static_cast<size_t>(p_spec - filterList[0].spec);
// allocate one more char space for the '\0'
nfdnchar_t* extnBuf = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * (numChars + 1));
if (!extnBuf) {
@ -710,7 +710,7 @@ nfdresult_t CopyCharToWChar(const nfdu8char_t* inStr, nfdnchar_t*& outStr) {
int charsNeeded = MultiByteToWideChar(CP_UTF8, 0, inStr, -1, nullptr, 0);
assert(charsNeeded);
nfdnchar_t* tmp_outStr = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * charsNeeded);
nfdnchar_t* tmp_outStr = NFDi_Malloc<nfdnchar_t>(sizeof(nfdnchar_t) * static_cast<size_t>(charsNeeded));
if (!tmp_outStr) {
return NFD_ERROR;
}
@ -727,7 +727,7 @@ nfdresult_t CopyWCharToNFDChar(const nfdnchar_t* inStr, nfdu8char_t*& outStr) {
int bytesNeeded = WideCharToMultiByte(CP_UTF8, 0, inStr, -1, nullptr, 0, nullptr, nullptr);
assert(bytesNeeded);
nfdu8char_t* tmp_outStr = NFDi_Malloc<nfdu8char_t>(sizeof(nfdu8char_t) * bytesNeeded);
nfdu8char_t* tmp_outStr = NFDi_Malloc<nfdu8char_t>(sizeof(nfdu8char_t) * static_cast<size_t>(bytesNeeded));
if (!tmp_outStr) {
return NFD_ERROR;
}

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

@ -2,7 +2,7 @@
source:
- src
copyright_notice: |-
Copyright 2015 - 2024 gary@drinkingtea.net
Copyright 2015 - 2025 gary@drinkingtea.net
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

View File

@ -9,9 +9,6 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(NOSTALGIA_BUILD_PLAYER OFF)
set(NOSTALGIA_BUILD_STUDIO_APP OFF)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
@ -28,3 +25,10 @@ endif()
add_library(CityHash INTERFACE)
target_include_directories(CityHash INTERFACE include)
install(
DIRECTORY
include/cityhash
DESTINATION
include
)

View File

@ -104,6 +104,11 @@ using size_t = decltype(alignof(int));
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif
namespace cityhash::detail {
template<typename T>
@ -671,4 +676,8 @@ constexpr uint128 CityHash128(const char *s, size_t len) noexcept {
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif // CITY_HASH_H_

90
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
back up the call stack, ```oxReturnError```, ```oxThrowError```, and
```oxRequire```.
back up the call stack, ```OX_RETURN_ERROR```, ```OX_THROW_ERROR```, and
```OX_REQUIRE```.
```oxReturnError``` is by far the more helpful of the two.
```oxReturnError``` will return an ```ox::Error``` if it is not 0 and
```oxThrowError``` will throw an ```ox::Error``` if it is not 0.
```OX_RETURN_ERROR``` is by far the more helpful of the two.
```OX_RETURN_ERROR``` will return an ```ox::Error``` if it is not 0 and
```OX_THROW_ERROR``` will throw an ```ox::Error``` if it is not 0.
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
@ -113,13 +113,13 @@ This should be used sparingly.
```cpp
void studioCode() {
auto [val, err] = foo(1);
oxThrowError(err);
OX_THROW_ERROR(err);
doStuff(val);
}
ox::Error engineCode() noexcept {
auto [val, err] = foo(1);
oxReturnError(err);
OX_RETURN_ERROR(err);
doStuff(val);
return {};
}
@ -136,19 +136,19 @@ Both macros will also take the ```ox::Result``` directly:
```cpp
void studioCode() {
auto valerr = foo(1);
oxThrowError(valerr);
OX_THROW_ERROR(valerr);
doStuff(valerr.value);
}
ox::Error engineCode() noexcept {
auto valerr = foo(1);
oxReturnError(valerr);
OX_RETURN_ERROR(valerr);
doStuff(valerr.value);
return {};
}
```
Ox also has the ```oxRequire``` macro, which will initialize a value if there is no error, and return if there is.
Ox also has the ```OX_REQUIRE``` 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.
Rust ```?``` operator:
@ -163,27 +163,23 @@ fn f2() -> Result<i32, i32> {
}
```
```oxRequire```:
```OX_REQUIRE```:
```cpp
ox::Result<int> f() noexcept {
// do stuff
}
ox::Result<int> f2() noexcept {
oxRequire(i, f()); // const auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__))
OX_REQUIRE(i, f()); // const auto [out, OX_CONCAT(oxRequire_err_, __LINE__)] = x; OX_RETURN_ERROR(OX_CONCAT(oxRequire_err_, __LINE__))
return i + 4;
}
```
```oxRequire``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code.
```OX_REQUIRE``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code.
```oxRequire``` also has variants for throwing the error and for making to value non-const:
```OX_REQUIRE``` by default creates a const, but there is also an ```OX_REQUIRE_M``` (OX_REQUIRE Mutable)
variant for creating a non-const value.
* ```oxRequireM``` - oxRequire Mutable
* ```oxRequireT``` - oxRequire Throw
* ```oxRequireMT``` - oxRequire Mutable Throw
The throw variants of ```oxRequire``` are generally legacy code.
```ox::Result::unwrapThrow``` is generally preferred now.
* ```OX_REQUIRE_M``` - OX_REQUIRE Mutable
### Logging and Output
@ -207,7 +203,7 @@ never be checked in.
```oxError``` always prints.
It includes file and line, and is prefixed with a red "ERROR:".
It should generally be used conservatively.
It shuld be used only when there is an error that is not technically fatal, but
It should be used only when there is an error that is not technically fatal, but
the user almost certainly wants to know about it.
```oxTrace``` and ```oxTracef```:
@ -272,19 +268,19 @@ constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaPalette> auto *pal) n
h->template setTypeInfo<NostalgiaPalette>();
// it is also possible to provide the type name and type version as function arguments
//h->setTypeInfo("net.drinkingtea.nostalgia.core.NostalgiaPalette", 1);
oxReturnError(h->field("colors", &pal->colors));
OX_RETURN_ERROR(h->field("colors", &pal->colors));
return {};
}
template<typename T>
constexpr ox::Error model(T *h, ox::CommonPtrWith<NostalgiaGraphic> auto *ng) noexcept {
h->template setTypeInfo<NostalgiaGraphic>();
oxReturnError(h->field("bpp", &ng->bpp));
oxReturnError(h->field("rows", &ng->rows));
oxReturnError(h->field("columns", &ng->columns));
oxReturnError(h->field("defaultPalette", &ng->defaultPalette));
oxReturnError(h->field("pal", &ng->pal));
oxReturnError(h->field("pixels", &ng->pixels));
OX_RETURN_ERROR(h->field("bpp", &ng->bpp));
OX_RETURN_ERROR(h->field("rows", &ng->rows));
OX_RETURN_ERROR(h->field("columns", &ng->columns));
OX_RETURN_ERROR(h->field("defaultPalette", &ng->defaultPalette));
OX_RETURN_ERROR(h->field("pal", &ng->pal));
OX_RETURN_ERROR(h->field("pixels", &ng->pixels));
return {};
}
```
@ -319,9 +315,9 @@ class FileAddress {
template<typename T>
constexpr Error model(T *h, ox::CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
h->template setTypeInfo<FileAddress::Data>();
oxReturnError(h->fieldCString("path", &obj->path));
oxReturnError(h->fieldCString("constPath", &obj->path));
oxReturnError(h->field("inode", &obj->inode));
OX_RETURN_ERROR(h->fieldCString("path", &obj->path));
OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path));
OX_RETURN_ERROR(h->field("inode", &obj->inode));
return {};
}
@ -331,13 +327,13 @@ constexpr Error model(T *io, ox::CommonPtrWith<FileAddress> auto *fa) noexcept {
// cannot read from object in Reflect operation
if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
int8_t type = 0;
oxReturnError(io->field("type", &type));
oxReturnError(io->field("data", UnionView(&fa->m_data, 0)));
OX_RETURN_ERROR(io->field("type", &type));
OX_RETURN_ERROR(io->field("data", UnionView(&fa->m_data, 0)));
} else {
auto type = static_cast<int8_t>(fa->m_type);
oxReturnError(io->field("type", &type));
OX_RETURN_ERROR(io->field("type", &type));
fa->m_type = static_cast<FileAddressType>(type);
oxReturnError(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
OX_RETURN_ERROR(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
}
return {};
}
@ -347,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:
```cpp
oxModelBegin(NostalgiaGraphic)
oxModelField(bpp)
oxModelField(rows)
oxModelField(columns)
oxModelField(defaultPalette)
oxModelField(pal)
oxModelField(pixels)
OX_MODEL_BEGIN(NostalgiaGraphic)
OX_MODEL_FIELD(bpp)
OX_MODEL_FIELD(rows)
OX_MODEL_FIELD(columns)
OX_MODEL_FIELD(defaultPalette)
OX_MODEL_FIELD(pal)
OX_MODEL_FIELD(pixels)
oxModelEnd()
```
@ -396,7 +392,7 @@ ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
NostalgiaPalette pal;
oxReturnError(ox::readMC(buff, pal));
OX_RETURN_ERROR(ox::readMC(buff, pal));
return pal;
}
```
@ -409,7 +405,7 @@ ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept {
ox::Buffer buffer(ox::units::MB);
std::size_t sz = 0;
oxReturnError(ox::writeMC(buffer.data(), buffer.size(), pal, &sz));
OX_RETURN_ERROR(ox::writeMC(buffer.data(), buffer.size(), pal, &sz));
buffer.resize(sz);
return buffer;
}
@ -432,7 +428,7 @@ ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
NostalgiaPalette pal;
oxReturnError(ox::readOC(buff, &pal));
OX_RETURN_ERROR(ox::readOC(buff, &pal));
return pal;
}
```
@ -444,7 +440,7 @@ ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
ox::Result<ox::Buffer> writeSpritePalette1(NostalgiaPalette const&pal) noexcept {
ox::Buffer buffer(ox::units::MB);
oxReturnError(ox::writeOC(buffer.data(), buffer.size(), pal));
OX_RETURN_ERROR(ox::writeOC(buffer.data(), buffer.size(), pal));
return buffer;
}
@ -466,7 +462,7 @@ ox::Result<NostalgiaPalette> loadPalette1(ox::BufferView const&buff) noexcept {
ox::Result<NostalgiaPalette> loadPalette2(ox::BufferView const&buff) noexcept {
NostalgiaPalette pal;
oxReturnError(ox::readClaw(buff, pal));
OX_RETURN_ERROR(ox::readClaw(buff, pal));
return pal;
}
```

View File

@ -1,4 +1,9 @@
cmake_minimum_required(VERSION 3.10)
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# enable warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
endif()
add_library(
OxClArgs

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -11,16 +11,18 @@
namespace ox {
ClArgs::ClArgs(int argc, const char **args) noexcept {
for (auto i = 0u; i < static_cast<unsigned>(argc); ++i) {
auto arg = String(args[i]);
ClArgs::ClArgs(int argc, const char **args) noexcept: ClArgs({args, static_cast<size_t>(argc)}) {}
ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
for (auto i = 0u; i < args.size(); ++i) {
auto arg = StringView(args[i]);
if (arg[0] == '-') {
while (arg[0] == '-' && arg.len()) {
arg = arg.substr(1);
arg = substr(arg, 1);
}
m_bools[arg] = true;
// parse additional arguments
if (i < static_cast<unsigned>(argc) && args[i + 1]) {
if (i < args.size() && args[i + 1]) {
auto val = String(args[i + 1]);
if (val.len() && val[i] != '-') {
if (val == "false") {
@ -53,17 +55,17 @@ int ClArgs::getInt(ox::StringViewCR arg, int defaultValue) const noexcept {
}
Result<bool> ClArgs::getBool(ox::StringViewCR arg) const noexcept {
oxRequire(out, m_bools.at(arg));
OX_REQUIRE(out, m_bools.at(arg));
return *out;
}
Result<String> ClArgs::getString(ox::StringViewCR argName) const noexcept {
oxRequire(out, m_strings.at(argName));
OX_REQUIRE(out, m_strings.at(argName));
return *out;
}
Result<int> ClArgs::getInt(ox::StringViewCR arg) const noexcept {
oxRequire(out, m_ints.at(arg));
OX_REQUIRE(out, m_ints.at(arg));
return *out;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -9,6 +9,7 @@
#pragma once
#include <ox/std/hashmap.hpp>
#include <ox/std/span.hpp>
#include <ox/std/string.hpp>
namespace ox {
@ -22,6 +23,8 @@ class ClArgs {
public:
ClArgs(int argc, const char **args) noexcept;
ClArgs(ox::SpanView<const char*> args) noexcept;
[[nodiscard]]
bool getBool(ox::StringViewCR arg, bool defaultValue) const noexcept;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -18,7 +18,7 @@ ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
size_t outSz{};
const auto s1End = ox::strchr(buffRaw, ';', buffLen);
if (!s1End) {
return OxError(1, "Could not read Claw header");
return ox::Error(1, "Could not read Claw header");
}
auto const fmtSz = static_cast<std::size_t>(s1End - buffRaw) + 1;
buffRaw += fmtSz;
@ -26,7 +26,7 @@ ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
outSz += fmtSz;
auto const s2End = ox::strchr(buffRaw, ';', buffLen);
if (!s2End) {
return OxError(2, "Could not read Claw header");
return ox::Error(2, "Could not read Claw header");
}
auto const s2Size = static_cast<std::size_t>(s2End - buffRaw) + 1;
buffRaw += s2Size;
@ -34,7 +34,7 @@ ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
outSz += s2Size;
auto const s3End = ox::strchr(buffRaw, ';', buffLen) + 1;
if (!s3End) {
return OxError(3, "Could not read Claw header");
return ox::Error(3, "Could not read Claw header");
}
auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
buffRaw += s3Size;
@ -48,7 +48,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
auto buffLen = buff.size();
const auto s1End = ox::strchr(buffRaw, ';', buffLen);
if (!s1End) {
return OxError(1, "Could not read Claw header");
return ox::Error(1, "Could not read Claw header");
}
auto const s1Size = static_cast<std::size_t>(s1End - buffRaw);
StringView const fmt(buffRaw, s1Size);
@ -57,7 +57,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
auto const s2End = ox::strchr(buffRaw, ';', buffLen);
if (!s2End) {
return OxError(2, "Could not read Claw header");
return ox::Error(2, "Could not read Claw header");
}
auto const s2Size = static_cast<std::size_t>(s2End - buffRaw);
StringView const typeName(buffRaw, s2Size);
@ -66,7 +66,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
auto const s3End = ox::strchr(buffRaw, ';', buffLen);
if (!s3End) {
return OxError(3, "Could not read Claw header");
return ox::Error(3, "Could not read Claw header");
}
auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
StringView const versionStr(buffRaw, s3Size);
@ -78,7 +78,7 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
} else if (fmt == "O1") {
hdr.fmt = ClawFormat::Organic;
} else {
return OxError(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;
std::ignore = ox::atoi(versionStr).copyTo(hdr.typeVersion);
@ -88,26 +88,26 @@ Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
}
Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept {
oxRequire(header, readClawHeader(buff));
OX_REQUIRE(header, readClawHeader(buff));
return {{header.data, header.dataSize}};
}
Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
oxRequire(header, readClawHeader(buff));
OX_REQUIRE(header, readClawHeader(buff));
auto const [t, tdErr] = ts.getLoad(
header.typeName, header.typeVersion, header.typeParams);
if (tdErr) {
return OxError(3, "Could not load type descriptor");
return ox::Error(3, "Could not load type descriptor");
}
ModelObject obj;
oxReturnError(obj.setType(t));
OX_RETURN_ERROR(obj.setType(t));
switch (header.fmt) {
case ClawFormat::Metal:
{
ox::BufferReader br({header.data, header.dataSize});
MetalClawReader reader(br);
ModelHandlerInterface handler(&reader);
oxReturnError(model(&handler, &obj));
OX_RETURN_ERROR(model(&handler, &obj));
return obj;
}
case ClawFormat::Organic:
@ -115,16 +115,16 @@ Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
#ifdef OX_USE_STDLIB
OrganicClawReader reader({header.data, header.dataSize});
ModelHandlerInterface handler(&reader);
oxReturnError(model(&handler, &obj));
OX_RETURN_ERROR(model(&handler, &obj));
return obj;
#else
break;
#endif
}
case ClawFormat::None:
return OxError(1);
return ox::Error(1);
}
return OxError(1);
return ox::Error(1);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -40,12 +40,12 @@ Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept;
template<typename T>
Error readClaw(ox::BufferView buff, T &val) {
oxRequire(header, readClawHeader(buff));
OX_REQUIRE(header, readClawHeader(buff));
if (header.typeName != getModelTypeName<T>()) {
return OxError(Error_ClawTypeMismatch, "Claw Read: Type mismatch");
return ox::Error(Error_ClawTypeMismatch, "Claw Read: Type mismatch");
}
if (header.typeVersion != getModelTypeVersion<T>()) {
return OxError(Error_ClawTypeVersionMismatch, "Claw Read: Type Version mismatch");
return ox::Error(Error_ClawTypeVersionMismatch, "Claw Read: Type Version mismatch");
}
switch (header.fmt) {
case ClawFormat::Metal:
@ -65,15 +65,15 @@ Error readClaw(ox::BufferView buff, T &val) {
#endif
}
case ClawFormat::None:
return OxError(1);
return ox::Error(1);
}
return OxError(1);
return ox::Error(1);
}
template<typename T>
Result<T> readClaw(ox::BufferView buff) {
Result<T> val;
oxReturnError(readClaw(buff, val.value));
OX_RETURN_ERROR(readClaw(buff, val.value));
return val;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -62,45 +62,45 @@ struct TestStruct {
template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) {
oxReturnError(io->template setTypeInfo<TestUnion>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->fieldCString("String", &obj->String));
return OxError(0);
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->fieldCString("String", &obj->String));
return ox::Error(0);
}
template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStructNest> auto *obj) {
oxReturnError(io->template setTypeInfo<TestStructNest>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->field("String", &obj->String));
return OxError(0);
OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("String", &obj->String));
return ox::Error(0);
}
template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) {
oxReturnError(io->template setTypeInfo<TestStruct>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->field("Int1", &obj->Int1));
oxReturnError(io->field("Int2", &obj->Int2));
oxReturnError(io->field("Int3", &obj->Int3));
oxReturnError(io->field("Int4", &obj->Int4));
oxReturnError(io->field("Int5", &obj->Int5));
oxReturnError(io->field("Int6", &obj->Int6));
oxReturnError(io->field("Int7", &obj->Int7));
oxReturnError(io->field("Int8", &obj->Int8));
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
int unionIdx = 0;
if constexpr(T::opType() != ox::OpType::Reflect) {
unionIdx = obj->unionIdx;
}
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
oxReturnError(io->field("String", &obj->String));
oxReturnError(io->field("List", obj->List, 4));
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
oxReturnError(io->field("Struct", &obj->Struct));
return OxError(0);
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, unionIdx}));
OX_RETURN_ERROR(io->field("String", &obj->String));
OX_RETURN_ERROR(io->field("List", obj->List, 4));
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
return ox::Error(0);
}
static std::map<ox::StringView, ox::Error(*)()> tests = {
@ -114,7 +114,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(ch.fmt == ox::ClawFormat::Organic, "Format wrong");
oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header", "Type name wrong");
oxAssert(ch.typeVersion == 2, "Type version wrong");
return OxError(0);
return ox::Error(0);
}
},
{
@ -126,7 +126,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(ch.fmt == ox::ClawFormat::Metal, "Format wrong");
oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header2", "Type name wrong");
oxAssert(ch.typeVersion == 3, "Type version wrong");
return OxError(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 expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3");
oxRequire(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1}));
OX_REQUIRE(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1}));
oxExpect(actual, expected);
return ox::Error{};
}
@ -145,8 +145,8 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
// This test doesn't confirm much, but it does show that the writer
// doesn't segfault
TestStruct ts;
oxReturnError(ox::writeClaw(ts, ox::ClawFormat::Metal));
return OxError(0);
OX_RETURN_ERROR(ox::writeClaw(ts, ox::ClawFormat::Metal));
return ox::Error(0);
}
},
{
@ -191,7 +191,7 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Struct.String == testOut.Struct.String, "Struct.String value mismatch");
oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch");
return OxError(0);
return ox::Error(0);
}
},
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -57,7 +57,7 @@ class Signal {
void call(Args... args) final {
if constexpr(detail::isError<decltype(f(args...))>::value) {
oxThrowError(f(args...));
OX_THROW_ERROR(f(args...));
} else {
f(args...);
}
@ -76,7 +76,7 @@ class Signal {
void call(Args... args) final {
if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
oxThrowError((m_receiver->*(m_methodPtr))(args...));
OX_THROW_ERROR((m_receiver->*(m_methodPtr))(args...));
} else {
f(args...);
}
@ -107,7 +107,7 @@ class Signal {
void call(Args... args) final {
if constexpr(detail::isError<decltype((m_receiver->*(m_methodPtr))(args...))>::value) {
oxThrowError((m_receiver->*(m_methodPtr))(args...));
OX_THROW_ERROR((m_receiver->*(m_methodPtr))(args...));
} else {
(m_receiver->*(m_methodPtr))(args...);
}
@ -193,11 +193,11 @@ Error Signal<Args...>::disconnectObject(const void *receiver) const noexcept {
for (auto i = 0u; i < m_slots.size(); ++i) {
const auto &slot = m_slots[i];
if (slot->receiver() == receiver) {
oxReturnError(m_slots.erase(i));
OX_RETURN_ERROR(m_slots.erase(i));
--i;
}
}
return OxError(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
return ox::Error(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
}
template<class... Args>
@ -213,7 +213,7 @@ Error Signal<Args...>::emitCheckError(Args... args) const noexcept {
for (auto &f : m_slots) {
f->call(args...);
}
return OxError(0);
return ox::Error(0);
} catch (const ox::Exception &ex) {
return ox::Error(ex.file, ex.line, ex.errCode, ex.msg);
}
@ -381,11 +381,11 @@ Error Signal<Error(Args...)>::disconnectObject(const void *receiver) const noexc
for (auto i = 0u; i < m_slots.size(); ++i) {
const auto &slot = m_slots[i];
if (slot->receiver() == receiver) {
oxReturnError(m_slots.erase(i));
OX_RETURN_ERROR(m_slots.erase(i));
--i;
}
}
return OxError(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
return ox::Error(1, "Signal::disconnectObject: Receiver was not found among this Signal's slots");
}
template<class... Args>
@ -398,9 +398,9 @@ void Signal<Error(Args...)>::emit(Args... args) const noexcept {
template<class... Args>
Error Signal<Error(Args...)>::emitCheckError(Args... args) const noexcept {
for (auto &f : m_slots) {
oxReturnError(f->call(ox::forward<Args>(args)...));
OX_RETURN_ERROR(f->call(ox::forward<Args>(args)...));
}
return OxError(0);
return ox::Error(0);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -17,7 +17,7 @@ struct TestStruct: public ox::SignalHandler {
int value = 0;
ox::Error method(int i) noexcept {
value = i;
return OxError(0);
return ox::Error(0);
}
};
@ -27,13 +27,13 @@ std::map<ox::StringView, std::function<ox::Error()>> tests = {
[] {
ox::Signal<ox::Error(int)> signal;
signal.connect([](int i) -> ox::Error {
return OxError(i != 5);
return ox::Error(i != 5);
});
TestStruct ts;
signal.connect(&ts, &TestStruct::method);
oxReturnError(signal.emitCheckError(5));
oxReturnError(OxError(ts.value != 5));
return OxError(0);
OX_RETURN_ERROR(signal.emitCheckError(5));
OX_RETURN_ERROR(ox::Error(ts.value != 5));
return ox::Error(0);
}
},
};

View File

@ -1,3 +1,7 @@
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# enable warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
endif()
add_library(
OxFS

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -10,6 +10,8 @@
#include <ox/fs/ptrarith/nodebuffer.hpp>
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
using InodeId_t = uint64_t;
@ -205,12 +207,12 @@ Error FileStoreTemplate<size_t>::format(void *buffer, std::size_t bufferSize) {
auto fsData = nb->malloc(sizeof(FileStoreData)).value;
if (!fsData.valid()) {
oxTrace("ox.fs.FileStoreTemplate.format.fail", "Could not read data section of FileStoreData");
return OxError(1, "Could not read data section of FileStoreData");
return ox::Error(1, "Could not read data section of FileStoreData");
}
auto data = nb->template dataOf<FileStoreData>(fsData);
if (!data.valid()) {
oxTrace("ox.fs.FileStoreTemplate.format.fail", "Could not read data section of FileStoreData");
return OxError(1, "Could not read data section of FileStoreData");
return ox::Error(1, "Could not read data section of FileStoreData");
}
new (data) FileStoreData;
return {};
@ -221,24 +223,24 @@ Error FileStoreTemplate<size_t>::setSize(std::size_t size) {
if (m_buffSize >= size) {
return m_buffer->setSize(static_cast<size_t>(size));
}
return OxError(1);
return ox::Error(1);
}
template<typename size_t>
Error FileStoreTemplate<size_t>::incLinks(uint64_t id) {
oxRequireM(item, find(static_cast<size_t>(id)).validate());
OX_REQUIRE_M(item, find(static_cast<size_t>(id)).validate());
++item->links;
return OxError(0);
return ox::Error(0);
}
template<typename size_t>
Error FileStoreTemplate<size_t>::decLinks(uint64_t id) {
oxRequireM(item, find(static_cast<size_t>(id)).validate());
OX_REQUIRE_M(item, find(static_cast<size_t>(id)).validate());
--item->links;
if (item->links == 0) {
oxReturnError(remove(item));
OX_RETURN_ERROR(remove(item));
}
return OxError(0);
return ox::Error(0);
}
template<typename size_t>
@ -247,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);
auto existing = find(id);
if (!canWrite(existing, dataSize)) {
oxReturnError(compact());
OX_RETURN_ERROR(compact());
existing = find(id);
}
@ -267,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 (!dest.valid()) {
oxTrace("ox.fs.FileStoreTemplate.write", "Allocation failed, compacting");
oxReturnError(compact());
OX_RETURN_ERROR(compact());
dest = m_buffer->malloc(dataSize).value;
}
if (dest.valid()) {
@ -296,16 +298,16 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
dest->id.get(), dest.offset(), destData.size());
fsData->rootNode = dest.offset();
oxTracef("ox.fs.FileStoreTemplate.write", "Root inode: {}", dest->id.get());
return OxError(0);
return ox::Error(0);
}
} else {
oxTrace("ox.fs.FileStoreTemplate.write.fail", "Could not place item due to absence of FileStore header.");
}
}
}
oxReturnError(m_buffer->free(dest));
OX_RETURN_ERROR(m_buffer->free(dest));
}
return OxError(1);
return ox::Error(1);
}
template<typename size_t>
@ -320,7 +322,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, void *out, FsSize_t outSize,
// error check
if (!src.valid()) {
oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
return OxError(1, "Could not find requested item");
return ox::Error(1, "Could not find requested item");
}
auto srcData = m_buffer->template dataOf<uint8_t>(src);
@ -333,7 +335,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, void *out, FsSize_t outSize,
oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
oxTracef("ox.fs.FileStoreTemplate.read.fail",
"Item data section size: {}, Expected size: {}", srcData.size(), outSize);
return OxError(1, "Invalid inode");
return ox::Error(1, "Invalid inode");
}
ox::memcpy(out, srcData, srcData.size());
@ -351,7 +353,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart, FsSize_t
// error check
if (!src.valid()) {
oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
return OxError(1);
return ox::Error(1);
}
auto srcData = m_buffer->template dataOf<uint8_t>(src);
@ -364,7 +366,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart, FsSize_t
oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
oxTracef("ox.fs.FileStoreTemplate.read.fail",
"Item data section size: {}, Expected size: {}", srcData.size(), readSize);
return OxError(1);
return ox::Error(1);
}
ox::memcpy(out, srcData.get() + readStart, readSize);
@ -384,7 +386,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart,
// error check
if (!src.valid()) {
oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not find requested item: {}", id);
return OxError(1);
return ox::Error(1);
}
auto srcData = m_buffer->template dataOf<uint8_t>(src);
@ -397,7 +399,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart,
oxTracef("ox.fs.FileStoreTemplate.read.fail", "Could not read data section of item: {}", id);
oxTracef("ox.fs.FileStoreTemplate.read.fail",
"Item data section size: {}, Expected size: {}", srcData.size(), readSize);
return OxError(1);
return ox::Error(1);
}
ox::memcpy(out, srcData.get() + readStart, readSize);
@ -420,30 +422,30 @@ ptrarith::Ptr<uint8_t, std::size_t> FileStoreTemplate<size_t>::read(uint64_t id)
template<typename size_t>
Error FileStoreTemplate<size_t>::resize() {
oxReturnError(compact());
OX_RETURN_ERROR(compact());
const auto newSize = static_cast<std::size_t>(size() - available());
oxTracef("ox.fs.FileStoreTemplate.resize", "resize to: {}", newSize);
oxReturnError(m_buffer->setSize(newSize));
OX_RETURN_ERROR(m_buffer->setSize(newSize));
oxTracef("ox.fs.FileStoreTemplate.resize", "resized to: {}", m_buffer->size());
return OxError(0);
return ox::Error(0);
}
template<typename size_t>
Error FileStoreTemplate<size_t>::resize(std::size_t size, void *newBuff) {
if (m_buffer->size() > size) {
return OxError(1);
return ox::Error(1);
}
m_buffSize = static_cast<size_t>(size);
if (newBuff) {
m_buffer = reinterpret_cast<Buffer*>(newBuff);
oxReturnError(m_buffer->setSize(static_cast<size_t>(size)));
OX_RETURN_ERROR(m_buffer->setSize(static_cast<size_t>(size)));
}
return OxError(0);
return ox::Error(0);
}
template<typename size_t>
Result<StatInfo> FileStoreTemplate<size_t>::stat(uint64_t id) const {
oxRequire(inode, find(static_cast<size_t>(id)).validate());
OX_REQUIRE(inode, find(static_cast<size_t>(id)).validate());
return StatInfo {
id,
inode->links,
@ -475,16 +477,16 @@ char *FileStoreTemplate<size_t>::buff() {
template<typename size_t>
Error FileStoreTemplate<size_t>::walk(Error(*cb)(uint8_t, uint64_t, uint64_t)) {
for (auto i = m_buffer->iterator(); i.valid(); i.next()) {
oxReturnError(cb(i->fileType, i.ptr().offset(), i.ptr().end()));
OX_RETURN_ERROR(cb(i->fileType, i.ptr().offset(), i.ptr().end()));
}
return OxError(0);
return ox::Error(0);
}
template<typename size_t>
Result<typename FileStoreTemplate<size_t>::InodeId_t> FileStoreTemplate<size_t>::generateInodeId() {
auto fsData = fileStoreData();
if (!fsData) {
return OxError(1);
return ox::Error(1);
}
for (auto i = 0; i < 100; i++) {
auto inode = static_cast<typename FileStoreTemplate<size_t>::InodeId_t>(fsData->random.gen() % MaxValue<InodeId_t>);
@ -492,7 +494,7 @@ Result<typename FileStoreTemplate<size_t>::InodeId_t> FileStoreTemplate<size_t>:
return inode;
}
}
return OxError(2);
return ox::Error(2);
}
template<typename size_t>
@ -501,10 +503,10 @@ Error FileStoreTemplate<size_t>::compact() {
return m_buffer->compact([this, &isFirstItem](uint64_t oldAddr, ItemPtr item) -> Error {
if (isFirstItem) {
isFirstItem = false;
return OxError(0);
return ox::Error(0);
}
if (!item.valid()) {
return OxError(1);
return ox::Error(1);
}
oxTracef("ox.fs.FileStoreTemplate.compact.moveItem", "Moving Item: {} from {} to {}", item->id.get(), oldAddr, item.offset());
// update rootInode if this is it
@ -522,7 +524,7 @@ Error FileStoreTemplate<size_t>::compact() {
parent->right = item;
}
}
return OxError(0);
return ox::Error(0);
});
}
@ -542,15 +544,15 @@ template<typename size_t>
Error FileStoreTemplate<size_t>::placeItem(ItemPtr item) {
auto fsData = fileStoreData();
if (!fsData) {
return OxError(1);
return ox::Error(1);
}
oxRequireM(root, m_buffer->ptr(fsData->rootNode).validate());
OX_REQUIRE_M(root, m_buffer->ptr(fsData->rootNode).validate());
if (root->id == item->id) {
fsData->rootNode = item;
item->left = root->left;
item->right = root->right;
oxTracef("ox.fs.FileStoreTemplate.placeItem", "Overwrote Root Item: {}", item->id.get());
return OxError(0);
return ox::Error(0);
} else {
return placeItem(root, item);
}
@ -560,7 +562,7 @@ template<typename size_t>
Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth) {
if (depth > 5000) {
oxTrace("ox.fs.FileStoreTemplate.placeItem.fail", "Excessive recursion depth, stopping before stack overflow.");
return OxError(2);
return ox::Error(2);
}
if (item->id > root->id) {
auto right = m_buffer->ptr(root->right);
@ -571,7 +573,7 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
item->right = right->right;
}
oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
return OxError(0);
return ox::Error(0);
} else {
return placeItem(right, item, depth + 1);
}
@ -584,13 +586,13 @@ Error FileStoreTemplate<size_t>::placeItem(ItemPtr root, ItemPtr item, int depth
item->right = left->right;
}
oxTracef("ox.fs.FileStoreTemplate.placeItem", "Placed Item: {}", item->id.get());
return OxError(0);
return ox::Error(0);
} else {
return placeItem(left, item, depth + 1);
}
} else {
oxTrace("ox.fs.FileStoreTemplate.placeItem.fail", "Cannot insert an item on itself.");
return OxError(1, "Cannot insert an item on itself.");
return ox::Error(1, "Cannot insert an item on itself.");
}
}
@ -598,9 +600,9 @@ template<typename size_t>
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
auto fsData = fileStoreData();
if (!fsData) {
return OxError(1);
return ox::Error(1);
}
oxRequireM(root, m_buffer->ptr(fsData->rootNode).validate());
OX_REQUIRE_M(root, m_buffer->ptr(fsData->rootNode).validate());
if (root->id == item->id) {
item->left = root->left;
item->right = root->right;
@ -622,7 +624,7 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr item) {
} else {
fsData->rootNode = 0;
}
return OxError(0);
return ox::Error(0);
} else {
return unplaceItem(root, item);
}
@ -632,7 +634,7 @@ template<typename size_t>
Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int depth) {
if (depth >= 5000) {
oxTrace("ox.fs.FileStoreTemplate.unplaceItem.fail", "Excessive recursion depth, stopping before stack overflow.");
return OxError(1, "Excessive recursion depth, stopping before stack overflow.");
return ox::Error(1, "Excessive recursion depth, stopping before stack overflow.");
}
if (item->id > root->id) {
auto right = m_buffer->ptr(root->right);
@ -651,25 +653,25 @@ Error FileStoreTemplate<size_t>::unplaceItem(ItemPtr root, ItemPtr item, int dep
return unplaceItem(left, item, depth + 1);
}
} else {
return OxError(1);
return ox::Error(1);
}
if (item->right) {
oxReturnError(placeItem(m_buffer->ptr(item->right)));
OX_RETURN_ERROR(placeItem(m_buffer->ptr(item->right)));
}
if (item->left) {
oxReturnError(placeItem(m_buffer->ptr(item->left)));
OX_RETURN_ERROR(placeItem(m_buffer->ptr(item->left)));
}
return OxError(0);
return ox::Error(0);
}
template<typename size_t>
Error FileStoreTemplate<size_t>::remove(ItemPtr item) {
if (item.valid()) {
oxReturnError(unplaceItem(item));
oxReturnError(m_buffer->free(item));
return OxError(0);
OX_RETURN_ERROR(unplaceItem(item));
OX_RETURN_ERROR(m_buffer->free(item));
return ox::Error(0);
}
return OxError(1);
return ox::Error(1);
}
template<typename size_t>
@ -771,3 +773,5 @@ using FileStore16 = FileStoreTemplate<uint16_t>;
using FileStore32 = FileStoreTemplate<uint32_t>;
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -15,6 +15,8 @@
#include "types.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename InodeId_t>
@ -53,7 +55,7 @@ struct OX_PACKED DirectoryEntry {
ox::strncpy(d->name, name.data(), ox::min(maxStrSz, name.len()));
return {};
}
return OxError(1);
return ox::Error(1);
}
ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() noexcept {
@ -139,11 +141,11 @@ template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::init() noexcept {
constexpr auto Size = sizeof(Buffer);
oxTracef("ox.fs.Directory.init", "Initializing Directory with Inode ID: {}", m_inodeId);
oxReturnError(m_fs.write(m_inodeId, nullptr, Size, static_cast<uint8_t>(FileType::Directory)));
OX_RETURN_ERROR(m_fs.write(m_inodeId, nullptr, Size, static_cast<uint8_t>(FileType::Directory)));
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (!buff.valid()) {
m_size = 0;
return OxError(1);
return ox::Error(1);
}
new (buff) Buffer(Size);
m_size = Size;
@ -156,21 +158,21 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
oxTrace("ox.fs.Directory.mkdir", path.fullPath());
// determine if already exists
ox::StringView name;
oxReturnError(path.get(name));
OX_RETURN_ERROR(path.get(name));
auto childInode = find(PathIterator(name));
if (!childInode.ok()) {
// if this is not the last item in the path and parents is disabled,
// return an error
if (!parents && path.hasNext()) {
return OxError(1);
return ox::Error(1);
}
childInode = m_fs.generateInodeId();
oxTracef("ox.fs.Directory.mkdir", "Generated Inode ID: {}", childInode.value);
oxLogError(childInode.error);
oxReturnError(childInode.error);
OX_RETURN_ERROR(childInode.error);
// initialize the directory
Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
oxReturnError(child.init());
OX_RETURN_ERROR(child.init());
auto err = write(PathIterator(name), childInode.value);
if (err) {
oxLogError(err);
@ -181,7 +183,7 @@ Error Directory<FileStore, InodeId_t>::mkdir(PathIterator path, bool parents) {
}
Directory<FileStore, InodeId_t> child(m_fs, childInode.value);
if (path.hasNext()) {
oxReturnError(child.mkdir(path.next(), parents));
OX_RETURN_ERROR(child.mkdir(path.next(), parents));
}
}
return {};
@ -194,28 +196,28 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
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 {}",
name, path.fullPath());
oxReturnError(path.get(name));
oxRequire(nextChild, findEntry(name));
OX_RETURN_ERROR(path.get(name));
OX_REQUIRE(nextChild, findEntry(name));
oxTracef("ox.fs.Directory.write", "{}: {}", name, nextChild);
if (nextChild) {
return Directory(m_fs, nextChild).write(path.next(), inode);
} else {
oxTracef("ox.fs.Directory.write", "{} not found and not allowed to create it.", name);
return OxError(1, "File not found and not allowed to create it.");
return ox::Error(1, "File not found and not allowed to create it.");
}
} else {
oxTrace("ox.fs.Directory.write", path.fullPath());
oxReturnError(path.next(name));
OX_RETURN_ERROR(path.next(name));
// insert the new entry on this directory
// get the name
// find existing version of directory
oxTracef("ox.fs.Directory.write", "Searching for directory inode {}", m_inodeId);
oxRequire(oldStat, m_fs.stat(m_inodeId));
OX_REQUIRE(oldStat, m_fs.stat(m_inodeId));
oxTracef("ox.fs.Directory.write", "Found existing directory of size {}", oldStat.size);
auto old = m_fs.read(m_inodeId).template to<Buffer>();
if (!old.valid()) {
oxTrace("ox.fs.Directory.write.fail", "Could not read existing version of Directory");
return OxError(1, "Could not read existing version of Directory");
return ox::Error(1, "Could not read existing version of Directory");
}
const auto pathSize = name.len() + 1;
const auto entryDataSize = DirectoryEntry<InodeId_t>::DirectoryEntryData::spaceNeeded(pathSize);
@ -223,16 +225,16 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
auto cpy = ox_malloca(newSize, Buffer, *old, oldStat.size);
if (cpy == nullptr) {
oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for copy of Directory");
return OxError(1, "Could not allocate memory for copy of Directory");
return ox::Error(1, "Could not allocate memory for copy of Directory");
}
oxReturnError(cpy->setSize(newSize));
OX_RETURN_ERROR(cpy->setSize(newSize));
auto val = cpy->malloc(entryDataSize).value;
if (!val.valid()) {
oxTrace("ox.fs.Directory.write.fail", "Could not allocate memory for new directory entry");
return OxError(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);
oxReturnError(val->init(inode, name, val.size()));
OX_RETURN_ERROR(val->init(inode, name, val.size()));
return m_fs.write(m_inodeId, cpy.get(), cpy->size(), static_cast<uint8_t>(FileType::Directory));
}
}
@ -240,7 +242,7 @@ Error Directory<FileStore, InodeId_t>::write(PathIterator path, uint64_t inode64
template<typename FileStore, typename InodeId_t>
Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
ox::StringView name;
oxReturnError(path.get(name));
OX_RETURN_ERROR(path.get(name));
oxTrace("ox.fs.Directory.remove", name);
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (buff.valid()) {
@ -249,7 +251,7 @@ Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
auto data = i->data();
if (data.valid()) {
if (name == data->name) {
oxReturnError(buff->free(i));
OX_RETURN_ERROR(buff->free(i));
}
} else {
oxTrace("ox.fs.Directory.remove", "INVALID DIRECTORY ENTRY");
@ -257,7 +259,7 @@ Error Directory<FileStore, InodeId_t>::remove(PathIterator path) noexcept {
}
} else {
oxTrace("ox.fs.Directory.remove.fail", "Could not find directory buffer");
return OxError(1, "Could not find directory buffer");
return ox::Error(1, "Could not find directory buffer");
}
return {};
}
@ -269,13 +271,13 @@ Error Directory<FileStore, InodeId_t>::ls(F cb) noexcept {
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (!buff.valid()) {
oxTrace("ox.fs.Directory.ls.fail", "Could not directory buffer");
return OxError(1, "Could not directory buffer");
return ox::Error(1, "Could not directory buffer");
}
oxTrace("ox.fs.Directory.ls", "Found directory buffer.");
for (auto i = buff->iterator(); i.valid(); i.next()) {
auto data = i->data();
if (data.valid()) {
oxReturnError(cb(data->name, data->inode));
OX_RETURN_ERROR(cb(data->name, data->inode));
} else {
oxTrace("ox.fs.Directory.ls", "INVALID DIRECTORY ENTRY");
}
@ -289,7 +291,7 @@ Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry
auto buff = m_fs.read(m_inodeId).template to<Buffer>();
if (!buff.valid()) {
oxTrace("ox.fs.Directory.findEntry.fail", "Could not findEntry directory buffer");
return OxError(2, "Could not findEntry directory buffer");
return ox::Error(2, "Could not findEntry directory buffer");
}
oxTracef("ox.fs.Directory.findEntry", "Found directory buffer, size: {}", buff.size());
for (auto i = buff->iterator(); i.valid(); i.next()) {
@ -305,15 +307,15 @@ Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::findEntry
}
}
oxTrace("ox.fs.Directory.findEntry.fail", "Entry not present");
return OxError(1, "Entry not present");
return ox::Error(1, "Entry not present");
}
template<typename FileStore, typename InodeId_t>
Result<typename FileStore::InodeId_t> Directory<FileStore, InodeId_t>::find(PathIterator path) const noexcept {
// determine if already exists
ox::StringView name;
oxReturnError(path.get(name));
oxRequire(v, findEntry(name));
OX_RETURN_ERROR(path.get(name));
OX_REQUIRE(v, findEntry(name));
// recurse if not at end of path
if (auto p = path.next(); p.valid()) {
Directory dir(m_fs, v);
@ -333,3 +335,5 @@ using Directory16 = Directory<FileStore16, uint16_t>;
using Directory32 = Directory<FileStore32, uint32_t>;
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -32,7 +32,9 @@ FileAddress::FileAddress(ox::StringViewCR path) noexcept {
auto pathSize = path.bytes();
m_data.path = new char[pathSize + 1];
memcpy(m_data.path, path.data(), pathSize);
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
m_data.path[pathSize] = 0;
OX_CLANG_NOWARN_END
m_type = FileAddressType::Path;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -13,6 +13,8 @@
#include <ox/model/typenamecatcher.hpp>
#include <ox/model/types.hpp>
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
enum class FileAddressType: int8_t {
@ -87,7 +89,7 @@ class FileAddress {
case FileAddressType::Inode:
return m_data.inode;
default:
return OxError(1);
return ox::Error(1);
}
}
@ -98,7 +100,7 @@ class FileAddress {
case FileAddressType::ConstPath:
return ox::CStringView(m_data.constPath);
default:
return OxError(1);
return ox::Error(1);
}
}
@ -152,31 +154,33 @@ constexpr const char *getModelTypeName<FileAddress>() noexcept {
template<typename T>
constexpr Error model(T *h, CommonPtrWith<FileAddress::Data> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<FileAddress::Data>());
oxReturnError(h->fieldCString("path", &obj->path));
oxReturnError(h->fieldCString("constPath", &obj->path));
oxReturnError(h->field("inode", &obj->inode));
OX_RETURN_ERROR(h->template setTypeInfo<FileAddress::Data>());
OX_RETURN_ERROR(h->fieldCString("path", &obj->path));
OX_RETURN_ERROR(h->fieldCString("constPath", &obj->path));
OX_RETURN_ERROR(h->field("inode", &obj->inode));
return {};
}
template<typename T>
constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
oxReturnError(h->template setTypeInfo<FileAddress>());
OX_RETURN_ERROR(h->template setTypeInfo<FileAddress>());
if constexpr(T::opType() == OpType::Reflect) {
int8_t type = -1;
oxReturnError(h->field("type", &type));
oxReturnError(h->field("data", UnionView(&fa->m_data, type)));
OX_RETURN_ERROR(h->field("type", &type));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, type)));
} else if constexpr(T::opType() == OpType::Read) {
auto type = static_cast<int8_t>(fa->m_type);
oxReturnError(h->field("type", &type));
OX_RETURN_ERROR(h->field("type", &type));
fa->m_type = static_cast<FileAddressType>(type);
oxReturnError(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
} else if constexpr(T::opType() == OpType::Write) {
auto const type = static_cast<int8_t>(fa->m_type);
oxReturnError(h->field("type", &type));
oxReturnError(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
OX_RETURN_ERROR(h->field("type", &type));
OX_RETURN_ERROR(h->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
}
return {};
}
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -21,7 +21,7 @@ Result<const char*> MemFS::directAccess(const FileAddress &addr) const noexcept
case FileAddressType::Path:
return directAccess(StringView(addr.getPath().value));
default:
return OxError(1);
return ox::Error(1);
}
}
@ -33,21 +33,21 @@ Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size)
case FileAddressType::Path:
return readFilePath(StringView(addr.getPath().value), buffer, size);
default:
return OxError(1);
return ox::Error(1);
}
}
Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
oxRequire(s, stat(addr));
OX_REQUIRE(s, stat(addr));
Buffer buff(static_cast<std::size_t>(s.size));
oxReturnError(read(addr, buff.data(), buff.size()));
OX_RETURN_ERROR(read(addr, buff.data(), buff.size()));
return buff;
}
Result<Buffer> FileSystem::read(StringViewCR path) noexcept {
oxRequire(s, statPath(path));
OX_REQUIRE(s, statPath(path));
Buffer buff(static_cast<std::size_t>(s.size));
oxReturnError(readFilePath(path, buff.data(), buff.size()));
OX_RETURN_ERROR(readFilePath(path, buff.data(), buff.size()));
return buff;
}
@ -57,9 +57,9 @@ Error FileSystem::read(const FileAddress &addr, std::size_t readStart, std::size
return read(addr.getInode().value, readStart, readSize, buffer, size);
case FileAddressType::ConstPath:
case FileAddressType::Path:
return OxError(2, "Unsupported for path lookups");
return ox::Error(2, "Unsupported for path lookups");
default:
return OxError(1);
return ox::Error(1);
}
}
@ -71,7 +71,7 @@ Error FileSystem::remove(const FileAddress &addr, bool recursive) noexcept {
case FileAddressType::Path:
return remove(StringView(addr.getPath().value), recursive);
default:
return OxError(1);
return ox::Error(1);
}
}
@ -83,7 +83,7 @@ Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t si
case FileAddressType::Path:
return writeFilePath(StringView(addr.getPath().value), buffer, size, fileType);
default:
return OxError(1);
return ox::Error(1);
}
}
@ -95,7 +95,7 @@ Result<FileStat> FileSystem::stat(const FileAddress &addr) const noexcept {
case FileAddressType::Path:
return statPath(StringView(addr.getPath().value));
default:
return OxError(1);
return ox::Error(1);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -284,69 +284,69 @@ FileSystemTemplate<FileStore, Directory>::~FileSystemTemplate() noexcept {
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::format(void *buff, uint64_t buffSize) noexcept {
oxReturnError(FileStore::format(buff, static_cast<size_t>(buffSize)));
OX_RETURN_ERROR(FileStore::format(buff, static_cast<size_t>(buffSize)));
FileStore fs(buff, static_cast<size_t>(buffSize));
constexpr auto rootDirInode = MaxValue<typename FileStore::InodeId_t> / 2;
Directory rootDir(fs, rootDirInode);
oxReturnError(rootDir.init());
OX_RETURN_ERROR(rootDir.init());
FileSystemData fd;
fd.rootDirInode = rootDirInode;
oxTracef("ox.fs.FileSystemTemplate.format", "rootDirInode: {}", fd.rootDirInode.get());
oxReturnError(fs.write(InodeFsData, &fd, sizeof(fd)));
OX_RETURN_ERROR(fs.write(InodeFsData, &fd, sizeof(fd)));
if (!fs.read(fd.rootDirInode).valid()) {
oxTrace("ox.fs.FileSystemTemplate.format.error", "FileSystemTemplate::format did not correctly create root directory");
return OxError(1);
return ox::Error(1);
}
return OxError(0);
return ox::Error(0);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::mkdir(StringViewCR path, bool recursive) noexcept {
oxTracef("ox.fs.FileSystemTemplate.mkdir", "path: {}, recursive: {}", path, recursive);
oxRequireM(rootDir, this->rootDir());
OX_REQUIRE_M(rootDir, this->rootDir());
return rootDir.mkdir(path, recursive);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::move(StringViewCR src, StringViewCR dest) noexcept {
oxRequire(fd, fileSystemData());
OX_REQUIRE(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
oxRequireM(inode, rootDir.find(src));
oxReturnError(rootDir.write(dest, inode));
oxReturnError(rootDir.remove(src));
return OxError(0);
OX_REQUIRE_M(inode, rootDir.find(src));
OX_RETURN_ERROR(rootDir.write(dest, inode));
OX_RETURN_ERROR(rootDir.remove(src));
return ox::Error(0);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::readFilePath(StringViewCR path, void *buffer, std::size_t buffSize) noexcept {
oxTrace("ox.fs.FileSystemTemplate.readFilePath", path);
oxRequire(fd, fileSystemData());
OX_REQUIRE(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(s, stat(path));
OX_REQUIRE(s, stat(path));
if (s.size > buffSize) {
return OxError(1, "Buffer to small to load file");
return ox::Error(1, "Buffer to small to load file");
}
return readFileInodeRange(s.inode, 0, static_cast<size_t>(s.size), buffer, &buffSize);
}
template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessPath(StringViewCR path) const noexcept {
oxRequire(fd, fileSystemData());
OX_REQUIRE(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(inode, rootDir.find(path));
OX_REQUIRE(inode, rootDir.find(path));
return directAccessInode(inode);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
oxTracef("ox.fs.FileSystemTemplate.readFileInode", "{}", inode);
oxRequire(s, stat(inode));
OX_REQUIRE(s, stat(inode));
if (s.size > buffSize) {
return OxError(1, "Buffer to small to load file");
return ox::Error(1, "Buffer to small to load file");
}
return readFileInodeRange(inode, 0, static_cast<size_t>(s.size), buffer, &buffSize);
}
@ -360,7 +360,7 @@ template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) const noexcept {
auto data = m_fs.read(inode);
if (!data.valid()) {
return OxError(1, "Data not valid");
return ox::Error(1, "Data not valid");
}
return reinterpret_cast<char*>(data.get());
}
@ -368,9 +368,9 @@ Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(
template<typename FileStore, typename Directory>
Result<Vector<String>> FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path) const noexcept {
Vector<String> out;
oxReturnError(ls(path, [&out](StringViewCR name, typename FileStore::InodeId_t) {
OX_RETURN_ERROR(ls(path, [&out](StringViewCR name, typename FileStore::InodeId_t) {
out.emplace_back(name);
return OxError(0);
return ox::Error(0);
}));
return out;
}
@ -379,17 +379,17 @@ template<typename FileStore, typename Directory>
template<typename F>
Error FileSystemTemplate<FileStore, Directory>::ls(StringViewCR path, F cb) const {
oxTracef("ox.fs.FileSystemTemplate.ls", "path: {}", path);
oxRequire(s, stat(path));
OX_REQUIRE(s, stat(path));
Directory dir(m_fs, s.inode);
return dir.ls(cb);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::remove(StringViewCR path, bool recursive) noexcept {
oxRequire(fd, fileSystemData());
OX_REQUIRE(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(inode, rootDir.find(path));
oxRequire(st, statInode(inode));
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
@ -398,9 +398,9 @@ Error FileSystemTemplate<FileStore, Directory>::remove(StringViewCR path, bool r
}
} else {
oxTrace("FileSystemTemplate.remove.fail", "Tried to remove directory without recursive setting.");
return OxError(1);
return ox::Error(1);
}
return OxError(0);
return ox::Error(0);
}
template<typename FileStore, typename Directory>
@ -410,7 +410,7 @@ Error FileSystemTemplate<FileStore, Directory>::resize() noexcept {
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::resize(uint64_t size, void *buffer) noexcept {
oxReturnError(m_fs.resize(static_cast<size_t>(size), buffer));
OX_RETURN_ERROR(m_fs.resize(static_cast<size_t>(size), buffer));
return {};
}
@ -423,11 +423,11 @@ Error FileSystemTemplate<FileStore, Directory>::writeFilePath(
oxTrace("ox.fs.FileSystemTemplate.writeFilePath", path);
auto [inode, err] = find(path);
if (err) {
oxReturnError(m_fs.generateInodeId().moveTo(inode));
oxRequireM(rootDir, this->rootDir());
oxReturnError(rootDir.write(path, inode));
OX_RETURN_ERROR(m_fs.generateInodeId().moveTo(inode));
OX_REQUIRE_M(rootDir, this->rootDir());
OX_RETURN_ERROR(rootDir.write(path, inode));
}
oxReturnError(writeFileInode(inode, buffer, size, fileType));
OX_RETURN_ERROR(writeFileInode(inode, buffer, size, fileType));
return {};
}
@ -439,7 +439,7 @@ Error FileSystemTemplate<FileStore, Directory>::writeFileInode(uint64_t inode, c
template<typename FileStore, typename Directory>
Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t inode) const noexcept {
oxRequire(s, m_fs.stat(inode));
OX_REQUIRE(s, m_fs.stat(inode));
FileStat out;
out.inode = s.inode;
out.links = s.links;
@ -450,7 +450,7 @@ Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t in
template<typename FileStore, typename Directory>
Result<FileStat> FileSystemTemplate<FileStore, Directory>::statPath(StringViewCR path) const noexcept {
oxRequire(inode, find(path));
OX_REQUIRE(inode, find(path));
return stat(inode);
}
@ -487,25 +487,25 @@ bool FileSystemTemplate<FileStore, Directory>::valid() const noexcept {
template<typename FileStore, typename Directory>
Result<typename FileSystemTemplate<FileStore, Directory>::FileSystemData> FileSystemTemplate<FileStore, Directory>::fileSystemData() const noexcept {
FileSystemData fd;
oxReturnError(m_fs.read(InodeFsData, &fd, sizeof(fd)));
OX_RETURN_ERROR(m_fs.read(InodeFsData, &fd, sizeof(fd)));
return fd;
}
template<typename FileStore, typename Directory>
Result<uint64_t> FileSystemTemplate<FileStore, Directory>::find(StringViewCR path) const noexcept {
oxRequire(fd, fileSystemData());
OX_REQUIRE(fd, fileSystemData());
// return root as a special case
if (path == "/") {
return static_cast<uint64_t>(fd.rootDirInode);
}
Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(out, rootDir.find(path));
OX_REQUIRE(out, rootDir.find(path));
return static_cast<uint64_t>(out);
}
template<typename FileStore, typename Directory>
Result<Directory> FileSystemTemplate<FileStore, Directory>::rootDir() const noexcept {
oxRequire(fd, fileSystemData());
OX_REQUIRE(fd, fileSystemData());
return Directory(m_fs, fd.rootDirInode);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -39,7 +39,7 @@ Error PassThroughFS::mkdir(StringViewCR path, bool recursive) noexcept {
success = true;
} else {
success = std::filesystem::create_directories(p, ec);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
}
} else {
std::error_code ec;
@ -48,26 +48,26 @@ Error PassThroughFS::mkdir(StringViewCR path, bool recursive) noexcept {
success = true;
} else {
success = std::filesystem::create_directory(p, ec);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: mkdir failed"));
}
}
return OxError(success ? 0 : 1);
return ox::Error(success ? 0 : 1);
}
Error PassThroughFS::move(StringViewCR src, StringViewCR dest) noexcept {
std::error_code ec;
std::filesystem::rename(m_path / stripSlash(src), m_path / stripSlash(dest), ec);
if (ec.value()) {
return OxError(1);
return ox::Error(1);
}
return OxError(0);
return ox::Error(0);
}
Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept {
Vector<String> out;
std::error_code ec;
const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
for (const auto &p : di) {
const auto u8p = p.path().filename().u8string();
out.emplace_back(reinterpret_cast<const char*>(u8p.c_str()));
@ -77,20 +77,20 @@ Result<Vector<String>> PassThroughFS::ls(StringViewCR dir) const noexcept {
Error PassThroughFS::remove(StringViewCR path, bool recursive) noexcept {
if (recursive) {
return OxError(std::filesystem::remove_all(m_path / stripSlash(path)) != 0);
return ox::Error(std::filesystem::remove_all(m_path / stripSlash(path)) != 0);
} else {
return OxError(std::filesystem::remove(m_path / stripSlash(path)) != 0);
return ox::Error(std::filesystem::remove(m_path / stripSlash(path)) != 0);
}
}
Error PassThroughFS::resize(uint64_t, void*) noexcept {
// unsupported
return OxError(1, "resize is not supported by PassThroughFS");
return ox::Error(1, "resize is not supported by PassThroughFS");
}
Result<FileStat> PassThroughFS::statInode(uint64_t) const noexcept {
// unsupported
return OxError(1, "statInode(uint64_t) is not supported by PassThroughFS");
return ox::Error(1, "statInode(uint64_t) is not supported by PassThroughFS");
}
Result<FileStat> PassThroughFS::statPath(StringViewCR path) const noexcept {
@ -101,7 +101,7 @@ Result<FileStat> PassThroughFS::statPath(StringViewCR path) const noexcept {
oxTracef("ox.fs.PassThroughFS.statInode", "{} {}", ec.message(), path);
const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
oxTracef("ox.fs.PassThroughFS.statInode.size", "{} {}", path, size);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: stat failed"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: stat failed"));
return FileStat{0, 0, size, type};
}
@ -112,14 +112,14 @@ uint64_t PassThroughFS::spaceNeeded(uint64_t size) const noexcept {
Result<uint64_t> PassThroughFS::available() const noexcept {
std::error_code ec;
const auto s = std::filesystem::space(m_path, ec);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
return s.available;
}
Result<uint64_t> PassThroughFS::size() const noexcept {
std::error_code ec;
const auto s = std::filesystem::space(m_path, ec);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: could not get FS size"));
return s.capacity;
}
@ -128,7 +128,7 @@ char *PassThroughFS::buff() noexcept {
}
Error PassThroughFS::walk(Error(*)(uint8_t, uint64_t, uint64_t)) noexcept {
return OxError(1, "walk(Error(*)(uint8_t, uint64_t, uint64_t)) is not supported by PassThroughFS");
return ox::Error(1, "walk(Error(*)(uint8_t, uint64_t, uint64_t)) is not supported by PassThroughFS");
}
bool PassThroughFS::valid() const noexcept {
@ -147,24 +147,24 @@ Error PassThroughFS::readFilePath(StringViewCR path, void *buffer, std::size_t b
file.seekg(0, std::ios::beg);
if (size > buffSize) {
oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path);
return OxError(1);
return ox::Error(1);
}
file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(buffSize));
} catch (const std::fstream::failure &f) {
oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what());
return OxError(2);
return ox::Error(2);
}
return OxError(0);
return ox::Error(0);
}
Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept {
// unsupported
return OxError(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::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
// unsupported
return OxError(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::writeFilePath(StringViewCR path, const void *buffer, uint64_t size, FileType) noexcept {
@ -174,14 +174,14 @@ Error PassThroughFS::writeFilePath(StringViewCR path, const void *buffer, uint64
f.write(static_cast<const char*>(buffer), static_cast<std::streamsize>(size));
} catch (const std::fstream::failure &f) {
oxTracef("ox.fs.PassThroughFS.read.error", "Write of {} failed: {}", path, f.what());
return OxError(1);
return ox::Error(1);
}
return OxError(0);
return ox::Error(0);
}
Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) noexcept {
// unsupported
return OxError(1, "writeFileInode(uint64_t, void*, uint64_t, uint8_t) is not supported by PassThroughFS");
return ox::Error(1, "writeFileInode(uint64_t, void*, uint64_t, uint8_t) is not supported by PassThroughFS");
}
std::string_view PassThroughFS::stripSlash(StringView path) noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -92,11 +92,11 @@ template<typename F>
Error PassThroughFS::ls(StringViewCR dir, F cb) const noexcept {
std::error_code ec;
const auto di = std::filesystem::directory_iterator(m_path / stripSlash(dir), ec);
oxReturnError(OxError(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
OX_RETURN_ERROR(ox::Error(static_cast<ox::ErrorCode>(ec.value()), "PassThroughFS: ls failed"));
for (auto &p : di) {
oxReturnError(cb(p.path().filename().c_str(), 0));
OX_RETURN_ERROR(cb(p.path().filename().c_str(), 0));
}
return OxError(0);
return ox::Error(0);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -11,6 +11,8 @@
#include <ox/std/trace.hpp>
#include "pathiterator.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
@ -30,13 +32,13 @@ PathIterator::PathIterator(StringViewCR path): PathIterator(path.data(), path.by
*/
Error PathIterator::dirPath(char *out, std::size_t outSize) {
const auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
const auto size = static_cast<std::size_t>(idx + 1);
const auto size = static_cast<std::size_t>(idx) + 1;
if (idx >= 0 && size < outSize) {
ox::memcpy(out, m_path, size);
out[size] = 0;
return OxError(0);
return ox::Error(0);
} else {
return OxError(1);
return ox::Error(1);
}
}
@ -45,11 +47,11 @@ Error PathIterator::get(StringView &fileName) {
std::size_t size = 0;
if (m_iterator >= m_maxSize) {
oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize);
return OxError(1);
return ox::Error(1);
}
if (!ox::strlen(&m_path[m_iterator])) {
oxTrace("ox.fs.PathIterator.get", "!ox::strlen(&m_path[m_iterator])");
return OxError(1);
return ox::Error(1);
}
auto start = m_iterator;
if (m_path[start] == '/') {
@ -65,7 +67,7 @@ Error PathIterator::get(StringView &fileName) {
size = end - start;
// cannot fit the output in the output parameter
if (size >= MaxFileNameLength || size == 0) {
return OxError(1);
return ox::Error(1);
}
fileName = ox::substr(m_path, start, start + size);
// truncate trailing /
@ -81,9 +83,9 @@ Error PathIterator::get(StringView &fileName) {
*/
Error PathIterator::next(StringView &fileName) {
std::size_t size = 0;
auto retval = OxError(1);
auto retval = ox::Error(1);
if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
retval = OxError(0);
retval = ox::Error(0);
if (m_path[m_iterator] == '/') {
m_iterator++;
}
@ -98,7 +100,7 @@ Error PathIterator::next(StringView &fileName) {
size = end - start;
// cannot fit the output in the output parameter
if (size >= MaxFileNameLength) {
return OxError(1);
return ox::Error(1);
}
fileName = ox::substr(m_path, start, start + size);
// truncate trailing /
@ -113,10 +115,10 @@ Error PathIterator::next(StringView &fileName) {
Result<std::size_t> PathIterator::nextSize() const {
std::size_t size = 0;
auto retval = OxError(1);
auto retval = ox::Error(1);
auto it = m_iterator;
if (it < m_maxSize && ox::strlen(&m_path[it])) {
retval = OxError(0);
retval = ox::Error(0);
if (m_path[it] == '/') {
it++;
}
@ -183,3 +185,5 @@ const char *PathIterator::fullPath() const {
}
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -13,6 +13,8 @@
#include "ptr.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox::ptrarith {
template<typename size_t, typename Item>
@ -282,14 +284,14 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
addr = m_header.firstItem;
} else {
oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer is in invalid state.");
return OxError(1, "NodeBuffer is in invalid state.");
return ox::Error(1, "NodeBuffer is in invalid state.");
}
}
oxTracef("ox.ptrarith.NodeBuffer.malloc", "buffer size: {}; addr: {}; fullSize: {}", m_header.size.get(), addr, fullSize);
auto out = ItemPtr(this, m_header.size, addr, fullSize);
if (!out.valid()) {
oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "Unknown");
return OxError(1, "NodeBuffer::malloc: unknown failure");
return ox::Error(1, "NodeBuffer::malloc: unknown failure");
}
ox::memset(out, 0, fullSize);
new (out) Item;
@ -302,7 +304,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
first->prev = out.offset();
} else {
oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer malloc failed due to invalid first element pointer.");
return OxError(1, "NodeBuffer malloc failed due to invalid first element pointer.");
return ox::Error(1, "NodeBuffer malloc failed due to invalid first element pointer.");
}
if (oldLast.valid()) {
@ -312,7 +314,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
if (out.offset() != first.offset()) {
// if this is not the first allocation, there should be an oldLast
oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "NodeBuffer malloc failed due to invalid last element pointer.");
return OxError(1, "NodeBuffer malloc failed due to invalid last element pointer.");
return ox::Error(1, "NodeBuffer malloc failed due to invalid last element pointer.");
}
out->prev = out.offset();
}
@ -321,7 +323,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
return out;
}
oxTracef("ox.ptrarith.NodeBuffer.malloc.fail", "Insufficient space: {} needed, {} available", fullSize, available());
return OxError(1);
return ox::Error(1);
}
template<typename size_t, typename Item>
@ -344,15 +346,15 @@ Error NodeBuffer<size_t, Item>::free(ItemPtr item) noexcept {
} else {
if (!prev.valid()) {
oxTracef("ox.ptrarith.NodeBuffer.free.fail", "NodeBuffer free failed due to invalid prev element pointer: {}", prev.offset());
return OxError(1);
return ox::Error(1);
}
if (!next.valid()) {
oxTracef("ox.ptrarith.NodeBuffer.free.fail", "NodeBuffer free failed due to invalid next element pointer: {}", next.offset());
return OxError(1);
return ox::Error(1);
}
}
m_header.bytesUsed -= item.size();
return OxError(0);
return ox::Error(0);
}
template<typename size_t, typename Item>
@ -363,12 +365,12 @@ Error NodeBuffer<size_t, Item>::setSize(std::size_t size) noexcept {
oxTracef("ox.ptrarith.NodeBuffer.setSize", "end: {}", end);
if (end > size) {
// resizing to less than buffer size
return OxError(1);
return ox::Error(1);
} else {
m_header.size = static_cast<size_t>(size);
auto data = reinterpret_cast<uint8_t*>(this) + end;
ox::memset(data, 0, size - end);
return OxError(0);
return ox::Error(0);
}
}
@ -399,14 +401,14 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
auto dest = ptr(sizeof(*this));
while (dest.offset() <= src.offset()) {
if (!src.valid()) {
return OxError(1);
return ox::Error(1);
}
if (!dest.valid()) {
return OxError(2);
return ox::Error(2);
}
// move node
ox::memcpy(dest, src, src->fullSize());
oxReturnError(cb(src, dest));
OX_RETURN_ERROR(cb(src, dest));
// update surrounding nodes
auto prev = ptr(dest->prev);
if (prev.valid()) {
@ -420,7 +422,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
src = ptr(dest->next);
dest = uninitializedPtr(dest.offset() + dest->fullSize());
}
return OxError(0);
return ox::Error(0);
}
template<typename size_t, typename Item>
@ -449,3 +451,5 @@ struct OX_PACKED Item {
};
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -10,6 +10,8 @@
#include <ox/std/std.hpp>
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox::ptrarith {
template<typename T, typename size_t, size_t minOffset = 1>
@ -252,7 +254,9 @@ constexpr Result<Ptr<T, size_t, minOffset>> Ptr<T, size_t, minOffset>::validate(
if (valid()) {
return *this;
}
return OxError(1);
return ox::Error(1);
}
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -52,7 +52,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
oxAssert(buffer->free(a1), "Free failed.");
oxAssert(buffer->free(a2), "Free failed.");
oxAssert(buffer->setSize(buffer->size() - buffer->available()), "Resize failed.");
return OxError(0);
return ox::Error(0);
}
},
{
@ -64,7 +64,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next");
return OxError(0);
return ox::Error(0);
}
},
{
@ -77,7 +77,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
oxExpect(buff, "usr");
oxAssert(it.next(buff), "PathIterator::next returned error");
oxExpect(buff, "share");
return OxError(0);
return ox::Error(0);
}
},
{
@ -87,7 +87,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
ox::PathIterator it(path.c_str(), path.len());
ox::StringView buff;
oxAssert(it.next(buff) == 0 && buff == "\0", "PathIterator shows wrong next");
return OxError(0);
return ox::Error(0);
}
},
{
@ -99,7 +99,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
oxAssert(it.next(buff) == 0 && buff == "charset.gbag", "PathIterator shows wrong next");
return OxError(0);
return ox::Error(0);
}
},
{
@ -110,7 +110,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
ox::StringView buff;
oxAssert(it.next(buff) == 0 && buff == "usr", "PathIterator shows wrong next");
oxAssert(it.next(buff) == 0 && buff == "share", "PathIterator shows wrong next");
return OxError(0);
return ox::Error(0);
}
},
{
@ -120,7 +120,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
return OxError(0);
return ox::Error(0);
}
},
{
@ -130,7 +130,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
ox::PathIterator it(path, ox::strlen(path));
oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext");
oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext");
return OxError(0);
return ox::Error(0);
}
},
{
@ -142,7 +142,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto subPtr = p.subPtr<uint64_t>(50);
oxAssert(subPtr.valid(), "Ptr::subPtr: Ptr subPtr is invalid.");
return OxError(0);
return ox::Error(0);
}
},
{
@ -155,7 +155,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto first = list->firstItem();
oxAssert(first.valid(), "NodeBuffer::insert: Could not access first item");
oxAssert(first->size() == 50, "NodeBuffer::insert: First item size invalid");
return OxError(0);
return ox::Error(0);
}
},
{
@ -176,7 +176,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
size_t str1ReadSize = 0;
oxAssert(fileStore.read(4, reinterpret_cast<void*>(str1Read), str1Len, &str1ReadSize), "FileStore::read 1 failed.");
return OxError(0);
return ox::Error(0);
}
},
{
@ -203,7 +203,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
oxTrace("ox.fs.test.Directory") << "write 3";
oxAssert(dir.write("/file2", 2), "Directory write of file2 failed");
return OxError(0);
return ox::Error(0);
}
},
{
@ -220,19 +220,20 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
oxAssert(fs.stat("/l1d1/l2d1/l3d1").error, "mkdir failed");
oxAssert(fs.mkdir("/l1d1/l2d2", true), "mkdir failed");
oxAssert(fs.stat("/l1d1/l2d2").error, "mkdir failed");
return OxError(0);
return ox::Error(0);
}
},
},
};
int main(int argc, const char **args) {
int main(int argc, const char **argv) {
if (argc < 2) {
oxError("Must specify test to run");
return -1;
}
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
ox::StringView const testName = args[1];
ox::StringView const testArg = args[2] ? args[2] : nullptr;
ox::StringView const testArg = argc >= 3 ? args[2] : nullptr;
auto const func = tests.find(testName);
if (func != tests.end()) {
oxAssert(func->second(testArg), "Test returned Error");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -20,7 +20,7 @@ static ox::Result<Buff> loadFsBuff(const char *path) noexcept {
std::ifstream file(path, std::ios::binary | std::ios::ate);
if (!file.good()) {
oxErrorf("Could not find OxFS file: {}", path);
return OxError(1, "Could not find OxFS file");
return ox::Error(1, "Could not find OxFS file");
}
try {
const auto size = static_cast<std::size_t>(file.tellg());
@ -30,51 +30,52 @@ static ox::Result<Buff> loadFsBuff(const char *path) noexcept {
return Buff{buff, size};
} catch (const std::ios_base::failure &e) {
oxErrorf("Could not read OxFS file: {}", e.what());
return OxError(2, "Could not read OxFS file");
return ox::Error(2, "Could not read OxFS file");
}
}
static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexcept {
oxRequire(buff, loadFsBuff(path));
OX_REQUIRE(buff, loadFsBuff(path));
return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)};
}
static ox::Error runLs(ox::FileSystem *fs, int argc, const char **argv) noexcept {
if (argc < 2) {
static ox::Error runLs(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
if (args.size() < 2) {
oxErr("Must provide a directory to ls\n");
return OxError(1);
return ox::Error(1);
}
oxRequire(files, fs->ls(argv[1]));
OX_REQUIRE(files, fs->ls(args[1]));
for (const auto &file : files) {
oxOutf("{}\n", file);
}
return OxError(0);
return ox::Error(0);
}
static ox::Error runRead(ox::FileSystem *fs, int argc, const char **argv) noexcept {
if (argc < 2) {
static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
if (args.size() < 2) {
oxErr("Must provide a path to a file to read\n");
return OxError(1);
return ox::Error(1);
}
oxRequire(buff, fs->read(ox::StringView(argv[1])));
fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
return OxError(0);
OX_REQUIRE(buff, fs->read(ox::StringView(args[1])));
std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
return ox::Error(0);
}
static ox::Error run(int argc, const char **argv) noexcept {
if (argc < 3) {
oxErr("OxFS file and subcommand arguments are required\n");
return OxError(1);
return ox::Error(1);
}
const auto fsPath = argv[1];
ox::String subCmd(argv[2]);
oxRequire(fs, loadFs(fsPath));
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
auto const fsPath = args[1];
ox::String subCmd(args[2]);
OX_REQUIRE(fs, loadFs(fsPath));
if (subCmd == "ls") {
return runLs(fs.get(), argc - 2, argv + 2);
return runLs(fs.get(), args + 2);
} else if (subCmd == "read") {
return runRead(fs.get(), argc - 2, argv + 2);
return runRead(fs.get(), args + 2);
}
return OxError(1);
return ox::Error(1);
}
int main(int argc, const char **argv) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -34,7 +34,7 @@ class CirculerBuffer {
constexpr ox::Error put(char v) noexcept {
return write(&v, 1);
if (1 > avail()) {
return OxError(1, "Insufficient space in buffer");
return ox::Error(1, "Insufficient space in buffer");
}
m_buff[m_writePt] = v;
++m_writePt;
@ -43,8 +43,9 @@ class CirculerBuffer {
constexpr ox::Error write(const char *buff, std::size_t sz) noexcept {
if (sz > avail()) {
return OxError(1, "Insufficient space in buffer");
return ox::Error(1, "Insufficient space in buffer");
}
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
// write seg 1
const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
@ -56,12 +57,13 @@ class CirculerBuffer {
ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
oxAssert(m_buff[0] == buff[seg1Sz], "break");
}
OX_ALLOW_UNSAFE_BUFFERS_END
return {};
}
constexpr ox::Error seekp(std::size_t bytesFwd) noexcept {
if (bytesFwd > avail()) {
return OxError(1, "Insufficient space in buffer to seek that far ahead");
return ox::Error(1, "Insufficient space in buffer to seek that far ahead");
}
m_writePt += bytesFwd;
if (m_writePt > m_buff.size()) {
@ -71,7 +73,7 @@ class CirculerBuffer {
}
constexpr ox::Error seekp(int, ios_base::seekdir) noexcept {
return OxError(1, "Unimplemented");
return ox::Error(1, "Unimplemented");
}
[[nodiscard]]
@ -90,7 +92,9 @@ class CirculerBuffer {
m_readPt -= m_buff.size();
// read seg 2
const auto seg2Sz = bytesRead - seg1Sz;
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
OX_ALLOW_UNSAFE_BUFFERS_END
}
return bytesRead;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -9,8 +9,8 @@
#ifdef OX_USE_STDLIB
#include <cstdio>
#include <sys/types.h>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@ -25,15 +25,22 @@
#include "logconn.hpp"
#include <ox/std/bit.hpp>
namespace ox {
#ifdef _WIN32
using Socket = SOCKET;
using LenType = int;
#else
using Socket = int;
using LenType = size_t;
#endif
using namespace trace;
void closeSock(auto s) noexcept {
static void closeSock(auto s) noexcept {
#ifdef _WIN32
closesocket(s);
closesocket(static_cast<Socket>(s));
#else
close(s);
#endif
@ -56,8 +63,8 @@ ox::Error LoggerConn::initConn(ox::StringViewCR appName) noexcept {
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = htons(5590);
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
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)))));
return sendInit({.appName = ox::BasicString<128>(appName)});
}
@ -65,10 +72,10 @@ ox::Error LoggerConn::send(const char *buff, std::size_t len) const noexcept {
std::size_t totalSent = 0;
while (totalSent < len) {
//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
const auto sent = ::send(m_socket, buff, len, 0);
const auto sent = ::send(static_cast<Socket>(m_socket), buff, static_cast<LenType>(len), 0);
if (sent < 0) {
std::fprintf(stderr, "Could not send msg\n");
return OxError(1, "Could not send msg");
std::ignore = std::fprintf(stderr, "Could not send msg\n");
return ox::Error(1, "Could not send msg");
}
totalSent += static_cast<std::size_t>(sent);
}
@ -90,13 +97,14 @@ void LoggerConn::msgSend() noexcept {
if (!m_running) {
break;
}
std::lock_guard buffLk(m_buffMut);
std::lock_guard const buffLk(m_buffMut);
while (true) {
ox::Array<char, ox::units::KB> tmp;
Array<char, units::KB> tmp;
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);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -45,13 +45,13 @@ class LoggerConn: public trace::Logger {
ox::Error send(trace::MsgId msgId, const auto &msg) noexcept {
ox::Array<char, 10 * ox::units::KB> buff;
std::size_t sz = 0;
oxReturnError(ox::writeMC(&buff[0], buff.size(), msg, &sz));
OX_RETURN_ERROR(ox::writeMC(&buff[0], buff.size(), msg, &sz));
//std::printf("sz: %lu\n", sz);
oxRequire(szBuff, serialize(static_cast<uint32_t>(sz)));
OX_REQUIRE(szBuff, serialize(static_cast<uint32_t>(sz)));
std::unique_lock buffLk(m_buffMut);
oxReturnError(m_buff.put(static_cast<char>(msgId)));
oxReturnError(m_buff.write(szBuff.data(), szBuff.size()));
oxReturnError(m_buff.write(buff.data(), sz));
OX_RETURN_ERROR(m_buff.put(static_cast<char>(msgId)));
OX_RETURN_ERROR(m_buff.write(szBuff.data(), szBuff.size()));
OX_RETURN_ERROR(m_buff.write(buff.data(), sz));
buffLk.unlock();
m_waitCond.notify_one();
return {};

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -57,7 +57,7 @@ static_assert(highestBit(uint64_t(1) << 31) == 31);
static_assert(highestBit(uint64_t(1) << 63) == 63);
struct McInt {
uint8_t data[9] = {};
ox::Array<uint8_t, 9> data{};
// length of integer in bytes
std::size_t length = 0;
};
@ -104,7 +104,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
auto intermediate =
static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
static_cast<uint64_t>(bytesIndicator);
ox::memcpy(out.data, &intermediate, sizeof(intermediate));
ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate));
}
out.length = bytes;
}
@ -135,19 +135,19 @@ static_assert(countBytes(0b1111'1111) == 9);
template<typename I>
constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noexcept {
uint8_t firstByte = 0;
oxReturnError(rdr.read(&firstByte, 1));
oxReturnError(rdr.seekg(-1, ox::ios_base::cur));
OX_RETURN_ERROR(rdr.read(&firstByte, 1));
OX_RETURN_ERROR(rdr.seekg(-1, ox::ios_base::cur));
const auto bytes = countBytes(firstByte);
if (bytes == 9) {
*bytesRead = bytes;
I out = 0;
oxReturnError(rdr.seekg(1, ox::ios_base::cur));
oxReturnError(rdr.read(&out, sizeof(I)));
OX_RETURN_ERROR(rdr.seekg(1, ox::ios_base::cur));
OX_RETURN_ERROR(rdr.read(&out, sizeof(I)));
return fromLittleEndian<I>(out);
}
*bytesRead = bytes;
uint64_t decoded = 0;
oxReturnError(rdr.read(&decoded, bytes));
OX_RETURN_ERROR(rdr.read(&decoded, bytes));
decoded >>= bytes;
// move sign bit
if constexpr(is_signed_v<I>) {
@ -160,7 +160,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
ox::Array<uint32_t, 2> d = {};
//d[0] = decoded & 0xffff'ffff;
//d[1] = decoded >> 32;
ox::memcpy(d.data(), &decoded, sizeof(decoded));
ox::memcpy(&d[0], &decoded, sizeof(decoded));
auto bit = negBit;
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
d[0] |= 1 << bit;
@ -175,7 +175,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
d[0] = d[1];
d[1] = d0Tmp;
}
ox::memcpy(&out, d.data(), sizeof(out));
ox::memcpy(&out, &d[0], sizeof(out));
return out;
}
}
@ -185,7 +185,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
template<typename I>
Result<I> decodeInteger(McInt m) noexcept {
std::size_t bytesRead{};
BufferReader br({reinterpret_cast<const char*>(m.data), 9});
BufferReader br({reinterpret_cast<const char*>(m.data.data()), 9});
return decodeInteger<I>(br, &bytesRead);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -47,7 +47,7 @@ constexpr Result<bool> FieldBitmapReader<Reader>::get(std::size_t idx) const noe
constexpr auto blockBits = sizeof(m_mapBlock);
auto const blockIdx = idx / blockBits;
if (m_mapBlockIdx != blockIdx) [[unlikely]] {
oxReturnError(loadMapBlock(blockIdx));
OX_RETURN_ERROR(loadMapBlock(blockIdx));
}
idx %= blockBits;
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>
constexpr ox::Error FieldBitmapReader<Reader>::loadMapBlock(std::size_t idx) const noexcept {
oxRequire(g, m_reader.tellg());
oxReturnError(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
OX_REQUIRE(g, m_reader.tellg());
OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(m_mapStart + idx), ox::ios_base::beg));
ox::Array<char, sizeof(m_mapBlock)> mapBlock{};
oxReturnError(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
OX_RETURN_ERROR(m_reader.read(mapBlock.data(), sizeof(m_mapBlock)));
// Warning: narrow-conv
oxReturnError(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
OX_RETURN_ERROR(m_reader.seekg(static_cast<int>(g), ox::ios_base::beg));
m_mapBlock = 0;
for (auto i = 0ull; auto b : mapBlock) {
m_mapBlock |= static_cast<uint64_t>(std::bit_cast<uint8_t>(b)) << i;
@ -110,7 +110,7 @@ constexpr Result<bool> FieldBitmapWriterBase<T>::get(std::size_t i) const noexce
if (i / 8 < m_mapLen) {
return (m_map[i / 8] >> (i % 8)) & 1;
} else {
return OxError(McPresenceMapOverflow);
return ox::Error(McPresenceMapOverflow);
}
}
@ -147,14 +147,16 @@ constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept:
constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
if (i / 8 < m_mapLen) {
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
if (on) {
m_map[i / 8] |= 1 << (i % 8);
} else {
m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8));
}
OX_ALLOW_UNSAFE_BUFFERS_END
return {};
} else {
return OxError(McPresenceMapOverflow);
return ox::Error(McPresenceMapOverflow);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -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) {
auto const result = m_fieldPresence.get(static_cast<std::size_t>(m_field));
*val = result.value;
oxReturnError(result);
OX_RETURN_ERROR(result);
}
++m_field;
return OxError(0);
return ox::Error(0);
}
// array handler
@ -207,18 +207,20 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
// read the list
if (valLen >= len) {
auto reader = child({});
auto &handler = *reader.interface();
oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
for (std::size_t i = 0; i < len; ++i) {
oxReturnError(handler.field({}, &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field({}, &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END
}
} else {
oxTracef("ox.mc.read.field(T)", "{}, length: {}", name, valLen);
return OxError(McOutputBuffEnded);
return ox::Error(McOutputBuffEnded);
}
}
}
@ -232,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_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
oxRequire(g, m_reader.tellg());
OX_REQUIRE(g, m_reader.tellg());
std::size_t bytesRead = 0;
oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
oxReturnError(m_reader.seekg(g));
OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
OX_RETURN_ERROR(m_reader.seekg(g));
// read the list
auto reader = child("");
auto &handler = *reader.interface();
oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
OX_RETURN_ERROR(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
constexpr auto loopBody = [](auto &handler, auto &val) {
oxRequire(keyLen, handler.stringLength(nullptr));
OX_REQUIRE(keyLen, handler.stringLength(nullptr));
auto wkey = ox_malloca(keyLen + 1, char, 0);
auto wkeyPtr = wkey.get();
oxReturnError(handler.fieldCString("", &wkeyPtr, keyLen + 1));
OX_RETURN_ERROR(handler.fieldCString("", &wkeyPtr, keyLen + 1));
return handler.field("", &val[wkeyPtr]);
};
for (std::size_t i = 0; i < len; ++i) {
oxReturnError(loopBody(handler, *val));
OX_RETURN_ERROR(loopBody(handler, *val));
}
}
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -264,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) {
// 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))) {
oxRequire(len, arrayLength(name, false));
oxReturnError(ox::resizeVector(*val, len));
OX_REQUIRE(len, arrayLength(name, false));
OX_RETURN_ERROR(ox::resizeVector(*val, len));
return field(name, val->data(), val->size());
}
oxReturnError(ox::resizeVector(*val, 0));
OX_RETURN_ERROR(ox::resizeVector(*val, 0));
}
++m_field;
return {};
@ -276,9 +278,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, T *val)
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
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
oxRequire(len, arrayLength(name, false));
OX_REQUIRE(len, arrayLength(name, false));
if (len > val->size()) {
return OxError(1, "Input array is too long");
return ox::Error(1, "Input array is too long");
}
}
return field(name, val->data(), val->size());
@ -289,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_fieldPresence.get(static_cast<std::size_t>(m_field))) {
auto reader = child("");
oxReturnError(model(reader.interface(), val));
OX_RETURN_ERROR(model(reader.interface(), val));
}
}
++m_field;
@ -303,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_fieldPresence.get(static_cast<std::size_t>(m_field))) {
auto reader = child("", ox::Optional<int>(ox::in_place, val.idx()));
oxReturnError(model(reader.interface(), val.get()));
OX_RETURN_ERROR(model(reader.interface(), val.get()));
}
}
++m_field;
@ -317,18 +319,18 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
const auto cap = size;
*val = BasicString<SmallStringSize>(cap);
auto data = val->data();
// read the string
oxReturnError(m_reader.read(data, size));
OX_RETURN_ERROR(m_reader.read(data, size));
} else {
*val = "";
}
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -338,12 +340,12 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, IString<L> *
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
*val = IString<L>();
oxReturnError(val->resize(size));
OX_RETURN_ERROR(val->resize(size));
auto const data = val->data();
// read the string
oxReturnError(m_reader.read(data, size));
OX_RETURN_ERROR(m_reader.read(data, size));
} else {
*val = "";
}
@ -357,18 +359,18 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
if (size > buffLen) {
return OxError(McOutputBuffEnded);
return ox::Error(McOutputBuffEnded);
}
// re-allocate in case too small
auto data = val;
// read the string
oxReturnError(m_reader.read(data, size));
OX_RETURN_ERROR(m_reader.read(data, size));
data[size] = 0;
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -376,17 +378,17 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
// re-allocate in case too small
safeDelete(*val);
*val = new char[size + 1];
auto data = *val;
auto data = ox::Span{*val, size + 1};
// read the string
oxReturnError(m_reader.read(data, size));
OX_RETURN_ERROR(m_reader.read(data.data(), size));
data[size] = 0;
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -395,16 +397,16 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
OX_REQUIRE(size, mc::decodeInteger<StringLength>(m_reader, &bytesRead));
// re-allocate if too small
if (buffLen < size + 1) {
safeDelete(*val);
*val = new char[size + 1];
buffLen = size + 1;
}
auto data = *val;
auto data = ox::Span{*val, size + 1};
// read the string
oxReturnError(m_reader.read(data, size));
OX_RETURN_ERROR(m_reader.read(data.data(), size));
data[size] = 0;
} else {
auto data = *val;
@ -414,7 +416,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
}
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -423,15 +425,15 @@ constexpr Result<ArrayLength> MetalClawReaderTemplate<Reader>::arrayLength(const
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(g, m_reader.tellg());
oxRequire(out, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
OX_REQUIRE(g, m_reader.tellg());
OX_REQUIRE(out, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
if (!pass) {
oxReturnError(m_reader.seekg(g));
OX_RETURN_ERROR(m_reader.seekg(g));
}
return out;
}
}
return OxError(1);
return ox::Error(1);
}
template<Reader_c Reader>
@ -441,7 +443,7 @@ constexpr Result<StringLength> MetalClawReaderTemplate<Reader>::stringLength(con
// read the length
std::size_t bytesRead = 0;
auto len = mc::decodeInteger<StringLength>(m_reader, &bytesRead);
oxReturnError(m_reader.seekg(-static_cast<int64_t>(bytesRead), ox::ios_base::cur));
OX_RETURN_ERROR(m_reader.seekg(-static_cast<int64_t>(bytesRead), ox::ios_base::cur));
return len;
}
}
@ -455,14 +457,14 @@ constexpr Error MetalClawReaderTemplate<Reader>::readInteger(I *val) noexcept {
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
std::size_t bytesRead = 0;
auto const result = mc::decodeInteger<I>(m_reader, &bytesRead);
oxReturnError(result);
OX_RETURN_ERROR(result);
*val = result.value;
} else {
*val = 0;
}
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -472,20 +474,20 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, CB cb) noexc
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
// read the length
std::size_t bytesRead = 0;
oxRequire(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
OX_REQUIRE(len, mc::decodeInteger<ArrayLength>(m_reader, &bytesRead));
// read the list
auto reader = child("");
auto &handler = *reader.interface();
oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
OX_RETURN_ERROR(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
for (std::size_t i = 0; i < len; ++i) {
T val;
oxReturnError(handler.field("", &val));
oxReturnError(cb(i, &val));
OX_RETURN_ERROR(handler.field("", &val));
OX_RETURN_ERROR(cb(i, &val));
}
}
}
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Reader_c Reader>
@ -546,7 +548,7 @@ Error readMC(ox::BufferView buff, T &val) noexcept {
template<typename T>
Result<T> readMC(ox::BufferView buff) noexcept {
Result<T> val;
oxReturnError(readMC(buff, val.value));
OX_RETURN_ERROR(readMC(buff, val.value));
return val;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -62,47 +62,47 @@ struct TestStruct {
template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
oxReturnError(io->template setTypeInfo<TestUnion>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->fieldCString("CString", &obj->CString));
return OxError(0);
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->fieldCString("CString", &obj->CString));
return ox::Error(0);
}
oxModelBegin(TestStructNest)
oxModelField(Bool)
oxModelField(Int)
oxModelField(IString)
oxModelEnd()
OX_MODEL_BEGIN(TestStructNest)
OX_MODEL_FIELD(Bool)
OX_MODEL_FIELD(Int)
OX_MODEL_FIELD(IString)
OX_MODEL_END()
template<typename T>
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
oxReturnError(io->template setTypeInfo<TestStruct>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->field("Int1", &obj->Int1));
oxReturnError(io->field("Int2", &obj->Int2));
oxReturnError(io->field("Int3", &obj->Int3));
oxReturnError(io->field("Int4", &obj->Int4));
oxReturnError(io->field("Int5", &obj->Int5));
oxReturnError(io->field("Int6", &obj->Int6));
oxReturnError(io->field("Int7", &obj->Int7));
oxReturnError(io->field("Int8", &obj->Int8));
oxReturnError(io->field("unionIdx", &obj->unionIdx));
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
OX_RETURN_ERROR(io->field("unionIdx", &obj->unionIdx));
if constexpr(T::opType() == ox::OpType::Reflect) {
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, 0}));
} else {
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
}
oxReturnError(io->field("String", &obj->String));
oxReturnError(io->field("IString", &obj->IString));
oxReturnError(io->field("List", obj->List, 4));
oxReturnError(io->field("Vector", &obj->Vector));
oxReturnError(io->field("Vector2", &obj->Vector2));
oxReturnError(io->field("Map", &obj->Map));
oxReturnError(io->field("Struct", &obj->Struct));
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
return OxError(0);
OX_RETURN_ERROR(io->field("String", &obj->String));
OX_RETURN_ERROR(io->field("IString", &obj->IString));
OX_RETURN_ERROR(io->field("List", obj->List, 4));
OX_RETURN_ERROR(io->field("Vector", &obj->Vector));
OX_RETURN_ERROR(io->field("Vector2", &obj->Vector2));
OX_RETURN_ERROR(io->field("Map", &obj->Map));
OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
return ox::Error(0);
}
std::map<ox::StringView, ox::Error(*)()> tests = {
@ -114,9 +114,9 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
// doesn't segfault
ox::Array<char, 1024> buff;
TestStruct ts;
oxReturnError(ox::writeMC(buff.data(), buff.size(), ts));
oxReturnError(ox::writeMC(ts));
return OxError(0);
OX_RETURN_ERROR(ox::writeMC(buff.data(), buff.size(), ts));
OX_RETURN_ERROR(ox::writeMC(ts));
return ox::Error(0);
}
},
@ -176,7 +176,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Struct.Int == testOut.Struct.Int, "Struct.Int value mismatch");
oxAssert(testIn.Struct.IString == testOut.Struct.IString, "Struct.IString value mismatch");
oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch");
return OxError(0);
return ox::Error(0);
}
},
@ -189,28 +189,28 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
static constexpr auto check = [](McInt val, const ox::Vector<uint8_t, 9> &expected) {
if (val.length != expected.size()) {
std::cout << "val.length: " << val.length << ", expected: " << expected.size() << '\n';
return OxError(1);
return ox::Error(1);
}
for (std::size_t i = 0; i < expected.size(); i++) {
if (expected[i] != val.data[i]) {
std::cout << "decoded: " << static_cast<uint32_t>(val.data[i]) << ", expected: " << static_cast<uint32_t>(expected[i]) << '\n';
std::cout << "decoded: " << i << ": " << static_cast<uint32_t>(val.data[i]) << '\n';
return OxError(1);
return ox::Error(1);
}
}
return OxError(0);
return ox::Error(0);
};
constexpr auto check64 = [](McInt val, auto expected) {
if (val.length != 9) {
std::cout << "val.length: " << val.length << '\n';
return OxError(1);
return ox::Error(1);
}
ox::LittleEndian<decltype(expected)> decoded = *reinterpret_cast<decltype(expected)*>(&val.data[1]);
if (expected != decoded) {
std::cout << "decoded: " << decoded << ", expected: " << expected << '\n';
return OxError(1);
return ox::Error(1);
}
return OxError(0);
return ox::Error(0);
};
// signed positive
oxAssert(check(encodeInteger(int64_t(1)), {0b000'0001'0}), "Encode 1 fail");
@ -247,7 +247,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
// code deduplication
oxAssert(check64(encodeInteger(MaxValue<int64_t>), MaxValue<int64_t>), "Encode MaxValue<int64_t> fail");
oxAssert(check64(encodeInteger(MaxValue<uint64_t>), MaxValue<uint64_t>), "Encode MaxValue<uint64_t> fail");
return OxError(0);
return ox::Error(0);
}
},
@ -260,12 +260,12 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
using ox::mc::decodeInteger;
static constexpr auto check = [](auto val) {
auto result = decodeInteger<decltype(val)>(encodeInteger(val));
oxReturnError(result.error);
OX_RETURN_ERROR(result.error);
if (result.value != val) {
std::cout << "Bad value: " << result.value << ", expected: " << val << '\n';
return OxError(1);
return ox::Error(1);
}
return OxError(0);
return ox::Error(0);
};
oxAssert(check(uint32_t(14)), "Decode of 14 failed.");
oxAssert(check(int8_t(-1)), "Decode of -1 failed.");
@ -291,7 +291,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(check(0xffffffff), "Decode of 0xffffffff failed.");
oxAssert(check(0xffffffffffff), "Decode of 0xffffffffffff failed.");
oxAssert(check(0xffffffffffffffff), "Decode of U64 max failed.");
return OxError(0);
return ox::Error(0);
}
},
@ -319,7 +319,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn);
oxAssert(typeErr, "Descriptor write failed");
ox::ModelObject testOut;
oxReturnError(testOut.setType(type));
OX_RETURN_ERROR(testOut.setType(type));
oxAssert(ox::readMC(dataBuff, testOut), "Data read 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");
@ -344,7 +344,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testOutStructCopy.at("IString").unwrap()->get<ox::String>() == testIn.Struct.IString.c_str(), "testOut.Struct.IString (copy) failed");
oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
return OxError(0);
return ox::Error(0);
}
},
@ -371,7 +371,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
const auto [type, typeErr] = ox::buildTypeDef(typeStore, testIn);
oxAssert(typeErr, "Descriptor write failed");
ox::BufferReader br({dataBuff, dataBuffLen});
oxReturnError(ox::walkModel<ox::MetalClawReader>(type, br,
OX_RETURN_ERROR(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 {
//std::cout << f.fieldName.c_str() << '\n';
auto fieldName = f.fieldName.c_str();
@ -454,10 +454,10 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
case ox::PrimitiveType::Union:
break;
}
return OxError(0);
return ox::Error(0);
}
));
return OxError(0);
return ox::Error(0);
}
},
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -117,12 +117,12 @@ class MetalClawWriter {
bool fieldSet = false;
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
auto mi = mc::encodeInteger(val);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length));
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
fieldSet = true;
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return OxError(0);
return ox::Error(0);
}
};
@ -181,10 +181,10 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const uint64_t *val)
template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::field(const char*, const bool *val) noexcept {
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), *val));
}
++m_field;
return OxError(0);
return ox::Error(0);
}
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)) {
// write the length
const auto strLen = mc::encodeInteger(val->len());
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
// write the string
oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
OX_RETURN_ERROR(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
fieldSet = true;
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Writer_c Writer>
@ -217,14 +217,14 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *c
const auto strLen = *val ? ox::strlen(*val) : 0;
// write the length
const auto strLenBuff = mc::encodeInteger(strLen);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
// write the string
oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
OX_RETURN_ERROR(m_writer.write(*val, static_cast<std::size_t>(strLen)));
fieldSet = true;
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Writer_c Writer>
@ -243,14 +243,14 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *v
if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length
const auto strLenBuff = mc::encodeInteger(strLen);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
// write the string
oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
OX_RETURN_ERROR(m_writer.write(val, static_cast<std::size_t>(strLen)));
fieldSet = true;
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Writer_c Writer>
@ -264,11 +264,11 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val) noexce
auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface<MetalClawWriter<Writer>> handler{&writer};
oxReturnError(model(&handler, val));
oxReturnError(writer.finalize());
OX_RETURN_ERROR(model(&handler, val));
OX_RETURN_ERROR(writer.finalize());
fieldSet = writeIdx != m_writer.tellp();
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return {};
}
@ -282,11 +282,11 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, UnionView<U, force>
auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer, ox::Optional<int>(ox::in_place, val.idx()));
ModelHandlerInterface handler{&writer};
oxReturnError(model(&handler, val.get()));
oxReturnError(writer.finalize());
OX_RETURN_ERROR(model(&handler, val.get()));
OX_RETURN_ERROR(writer.finalize());
fieldSet = writeIdx != m_writer.tellp();
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return {};
}
@ -298,21 +298,23 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length
const auto arrLen = mc::encodeInteger(len);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
auto const writeIdx = m_writer.tellp();
MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface handler{&writer};
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
OX_RETURN_ERROR(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
// write the array
for (std::size_t i = 0; i < len; ++i) {
oxReturnError(handler.field("", &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field("", &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END
}
oxReturnError(writer.finalize());
OX_RETURN_ERROR(writer.finalize());
fieldSet = writeIdx != m_writer.tellp();
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Writer_c Writer>
@ -324,32 +326,32 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
// write the length
const auto arrLen = mc::encodeInteger(len);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
OX_RETURN_ERROR(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
// write map
MetalClawWriter<Writer> writer(m_writer);
ModelHandlerInterface handler{&writer};
// double len for both key and value
oxReturnError(handler.setTypeInfo("Map", 0, {}, len * 2));
OX_RETURN_ERROR(handler.setTypeInfo("Map", 0, {}, len * 2));
// 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 {
const auto keyLen = key.len();
auto wkey = ox_malloca(keyLen + 1, char, 0);
memcpy(wkey.get(), key.c_str(), keyLen + 1);
oxReturnError(handler.fieldCString("", wkey.get(), keyLen));
oxRequireM(value, val.at(key));
OX_RETURN_ERROR(handler.fieldCString("", wkey.get(), keyLen));
OX_REQUIRE_M(value, val.at(key));
return handler.field("", value);
};
// write the array
for (std::size_t i = 0; i < len; ++i) {
auto const&key = keys[i];
oxReturnError(loopBody(handler, key, *val));
OX_RETURN_ERROR(loopBody(handler, key, *val));
}
oxReturnError(writer.finalize());
OX_RETURN_ERROR(writer.finalize());
fieldSet = true;
}
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
OX_RETURN_ERROR(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
++m_field;
return OxError(0);
return ox::Error(0);
}
template<Writer_c Writer>
@ -360,7 +362,7 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
const Vector<String>&,
std::size_t fields) noexcept {
const auto fieldPresenceLen = (fields - 1) / 8 + 1;
oxReturnError(m_writer.write(nullptr, fieldPresenceLen));
OX_RETURN_ERROR(m_writer.write(nullptr, fieldPresenceLen));
m_presenceMapBuff.resize(fieldPresenceLen);
m_fieldPresence.setBuffer(m_presenceMapBuff.data(), m_presenceMapBuff.size());
m_fieldPresence.setFields(static_cast<int>(fields));
@ -370,33 +372,33 @@ constexpr ox::Error MetalClawWriter<Writer>::setTypeInfo(
template<Writer_c Writer>
ox::Error MetalClawWriter<Writer>::finalize() noexcept {
const auto end = m_writer.tellp();
oxReturnError(m_writer.seekp(m_writerBeginP));
oxReturnError(m_writer.write(
OX_RETURN_ERROR(m_writer.seekp(m_writerBeginP));
OX_RETURN_ERROR(m_writer.write(
reinterpret_cast<const char*>(m_presenceMapBuff.data()),
m_presenceMapBuff.size()));
oxReturnError(m_writer.seekp(end));
OX_RETURN_ERROR(m_writer.seekp(end));
return {};
}
Result<Buffer> writeMC(Writer_c auto &writer, const auto &val) noexcept {
MetalClawWriter mcWriter(writer);
ModelHandlerInterface handler{&mcWriter};
oxReturnError(model(&handler, &val));
oxReturnError(mcWriter.finalize());
OX_RETURN_ERROR(model(&handler, &val));
OX_RETURN_ERROR(mcWriter.finalize());
return {};
}
Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB) noexcept {
Buffer buff(buffReserveSz);
BufferWriter bw(&buff, 0);
oxReturnError(writeMC(bw, val));
OX_RETURN_ERROR(writeMC(bw, val));
buff.resize(bw.tellp());
return buff;
}
Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
CharBuffWriter bw(buff, buffLen);
oxReturnError(writeMC(bw, val));
CharBuffWriter bw{{buff, buffLen}};
OX_RETURN_ERROR(writeMC(bw, val));
if (sizeOut) {
*sizeOut = bw.tellp();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -11,9 +11,9 @@
#include <ox/std/concepts.hpp>
// oxModelFwdDecl is necessary because Apple-Clang is broken...
#define oxModelFwdDecl(modelName) constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
#define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { oxReturnError(io->template setTypeInfo<modelName>());
#define oxModelEnd() return OxError(0); }
#define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
#define oxModelFieldRename(objFieldName, serFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
#define oxModelFriend(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept
#define OX_MODEL_FWD_DECL(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 OX_MODEL_END() return ox::Error(0); }
#define OX_MODEL_FIELD(fieldName) OX_RETURN_ERROR(io->field(#fieldName, &o->fieldName));
#define OX_MODEL_FIELD_RENAME(objFieldName, serFieldName) OX_RETURN_ERROR(io->field(#serFieldName, &o->objFieldName));
#define OX_MODEL_FRIEND(modelName) friend constexpr ox::Error model(auto *io, ox::CommonPtrWith<modelName> auto *o) noexcept

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -76,21 +76,21 @@ struct Subscript {
template<typename T>
constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
oxReturnError(io->template setTypeInfo<Subscript>());
OX_RETURN_ERROR(io->template setTypeInfo<Subscript>());
if constexpr(T::opType() == OpType::Reflect) {
uint32_t st = 0;
oxReturnError(io->field("subscriptType", &st));
OX_RETURN_ERROR(io->field("subscriptType", &st));
} else if constexpr(T::opType() == OpType::Write) {
auto pt = type ? static_cast<uint8_t>(type->subscriptType) : 0;
oxReturnError(io->field("subscriptType", &pt));
OX_RETURN_ERROR(io->field("subscriptType", &pt));
} else {
auto pt = type ? static_cast<uint32_t>(type->subscriptType) : 0;
oxReturnError(io->field("subscriptType", &pt));
OX_RETURN_ERROR(io->field("subscriptType", &pt));
type->subscriptType = static_cast<Subscript::SubscriptType>(pt);
}
oxReturnError(io->field("length", &type->length));
oxReturnError(io->field("smallSzLen", &type->smallSzLen));
return OxError(0);
OX_RETURN_ERROR(io->field("length", &type->length));
OX_RETURN_ERROR(io->field("smallSzLen", &type->smallSzLen));
return {};
}
using SubscriptStack = Vector<Subscript, 3>;
@ -119,6 +119,7 @@ struct DescriptorField {
subscriptLevels(pSubscriptLevels),
subscriptStack(std::move(pSubscriptType)),
typeId(std::move(pTypeId)) {
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "Subscript level mismatch");
}
constexpr DescriptorField(const DescriptorField &other) noexcept:
@ -184,38 +185,38 @@ constexpr auto buildTypeId(const DescriptorType &t) noexcept {
template<typename T>
constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept {
oxReturnError(io->template setTypeInfo<DescriptorType>());
oxReturnError(io->field("typeName", &type->typeName));
oxReturnError(io->field("typeVersion", &type->typeVersion));
OX_RETURN_ERROR(io->template setTypeInfo<DescriptorType>());
OX_RETURN_ERROR(io->field("typeName", &type->typeName));
OX_RETURN_ERROR(io->field("typeVersion", &type->typeVersion));
if constexpr(T::opType() == OpType::Reflect) {
uint8_t pt = 0;
oxReturnError(io->field("primitiveType", &pt));
OX_RETURN_ERROR(io->field("primitiveType", &pt));
} else if constexpr(T::opType() == OpType::Write) {
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
oxReturnError(io->field("primitiveType", &pt));
OX_RETURN_ERROR(io->field("primitiveType", &pt));
} else {
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
oxReturnError(io->field("primitiveType", &pt));
OX_RETURN_ERROR(io->field("primitiveType", &pt));
type->primitiveType = static_cast<PrimitiveType>(pt);
}
oxReturnError(io->field("typeParams", &type->typeParams));
oxReturnError(io->field("fieldList", &type->fieldList));
oxReturnError(io->field("length", &type->length));
oxReturnError(io->field("preloadable", &type->preloadable));
return OxError(0);
OX_RETURN_ERROR(io->field("typeParams", &type->typeParams));
OX_RETURN_ERROR(io->field("fieldList", &type->fieldList));
OX_RETURN_ERROR(io->field("length", &type->length));
OX_RETURN_ERROR(io->field("preloadable", &type->preloadable));
return {};
}
template<typename T>
constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcept {
oxReturnError(io->template setTypeInfo<DescriptorField>());
oxReturnError(io->field("typeId", &field->typeId));
oxReturnError(io->field("fieldName", &field->fieldName));
oxReturnError(io->field("subscriptLevels", &field->subscriptLevels));
oxReturnError(io->field("subscriptStack", &field->subscriptStack));
OX_RETURN_ERROR(io->template setTypeInfo<DescriptorField>());
OX_RETURN_ERROR(io->field("typeId", &field->typeId));
OX_RETURN_ERROR(io->field("fieldName", &field->fieldName));
OX_RETURN_ERROR(io->field("subscriptLevels", &field->subscriptLevels));
OX_RETURN_ERROR(io->field("subscriptStack", &field->subscriptStack));
// defaultValue is unused now, but leave placeholder for backwards compatibility
int defaultValue = 0;
oxReturnError(io->field("defaultValue", &defaultValue));
return OxError(0);
OX_RETURN_ERROR(io->field("defaultValue", &defaultValue));
return {};
}
template<typename ReaderBase>
@ -243,7 +244,7 @@ constexpr Error model(TypeDescReader<T> *io, CommonPtrWith<DescriptorField> auto
// defaultValue is unused now, but placeholder for backwards compatibility
int defaultValue = 0;
oxReturnError(io->field("defaultValue", &defaultValue));
return OxError(0);
return ox::Error(0);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -97,8 +97,14 @@ class TypeDescWriter {
std::size_t fields = ModelFieldCount_v<T>) noexcept;
template<typename T>
constexpr Error field(StringViewCR name, const T *val, std::size_t valLen,
const SubscriptStack &subscriptStack = {}) noexcept;
constexpr Error field(
StringViewCR name,
T const*val,
std::size_t valLen,
SubscriptStack const&subscriptStack) noexcept;
template<typename T>
constexpr Error field(StringViewCR name, T const*val, std::size_t valLen) noexcept;
template<typename T, bool force>
constexpr Error field(StringViewCR name, UnionView<T, force> val) noexcept;
@ -193,15 +199,30 @@ constexpr ox::Error TypeDescWriter::setTypeInfo(
// array handler
template<typename T>
constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept {
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t, SubscriptStack const&subscriptStack) noexcept {
if (m_type) {
constexpr typename remove_pointer<T>::type *p = nullptr;
const auto t = type(p);
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));
return OxError(0);
return ox::Error(0);
}
return OxError(1);
return ox::Error(1);
}
// array handler
template<typename T>
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t) noexcept {
if (m_type) {
constexpr typename remove_pointer<T>::type *p = nullptr;
const auto t = type(p);
oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
auto const lvls = detail::indirectionLevels_v<T> + 1;
SubscriptStack subscriptStack{lvls};
m_type->fieldList.emplace_back(t, String(name), lvls, subscriptStack, buildTypeId(*t));
return ox::Error(0);
}
return ox::Error(1);
}
template<typename T, bool force>
@ -210,9 +231,9 @@ constexpr Error TypeDescWriter::field(StringViewCR name, UnionView<T, force> val
const auto t = type(val);
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));
return OxError(0);
return ox::Error(0);
}
return OxError(1);
return ox::Error(1);
}
template<typename T>
@ -233,7 +254,7 @@ constexpr Error TypeDescWriter::field(StringViewCR name, const T *val) noexcept
return {};
}
}
return OxError(1);
return ox::Error(1);
}
template<typename ...Args>
@ -363,11 +384,11 @@ constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore) noexcept {
if (std::is_constant_evaluated()) {
std::allocator<T> a;
T *t = a.allocate(1);
oxReturnError(model(&handler, t));
OX_RETURN_ERROR(model(&handler, t));
a.deallocate(t, 1);
} else {
auto t = ox_malloca(sizeof(T), T);
oxReturnError(model(&handler, t.get()));
OX_RETURN_ERROR(model(&handler, t.get()));
}
return writer.definition();
}
@ -376,7 +397,7 @@ template<typename T>
constexpr Result<DescriptorType*> buildTypeDef(TypeStore &typeStore, T &val) noexcept {
TypeDescWriter writer(&typeStore);
ModelHandlerInterface<TypeDescWriter, ox::OpType::Reflect> handler(&writer);
oxReturnError(model(&handler, &val));
OX_RETURN_ERROR(model(&handler, &val));
return writer.definition();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -31,25 +31,25 @@ class FieldCounter {
template<typename U>
constexpr ox::Error field(StringViewCR, U) noexcept {
++fields;
return OxError(0);
return ox::Error(0);
}
template<typename U>
constexpr ox::Error field(StringViewCR, U, std::size_t) noexcept {
++fields;
return OxError(0);
return ox::Error(0);
}
template<typename U, typename Handler>
constexpr Error field(StringViewCR, Handler) {
++fields;
return OxError(0);
return ox::Error(0);
}
template<typename ...Args>
constexpr Error fieldCString(Args&&...) noexcept {
++fields;
return OxError(0);
return ox::Error(0);
}
static constexpr auto opType() noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -135,8 +135,8 @@ class ModelHandlerInterface {
return m_handler->field(name, &v->template get<ModelValueArray>());
}
oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type()));
oxPanic(OxError(1), "invalid type");
return OxError(1, "invalid type");
oxPanic(ox::Error(1), "invalid type");
return ox::Error(1, "invalid type");
}
// array handler, with callback to allow handling individual elements

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -56,19 +56,19 @@ class MemberList {
template<typename T>
constexpr Error field(const char*, T *v) noexcept {
vars[m_i++] = static_cast<void*>(v);
return OxError(0);
return ox::Error(0);
}
template<typename T>
constexpr Error field(const char*, T *v, int) noexcept {
vars[m_i++] = static_cast<void*>(v);
return OxError(0);
return ox::Error(0);
}
template<typename U, bool force = false>
constexpr Error field(const char*, UnionView<U, force> u) noexcept {
vars[m_i++] = static_cast<void*>(u.get());
return OxError(0);
return ox::Error(0);
}
template<typename T>
@ -107,7 +107,7 @@ class Copier {
auto &dst = *cbit_cast<FT*>(m_dst->vars[m_i]);
dst = src;
++m_i;
return OxError(0);
return ox::Error(0);
}
}
@ -119,7 +119,7 @@ class Copier {
dst = src;
}
++m_i;
return OxError(0);
return ox::Error(0);
}
template<typename U, bool force = false>
@ -128,7 +128,7 @@ class Copier {
auto &src = *u.get();
dst = src;
++m_i;
return OxError(0);
return ox::Error(0);
}
template<typename T = void>
@ -168,7 +168,7 @@ class Mover {
dst = std::move(src);
src = FT{};
++m_i;
return OxError(0);
return ox::Error(0);
}
}
@ -181,7 +181,7 @@ class Mover {
src = FT{};
}
++m_i;
return OxError(0);
return ox::Error(0);
}
template<typename U, bool force = false>
@ -190,7 +190,7 @@ class Mover {
auto &src = *u.get();
dst = std::move(src);
++m_i;
return OxError(0);
return ox::Error(0);
}
template<typename T = void>
@ -228,10 +228,10 @@ class Equals {
const auto &dst = std::bit_cast<FT>(*m_other->vars[m_i]);
++m_i;
if (dst == src) {
return OxError(0);
return ox::Error(0);
} else {
this->value = false;
return OxError(1);
return ox::Error(1);
}
}
@ -242,11 +242,11 @@ class Equals {
const auto &dst = cbit_cast<FT*>(m_other->vars[m_i])[i];
if (!(dst == src)) {
this->value = false;
return OxError(1);
return ox::Error(1);
}
}
++m_i;
return OxError(0);
return ox::Error(0);
}
template<typename U, bool force = false>
@ -255,10 +255,10 @@ class Equals {
const auto &src = *u.get();
++m_i;
if (dst == src) {
return OxError(0);
return ox::Error(0);
} else {
this->value = false;
return OxError(1);
return ox::Error(1);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -12,12 +12,12 @@ namespace ox {
static_assert([]() -> ox::Error {
ox::ModelValue v;
oxReturnError(v.setType<int32_t>());
OX_RETURN_ERROR(v.setType<int32_t>());
if (v.type() != ModelValue::Type::SignedInteger32) {
return OxError(1, "type is wrong");
return ox::Error(1, "type is wrong");
}
//oxReturnError(v.set<int32_t>(5));
return {};
}() == OxError(0));
}() == ox::Error(0));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -168,7 +168,7 @@ class ModelValue {
constexpr const auto &get() const noexcept {
constexpr auto type = getType<T>();
if (m_type != type) [[unlikely]] {
oxPanic(OxError(1), "invalid cast");
oxPanic(ox::Error(1), "invalid cast");
}
return getValue<type>(*this);
}
@ -178,7 +178,7 @@ class ModelValue {
constexpr auto &get() noexcept {
constexpr auto type = getType<T>();
if (m_type != type) [[unlikely]] {
oxPanic(OxError(1), "invalid cast");
oxPanic(ox::Error(1), "invalid cast");
}
return getValue<type>(*this);
}
@ -188,8 +188,8 @@ class ModelValue {
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels = 0,
SubscriptStack const& = {}) noexcept;
SubscriptStack const& = {},
int subscriptLevels = 0) noexcept;
template<typename T>
constexpr Error setType() noexcept;
@ -242,7 +242,7 @@ class ModelValueArray {
m_vec.resize(sz);
if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) {
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
OX_RETURN_ERROR(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
}
}
return {};
@ -276,8 +276,9 @@ class ModelValueArray {
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
SubscriptStack subscriptStack,
int subscriptLevels) noexcept {
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
@ -400,7 +401,7 @@ class ModelValueVector {
m_vec.resize(sz);
if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) {
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
OX_RETURN_ERROR(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
}
}
return {};
@ -418,8 +419,9 @@ class ModelValueVector {
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
SubscriptStack subscriptStack,
int subscriptLevels) noexcept {
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
@ -517,7 +519,7 @@ class ModelObject {
ModelValue value;
};
protected:
oxModelFriend(ModelObject);
OX_MODEL_FRIEND(ModelObject);
friend ModelValue;
Vector<UniquePtr<Field>> m_fieldsOrder;
HashMap<String, ModelValue*> m_fields;
@ -632,18 +634,18 @@ class ModelObject {
if (m_fields.contains(k)) {
return *m_fields.at(k).value;
}
return OxError(1);
return ox::Error(1);
}
template<typename T>
constexpr Error set(const String &k, T &&val) noexcept {
oxRequire(t, m_fields.at(k));
OX_REQUIRE(t, m_fields.at(k));
*t = ox::forward<T>(val);
return {};
}
constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
oxRequire(v, m_fields.at(k));
OX_REQUIRE(v, m_fields.at(k));
return *v;
}
@ -668,17 +670,17 @@ class ModelObject {
constexpr Error setType(const DescriptorType *type) noexcept {
if (type->primitiveType != PrimitiveType::Struct && type->primitiveType != PrimitiveType::Union) {
return OxError(1, "Cannot load a non-struct type to ModelObject");
return ox::Error(1, "Cannot load a non-struct type to ModelObject");
}
m_type = type;
for (const auto &f : type->fieldList) {
auto field = make_unique<Field>();
field->name = f.fieldName;
oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
OX_RETURN_ERROR(field->value.setType(f.type, f.subscriptStack, f.subscriptLevels));
m_fields[field->name] = &field->value;
m_fieldsOrder.emplace_back(std::move(field));
}
return OxError(0);
return {};
}
};
@ -720,7 +722,7 @@ class ModelUnion {
static constexpr Result<UniquePtr<ModelUnion>> make(const DescriptorType *type) noexcept {
UniquePtr<ModelUnion> out(new ModelUnion);
oxReturnError(out->setType(type));
OX_RETURN_ERROR(out->setType(type));
return out;
}
@ -729,7 +731,7 @@ class ModelUnion {
}
constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
oxRequire(v, m_fields.at(k));
OX_REQUIRE(v, m_fields.at(k));
return &(*v)->value;
}
@ -761,7 +763,7 @@ class ModelUnion {
[[nodiscard]]
constexpr Result<const ModelValue*> get(StringView const&k) const noexcept {
oxRequire(t, m_fields.at(k));
OX_REQUIRE(t, m_fields.at(k));
return &(*t)->value;
}
@ -788,7 +790,7 @@ class ModelUnion {
constexpr Error setType(const DescriptorType *type) noexcept {
if (type->primitiveType != PrimitiveType::Struct && type->primitiveType != PrimitiveType::Union) {
return OxError(1, "Cannot load a non-struct type to ModelUnion");
return ox::Error(1, "Cannot load a non-struct type to ModelUnion");
}
m_fields.clear();
m_fieldsOrder.clear();
@ -797,12 +799,12 @@ class ModelUnion {
auto field = make_unique<Field>();
field->name = f.fieldName;
field->idx = i;
oxReturnError(field->value.setType(f.type, f.subscriptLevels));
OX_RETURN_ERROR(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels));
m_fields[field->name] = field.get();
m_fieldsOrder.emplace_back(std::move(field));
++i;
}
return OxError(0);
return {};
}
[[nodiscard]]
@ -965,21 +967,21 @@ constexpr std::size_t alignOf(const ModelValue &t) noexcept {
}
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelObject>(
OX_RETURN_ERROR(h->template setTypeInfo<ModelObject>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value));
OX_RETURN_ERROR(h->field(f->name.c_str(), &f->value));
}
return OxError(0);
return ox::Error(0);
}
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelUnion>(
OX_RETURN_ERROR(h->template setTypeInfo<ModelUnion>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value));
OX_RETURN_ERROR(h->field(f->name.c_str(), &f->value));
}
return OxError(0);
return ox::Error(0);
}
constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
@ -1076,20 +1078,21 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
constexpr Error ModelValue::setType(
const DescriptorType *type,
int subscriptLevels,
SubscriptStack const&subscriptStack) noexcept {
SubscriptStack const&subscriptStack,
int subscriptLevels) noexcept {
freeResources();
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
if (subscriptLevels) {
auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
m_type = Type::InlineArray;
m_data.array = new ModelValueArray;
oxReturnError(m_data.array->setType(type, subscriptLevels - 1, subscriptStack));
oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
OX_RETURN_ERROR(m_data.array->setType(type, subscriptStack, subscriptLevels - 1));
OX_RETURN_ERROR(m_data.array->setSize(static_cast<size_t>(subscript.length)));
} else {
m_type = Type::Vector;
m_data.vec = new ModelValueVector;
oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
OX_RETURN_ERROR(m_data.vec->setType(type, subscriptStack, subscriptLevels - 1));
}
return {};
} else if (type->typeName == types::Bool) {
@ -1118,15 +1121,15 @@ constexpr Error ModelValue::setType(
} else if (type->primitiveType == PrimitiveType::Struct) {
m_type = Type::Object;
m_data.obj = new ModelObject;
oxReturnError(m_data.obj->setType(type));
OX_RETURN_ERROR(m_data.obj->setType(type));
} else if (type->primitiveType == PrimitiveType::Union) {
m_type = Type::Union;
oxRequireM(u, ModelUnion::make(type));
OX_REQUIRE_M(u, ModelUnion::make(type));
m_data.uni = u.release();
oxReturnError(m_data.uni->setType(type));
OX_RETURN_ERROR(m_data.uni->setType(type));
}
oxAssert(m_type != Type::Undefined, "No type set");
return OxError(0);
return ox::Error(0);
}
template<typename T>
@ -1138,11 +1141,11 @@ constexpr Error ModelValue::setType() noexcept {
// rather than using getValue<type>()
if constexpr(type == Type::Object) {
m_data.obj = new ModelObject;
oxReturnError(m_data.obj->setType(type));
OX_RETURN_ERROR(m_data.obj->setType(type));
} else if constexpr(type == Type::Union) {
oxRequireM(u, ModelUnion::make(type));
OX_REQUIRE_M(u, ModelUnion::make(type));
m_data.uni = u.release();
oxReturnError(m_data.uni->setType(type));
OX_RETURN_ERROR(m_data.uni->setType(type));
} else if constexpr(type == Type::String) {
m_data.str = new String;
} else if constexpr(type == Type::Vector) {
@ -1173,7 +1176,7 @@ template<typename T>
constexpr Error ModelValue::set(const T &v) noexcept {
constexpr auto type = getType<T>();
if (m_type != type) [[unlikely]] {
return OxError(1, "type mismatch");
return ox::Error(1, "type mismatch");
}
auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object ||
@ -1181,14 +1184,14 @@ constexpr Error ModelValue::set(const T &v) noexcept {
safeDelete(&value);
}
value = v;
return OxError(0);
return ox::Error(0);
}
template<typename T>
constexpr Error ModelValue::set(T &&v) noexcept {
constexpr auto type = getType<T>();
if (m_type != type) [[unlikely]] {
return OxError(1, "type mismatch");
return ox::Error(1, "type mismatch");
}
auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object ||
@ -1196,7 +1199,7 @@ constexpr Error ModelValue::set(T &&v) noexcept {
safeDelete(&value);
}
value = std::move(v);
return OxError(0);
return ox::Error(0);
}
constexpr ModelValue &ModelValue::operator=(ModelValue &other) noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -17,8 +17,8 @@ struct TestType {
static constexpr auto TypeVersion = 1;
};
oxModelBegin(TestType)
oxModelEnd()
OX_MODEL_BEGIN(TestType)
OX_MODEL_END()
struct TestType2 {
};
@ -38,12 +38,12 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
"ModelValue",
[] {
ox::ModelValue v;
oxReturnError(v.setType<int32_t>());
OX_RETURN_ERROR(v.setType<int32_t>());
//v.m_type = ox::ModelValue::getType<int32_t>();
if (v.type() != ox::ModelValue::Type::SignedInteger32) {
return OxError(1, "type is wrong");
return ox::Error(1, "type is wrong");
}
oxReturnError(v.set<int32_t>(5));
OX_RETURN_ERROR(v.set<int32_t>(5));
return ox::Error{};
}
},

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -38,17 +38,17 @@ struct TypeNameCatcher {
template<typename T>
constexpr Error field(const char*, T*, std::size_t) noexcept {
return OxError(0);
return ox::Error(0);
}
template<typename T>
constexpr Error field(const char*, T) noexcept {
return OxError(0);
return ox::Error(0);
}
template<typename ...Args>
constexpr Error fieldCString(Args&&...) noexcept {
return OxError(0);
return ox::Error(0);
}
static constexpr auto opType() noexcept {
@ -77,17 +77,17 @@ struct TypeInfoCatcher {
template<typename T>
constexpr Error field(const char*, T*, std::size_t) noexcept {
return OxError(0);
return ox::Error(0);
}
template<typename T>
constexpr Error field(const char*, T) noexcept {
return OxError(0);
return ox::Error(0);
}
template<typename T>
constexpr Error fieldCString(const char*, T) noexcept {
return OxError(0);
return ox::Error(0);
}
static constexpr auto opType() noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -31,7 +31,7 @@ class TypeStore {
constexpr Result<const DescriptorType*> get(const auto &name, int typeVersion,
const TypeParamPack &typeParams) const noexcept {
const auto typeId = buildTypeId(name, typeVersion, typeParams);
oxRequire(out, m_cache.at(typeId));
OX_REQUIRE(out, m_cache.at(typeId));
return out->get();
}
@ -40,7 +40,7 @@ class TypeStore {
constexpr auto typeName = ModelTypeName_v<T>;
constexpr auto typeVersion = ModelTypeVersion_v<T>;
const auto typeId = buildTypeId(typeName, typeVersion, {});
oxRequire(out, m_cache.at(typeId));
OX_REQUIRE(out, m_cache.at(typeId));
return out->get();
}
@ -56,15 +56,15 @@ class TypeStore {
auto [val, err] = m_cache.at(typeId);
if (err) {
if (!std::is_constant_evaluated()) {
oxRequireM(dt, loadDescriptor(typeId));
OX_REQUIRE_M(dt, loadDescriptor(typeId));
for (auto &f : dt->fieldList) {
oxReturnError(this->getLoad(f.typeId).moveTo(f.type));
OX_RETURN_ERROR(this->getLoad(f.typeId).moveTo(f.type));
}
auto &out = m_cache[typeId];
out = std::move(dt);
return out.get();
} else {
return OxError(1, "Type not available");
return ox::Error(1, "Type not available");
}
}
return val->get();
@ -102,7 +102,7 @@ class TypeStore {
protected:
virtual Result<UniquePtr<DescriptorType>> loadDescriptor(ox::StringView) noexcept {
return OxError(1);
return ox::Error(1);
}
Result<UniquePtr<DescriptorType>> loadDescriptor(ox::StringViewCR name, int version,

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -19,7 +19,7 @@ OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize)
Json::CharReaderBuilder parserBuilder;
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
throw OxException(1, "Could not parse JSON");
throw ox::Exception(1, "Could not parse JSON");
}
}
@ -27,7 +27,7 @@ OrganicClawReader::OrganicClawReader(const char *json, std::size_t jsonLen) {
Json::CharReaderBuilder parserBuilder;
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
throw OxException(1, "Could not parse JSON");
throw ox::Exception(1, "Could not parse JSON");
}
}
@ -37,7 +37,7 @@ OrganicClawReader::OrganicClawReader(Json::Value json, int unionIdx) noexcept:
}
Error OrganicClawReader::field(const char *key, bool *val) noexcept {
auto err = OxError(0);
auto err = ox::Error(0);
if (targetValid()) {
const auto &jv = value(key);
if (jv.empty()) {
@ -45,7 +45,7 @@ Error OrganicClawReader::field(const char *key, bool *val) noexcept {
} else if (jv.isBool()) {
*val = jv.asBool();
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -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 {
auto err = OxError(0);
auto err = ox::Error(0);
const char *begin = nullptr, *end = nullptr;
const auto &jv = value(key);
if (targetValid()) {
@ -67,13 +67,13 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu
const auto strSize = static_cast<std::size_t>(end - begin);
auto data = val;
if (strSize >= buffLen) {
err = OxError(2, "String size exceeds capacity of destination");
err = ox::Error(2, "String size exceeds capacity of destination");
} else {
ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0;
}
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -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 {
auto err = OxError(0);
auto err = ox::Error(0);
const char *begin = nullptr, *end = nullptr;
const auto &jv = value(key);
auto &data = *val;
@ -98,7 +98,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0;
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -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 {
auto err = OxError(0);
auto err = ox::Error(0);
const char *begin = nullptr, *end = nullptr;
const auto &jv = value(key);
if (targetValid()) {
@ -126,7 +126,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = nullptr;
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -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 {
UUIDStr str;
oxReturnError(field(key, &str));
OX_RETURN_ERROR(field(key, &str));
return UUID::fromString(str).moveTo(*val);
}
@ -147,7 +147,7 @@ Result<std::size_t> OrganicClawReader::arrayLength(const char *key, bool) noexce
if (jv.isArray()) {
return jv.size();
}
return OxError(1, "Type mismatch");
return ox::Error(1, "Type mismatch");
}
[[nodiscard]]
@ -161,7 +161,7 @@ std::size_t OrganicClawReader::stringLength(const char *key) noexcept {
jv.getString(&begin, &end);
return static_cast<std::size_t>(end - begin);
}
return OxError(1, "Type mismatch");
return ox::Error(1, "Type mismatch");
}
OrganicClawReader OrganicClawReader::child(const char *key, int unionIdx) noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -133,7 +133,7 @@ class OrganicClawReader {
template<typename T>
Error OrganicClawReader::field(const char *key, T *val) noexcept {
auto err = OxError(0);
auto err = ox::Error(0);
try {
if constexpr (is_integer_v<T>) {
if (targetValid()) {
@ -146,19 +146,19 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
} else if (rightType) {
*val = static_cast<T>(jv.asUInt());
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
} else if constexpr (isVector_v<T>) {
const auto&srcVal = value(key);
const auto srcSize = srcVal.size();
oxReturnError(ox::resizeVector(*val, srcSize));
OX_RETURN_ERROR(ox::resizeVector(*val, srcSize));
err = field(key, val->data(), val->size());
} else if constexpr (isArray_v<T>) {
const auto&srcVal = value(key);
const auto srcSize = srcVal.size();
if (srcSize > val->size()) {
err = OxError(1, "Input array is too long");
err = ox::Error(1, "Input array is too long");
} else {
err = field(key, val->data(), val->size());
}
@ -169,11 +169,11 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
ModelHandlerInterface handler(&reader);
err = model(&handler, val);
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
} catch (Json::LogicError const&) {
err = OxError(1, "error reading JSON data");
err = ox::Error(1, "error reading JSON data");
}
++m_fieldIt;
return err;
@ -181,7 +181,7 @@ Error OrganicClawReader::field(const char *key, T *val) noexcept {
template<typename U, bool force>
Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcept {
auto err = OxError(0);
auto err = ox::Error(0);
if (targetValid()) {
const auto &jv = value(key);
if (jv.empty() || jv.isObject()) {
@ -189,7 +189,7 @@ Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcep
ModelHandlerInterface handler(&reader);
err = model(&handler, val.get());
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -198,7 +198,7 @@ Error OrganicClawReader::field(const char *key, UnionView<U, force> val) noexcep
template<std::size_t L>
Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
auto err = OxError(0);
auto err = ox::Error(0);
if (targetValid()) {
const auto &jv = value(key);
if (jv.empty()) {
@ -206,7 +206,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
} else if (jv.isString()) {
*val = jv.asString().c_str();
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -215,7 +215,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
template<std::size_t L>
Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
auto err = OxError(0);
auto err = ox::Error(0);
if (targetValid()) {
const auto &jv = value(key);
if (jv.empty()) {
@ -223,7 +223,7 @@ Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
} else if (jv.isString()) {
*val = jv.asString().c_str();
} else {
err = OxError(1, "Type mismatch");
err = ox::Error(1, "Type mismatch");
}
}
++m_fieldIt;
@ -235,25 +235,27 @@ template<typename T>
Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noexcept {
const auto &srcVal = value(key);
if (!srcVal.isNull() && !srcVal.isArray()) {
return OxError(1, "Type mismatch");
return ox::Error(1, "Type mismatch");
}
auto srcSize = srcVal.size();
if (srcSize > valLen) {
return OxError(1);
return ox::Error(1);
}
OrganicClawReader r(srcVal);
ModelHandlerInterface handler{&r};
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
oxReturnError(handler.field("", &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field("", &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END
}
return OxError(0);
return ox::Error(0);
}
template<typename T>
Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcept {
const auto &srcVal = value(key);
if (!srcVal.isObject()) {
return OxError(1, "Type mismatch");
return ox::Error(1, "Type mismatch");
}
auto keys = srcVal.getMemberNames();
auto srcSize = srcVal.size();
@ -261,9 +263,9 @@ Error OrganicClawReader::field(const char *key, HashMap<String, T> *val) noexcep
ModelHandlerInterface handler{&r};
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
const auto k = keys[i].c_str();
oxReturnError(handler.field(k, &val->operator[](k)));
OX_RETURN_ERROR(handler.field(k, &val->operator[](k)));
}
return OxError(0);
return ox::Error(0);
}
Error readOC(BufferView buff, auto &val) noexcept {
@ -272,8 +274,10 @@ Error readOC(BufferView buff, auto &val) noexcept {
Json::Value doc;
Json::CharReaderBuilder parserBuilder;
auto parser = UniquePtr<Json::CharReader>(parserBuilder.newCharReader());
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) {
return OxError(1, "Could not parse JSON");
OX_ALLOW_UNSAFE_BUFFERS_END
return ox::Error(1, "Could not parse JSON");
}
OrganicClawReader reader(buff.data(), buff.size());
ModelHandlerInterface handler(&reader);
@ -281,14 +285,14 @@ Error readOC(BufferView buff, auto &val) noexcept {
} catch (const Error &err) {
return err;
} catch (...) {
return OxError(1, "Unknown Error");
return ox::Error(1, "Unknown Error");
}
}
template<typename T>
Result<T> readOC(BufferView buff) noexcept {
Result<T> val;
oxReturnError(readOC(buff, val.value));
OX_RETURN_ERROR(readOC(buff, val.value));
return val;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -74,45 +74,45 @@ struct TestStruct {
};
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
oxReturnError(io->template setTypeInfo<TestUnion>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->fieldCString("String", &obj->String));
return OxError(0);
OX_RETURN_ERROR(io->template setTypeInfo<TestUnion>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->fieldCString("String", &obj->String));
return ox::Error(0);
}
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStructNest> auto *obj) noexcept {
oxReturnError(io->template setTypeInfo<TestStructNest>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->field("String", &obj->String));
return OxError(0);
OX_RETURN_ERROR(io->template setTypeInfo<TestStructNest>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("String", &obj->String));
return ox::Error(0);
}
constexpr ox::Error model(auto *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
oxReturnError(io->template setTypeInfo<TestStruct>());
oxReturnError(io->field("Bool", &obj->Bool));
oxReturnError(io->field("Int", &obj->Int));
oxReturnError(io->field("Int1", &obj->Int1));
oxReturnError(io->field("Int2", &obj->Int2));
oxReturnError(io->field("Int3", &obj->Int3));
oxReturnError(io->field("Int4", &obj->Int4));
oxReturnError(io->field("Int5", &obj->Int5));
oxReturnError(io->field("Int6", &obj->Int6));
oxReturnError(io->field("Int7", &obj->Int7));
oxReturnError(io->field("Int8", &obj->Int8));
oxReturnError(io->field("unionIdx", &obj->unionIdx));
OX_RETURN_ERROR(io->template setTypeInfo<TestStruct>());
OX_RETURN_ERROR(io->field("Bool", &obj->Bool));
OX_RETURN_ERROR(io->field("Int", &obj->Int));
OX_RETURN_ERROR(io->field("Int1", &obj->Int1));
OX_RETURN_ERROR(io->field("Int2", &obj->Int2));
OX_RETURN_ERROR(io->field("Int3", &obj->Int3));
OX_RETURN_ERROR(io->field("Int4", &obj->Int4));
OX_RETURN_ERROR(io->field("Int5", &obj->Int5));
OX_RETURN_ERROR(io->field("Int6", &obj->Int6));
OX_RETURN_ERROR(io->field("Int7", &obj->Int7));
OX_RETURN_ERROR(io->field("Int8", &obj->Int8));
OX_RETURN_ERROR(io->field("unionIdx", &obj->unionIdx));
if (io->opType() == ox::OpType::Reflect) {
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, 0}));
} else {
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
OX_RETURN_ERROR(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
}
oxReturnError(io->field("String", &obj->String));
oxReturnError(io->field("List", obj->List, 4));
oxReturnError(io->field("Map", &obj->Map));
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
oxReturnError(io->field("Struct", &obj->Struct));
return OxError(0);
OX_RETURN_ERROR(io->field("String", &obj->String));
OX_RETURN_ERROR(io->field("List", obj->List, 4));
OX_RETURN_ERROR(io->field("Map", &obj->Map));
OX_RETURN_ERROR(io->field("EmptyStruct", &obj->EmptyStruct));
OX_RETURN_ERROR(io->field("Struct", &obj->Struct));
return ox::Error(0);
}
TestStruct::TestStruct(TestStruct &&other) noexcept {
@ -184,7 +184,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Struct.String == testOut.Struct.String, "Struct.String value mismatch");
oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch");
return OxError(0);
return ox::Error(0);
}
},
@ -210,7 +210,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
auto type = ox::buildTypeDef(typeStore, testIn);
oxAssert(type.error, "Descriptor write failed");
ox::ModelObject testOut;
oxReturnError(testOut.setType(type.value));
OX_RETURN_ERROR(testOut.setType(type.value));
oxAssert(ox::readOC(dataBuff, testOut), "Data read 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");
@ -234,7 +234,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testOutStructCopy.get("String").unwrap()->get<ox::String>() == testIn.Struct.String.c_str(), "testOut.Struct.String (copy) failed");
oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
return OxError(0);
return ox::Error(0);
}
},
@ -259,7 +259,7 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
ox::TypeStore typeStore;
auto type = ox::buildTypeDef(typeStore, testIn);
oxAssert(type.error, "Descriptor write failed");
oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(),
OX_RETURN_ERROR(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(),
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f,
ox::OrganicClawReader *rdr) -> ox::Error {
auto fieldName = f.fieldName.c_str();
@ -341,10 +341,10 @@ const std::map<ox::StringView, ox::Error(*)()> tests = {
case ox::PrimitiveType::Union:
break;
}
return OxError(0);
return ox::Error(0);
}
));
return OxError(0);
return ox::Error(0);
}
},
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -23,7 +23,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, in
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -42,7 +42,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(const char *key, const int16_t *val) noexcept {
@ -50,7 +50,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(const char *key, const int32_t *val) noexcept {
@ -58,7 +58,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(const char *key, const int64_t *val) noexcept {
@ -66,7 +66,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
@ -75,7 +75,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(const char *key, const uint16_t *val) noexcept {
@ -83,7 +83,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(const char *key, const uint32_t *val) noexcept {
@ -91,7 +91,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(const char *key, const uint64_t *val) noexcept {
@ -99,7 +99,7 @@ class OrganicClawWriter {
value(key) = *val;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error field(char const*key, bool const*val) noexcept {
@ -122,8 +122,8 @@ class OrganicClawWriter {
for (std::size_t i = 0; i < keys.size(); ++i) {
const auto k = keys[i].c_str();
if (k) [[likely]] {
oxRequireM(value, val->at(k));
oxReturnError(handler.field(k, value));
OX_REQUIRE_M(value, val->at(k));
OX_RETURN_ERROR(handler.field(k, value));
}
}
value(key) = w.m_json;
@ -147,7 +147,7 @@ class OrganicClawWriter {
value(key) = val->c_str();
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Error fieldCString(const char*, const char *const*val, int len) noexcept;
@ -200,12 +200,14 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n
OrganicClawWriter w((Json::Value(Json::arrayValue)));
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
for (std::size_t i = 0; i < len; ++i) {
oxReturnError(handler.field({}, &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
OX_RETURN_ERROR(handler.field({}, &val[i]));
OX_ALLOW_UNSAFE_BUFFERS_END
}
value(key) = w.m_json;
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
template<typename T>
@ -225,13 +227,13 @@ Error OrganicClawWriter::field(const char *key, const T *val) noexcept {
} else if (val && targetValid()) {
OrganicClawWriter w;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
oxReturnError(model(&handler, val));
OX_RETURN_ERROR(model(&handler, val));
if (!w.m_json.empty() || m_json.isArray()) {
value(key) = w.m_json;
}
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
template<typename U, bool force>
@ -239,19 +241,19 @@ Error OrganicClawWriter::field(const char *key, UnionView<U, force> val) noexcep
if (targetValid()) {
OrganicClawWriter w(val.idx());
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
oxReturnError(model(&handler, val.get()));
OX_RETURN_ERROR(model(&handler, val.get()));
if (!w.m_json.isNull()) {
value(key) = w.m_json;
}
}
++m_fieldIt;
return OxError(0);
return ox::Error(0);
}
Result<ox::Buffer> writeOC(const auto &val) noexcept {
OrganicClawWriter writer;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
oxReturnError(model(&handler, &val));
OX_RETURN_ERROR(model(&handler, &val));
Json::StreamWriterBuilder const jsonBuilder;
const auto str = Json::writeString(jsonBuilder, writer.m_json);
Result<Buffer> buff;
@ -263,7 +265,7 @@ Result<ox::Buffer> writeOC(const auto &val) noexcept {
Result<ox::String> writeOCString(const auto &val) noexcept {
OrganicClawWriter writer;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler(&writer);
oxReturnError(model(&handler, &val));
OX_RETURN_ERROR(model(&handler, &val));
Json::StreamWriterBuilder const jsonBuilder;
const auto str = Json::writeString(jsonBuilder, writer.m_json);
Result<ox::String> buff;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -63,7 +63,7 @@ struct AlignmentCatcher: public ModelHandlerBase<AlignmentCatcher<PlatSpec>, OpT
template<typename T>
constexpr ox::Error field(StringViewCR, const T *val, std::size_t cnt) noexcept {
for (std::size_t i = 0; i < cnt; ++i) {
oxReturnError(field(nullptr, &val[i]));
OX_RETURN_ERROR(field(nullptr, &val[i]));
}
return {};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -74,7 +74,7 @@ template<typename T, bool force>
constexpr ox::Error SizeCatcher<PlatSpec>::field(const char*, const UnionView<T, force> val) noexcept {
pad(val.get());
UnionSizeCatcher<PlatSpec> sc;
oxReturnError(model(sc.interface(), val.get()));
OX_RETURN_ERROR(model(sc.interface(), val.get()));
m_size += sc.size();
return {};
}
@ -91,7 +91,7 @@ template<typename PlatSpec>
template<typename T>
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) {
oxReturnError(field("", &val[i]));
OX_RETURN_ERROR(field("", &val[i]));
}
return {};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -43,7 +43,7 @@ class UnionSizeCatcher: public ModelHandlerBase<UnionSizeCatcher<PlatSpec>, OpTy
template<typename T, bool force>
constexpr ox::Error field(StringViewCR, const UnionView<T, force> val) noexcept {
UnionSizeCatcher<PlatSpec> sc;
oxReturnError(model(sc.interface(), val.get()));
OX_RETURN_ERROR(model(sc.interface(), val.get()));
m_size += sc.size();
return {};
}
@ -80,7 +80,7 @@ template<typename PlatSpec>
template<typename T>
constexpr ox::Error UnionSizeCatcher<PlatSpec>::field(StringViewCR, const T **val, std::size_t cnt) noexcept {
for (std::size_t i = 0; i < cnt; ++i) {
oxReturnError(field("", &val[i]));
OX_RETURN_ERROR(field("", &val[i]));
}
return {};
}

View File

@ -1,3 +1,9 @@
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
# enable warnings
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
endif()
if(OX_USE_STDLIB AND OX_ENABLE_TRACEHOOK)
add_library(
OxTraceHook SHARED
@ -103,6 +109,7 @@ install(
error.hpp
fmt.hpp
hardware.hpp
hash.hpp
hashmap.hpp
heapmgr.hpp
ignore.hpp

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -8,6 +8,10 @@
#pragma once
#include "def.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename It, typename T>
@ -40,4 +44,6 @@ constexpr OutIt copy_n(It in, Size cnt, OutIt out) {
return out;
}
}
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -9,6 +9,7 @@
#pragma once
#include "bit.hpp"
#include "def.hpp"
#include "error.hpp"
#include "initializerlist.hpp"
#include "iterator.hpp"
@ -17,6 +18,8 @@
#include "types.hpp"
#include "utility.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox {
template<typename T, std::size_t ArraySize>
@ -35,6 +38,10 @@ class Array {
public:
constexpr Array() noexcept = default;
template<typename ...Args>
constexpr Array(Args ...list) noexcept: m_items{std::move(list)...} {
}
constexpr Array(std::initializer_list<T> list) noexcept;
constexpr Array(const Array &other);
@ -174,11 +181,13 @@ constexpr Array<T, ArraySize> &Array<T, ArraySize>::operator=(Array &&other) noe
template<typename T, std::size_t ArraySize>
constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
return m_items[i];
}
template<typename T, std::size_t ArraySize>
constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
return m_items[i];
}
@ -198,3 +207,5 @@ constexpr bool Array<T, ArraySize>::contains(const T &v) const {
}
}
OX_CLANG_NOWARN_END

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -22,9 +22,9 @@
namespace ox {
void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = OxError(0)) noexcept;
void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = ox::Error(0)) noexcept;
constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = OxError(0)) noexcept {
constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err = ox::Error(0)) noexcept {
if (!std::is_constant_evaluated()) {
panic(file, line, panicMsg, err);
} else {
@ -32,19 +32,13 @@ constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg
}
}
void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept;
void assertFailFuncRuntime(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept;
constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused]]StringViewCR assertTxt, [[maybe_unused]]StringViewCR msg) noexcept {
if (!pass) {
if (!std::is_constant_evaluated()) {
#ifdef OX_USE_STDLIB
auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
output += genStackTrace(2);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
std::abort();
#else
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
constexprPanic(file, line, msg);
#endif
assertFailFuncRuntime(file, line, assertTxt, msg);
} else {
while (true);
}
@ -54,22 +48,7 @@ constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused
constexpr void assertFunc(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept {
if (err) {
if (!std::is_constant_evaluated()) {
#if defined(OX_USE_STDLIB)
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
if (err.msg) {
msg += sfmt("\tError Message:\t{}\n", err.msg);
}
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
if (err.file != nullptr) {
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
}
msg += genStackTrace(2);
oxErr(msg);
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
std::abort();
#else
constexprPanic(file, line, assertMsg);
#endif
assertFailFuncRuntime(file, line, err, {}, assertMsg);
} else {
while (true);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -9,9 +9,12 @@
#pragma once
#include "bit.hpp"
#include "def.hpp"
#include "cstrops.hpp"
#include "iterator.hpp"
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
namespace ox::detail {
class BaseStringView {
@ -202,7 +205,7 @@ class BaseStringView {
}
[[nodiscard]]
constexpr auto operator[](std::size_t i) const noexcept {
constexpr auto &operator[](std::size_t i) const noexcept {
return m_str[i];
}
@ -215,3 +218,5 @@ class BaseStringView {
};
}
OX_CLANG_NOWARN_END

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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
@ -126,11 +126,11 @@ constexpr void Bounds::set(const Point &pt1, const Point &pt2) noexcept {
template<typename T>
constexpr Error model(T *io, ox::CommonPtrWith<Bounds> auto *obj) noexcept {
oxReturnError(io->template setTypeInfo<Bounds>());
oxReturnError(io->field("x", &obj->x));
oxReturnError(io->field("y", &obj->y));
oxReturnError(io->field("width", &obj->width));
oxReturnError(io->field("height", &obj->height));
OX_RETURN_ERROR(io->template setTypeInfo<Bounds>());
OX_RETURN_ERROR(io->field("x", &obj->x));
OX_RETURN_ERROR(io->field("y", &obj->y));
OX_RETURN_ERROR(io->field("width", &obj->width));
OX_RETURN_ERROR(io->field("height", &obj->height));
return {};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2024 gary@drinkingtea.net
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* 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

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