Compare commits

...

133 Commits

Author SHA1 Message Date
4061b8314e [ox/model] Remove broken global var
All checks were successful
Build / build (push) Successful in 2m29s
2024-05-03 00:12:34 -05:00
18bb50626d [ox/std] Add String::append(StringView), cleanup
All checks were successful
Build / build (push) Successful in 2m30s
2024-05-03 00:07:03 -05:00
6a4b48221f [nostalgia,studio] Fixes for Ox changes 2024-05-03 00:00:05 -05:00
d2a3cfa72e [ox/std] Remove append operators from IString
This is because the append operators cannot report the failure that is possible with IString
2024-05-02 23:59:19 -05:00
7c4e2a6564 [ox/std] Cleanup IString 2024-05-02 23:33:39 -05:00
e30ebce4c0 [nostalgia] Add pyenv to .gitignore
All checks were successful
Build / build (push) Successful in 2m34s
2024-05-02 23:15:01 -05:00
7163947efd [ox/std] Cleanup 2024-05-02 23:14:03 -05:00
0a0a6e306d [studio] Move UndoCommand implementation to its own file 2024-05-02 22:50:25 -05:00
97bc9332d3 [nostalgia/core] Fix TileSheetV1 to use PaletteV1 2024-05-02 22:48:35 -05:00
9caf7099b6 [keel] Fix for Ox change 2024-05-02 22:21:04 -05:00
fda1280d29 [ox/std] Make substr always take and return a StringView 2024-05-02 22:20:25 -05:00
59aa4ad21a [cityhash] Cleanup 2024-05-02 22:20:01 -05:00
1a8afa1a98 [nostalgia/sample_project] Add missing type descriptor 2024-05-02 22:11:52 -05:00
cdbc2d6cc8 [olympic/studio] Move UndoCommand to its own file 2024-05-02 22:09:35 -05:00
acd93337d4 [ox/std] Fix Integer assignment operator return
All checks were successful
Build / build (push) Successful in 2m27s
2024-04-29 22:54:34 -05:00
cebd3b0a0f [ox/std] Fix Integer assignment operator return 2024-04-29 22:52:34 -05:00
43e2e2155b [ox/std] Cleanup 2024-04-29 22:48:22 -05:00
be1f90955b [ox/std] Make safeDelete constexpr
All checks were successful
Build / build (push) Successful in 2m32s
2024-04-29 22:43:27 -05:00
0f2c18d554 [ox/std] Add std::string(_view) variant of MaybeView
All checks were successful
Build / build (push) Successful in 2m29s
2024-04-25 23:03:38 -05:00
0c0ccd1a69 [nostalgia/core/studio] Cleanup scratchpad code
All checks were successful
Build / build (push) Successful in 2m32s
2024-04-24 23:09:50 -05:00
1b629da8fc [ox/std] Make Vector::contains always noexcept
All checks were successful
Build / build (push) Successful in 2m29s
2024-04-24 21:39:02 -05:00
32e4702dc7 [ox] Improve hasing and MaybeView
All checks were successful
Build / build (push) Successful in 2m29s
* Add CityHash dep
* Use CityHash for HashMap
* Make MaybeView more versatile
* Cleanup some inappropriate MaybeView uses
2024-04-24 20:59:37 -05:00
6b47133c22 [nostalgia] Cleanup StudioModules
All checks were successful
Build / build (push) Successful in 2m22s
2024-04-24 00:58:10 -05:00
0764720f9a [nostalgia,olympic] Update for Ox changes 2024-04-24 00:54:43 -05:00
78955376d6 [glutils] Update for Ox changes 2024-04-24 00:54:25 -05:00
a00a0bd2ff [ox] Rename BString to IString 2024-04-24 00:54:02 -05:00
ed4f0e1f2b [nostalgia,olympic] Replace oxIgnoreError with std::ignore 2024-04-22 23:43:22 -05:00
ea1feb726e [ox] Remove oxIgnoreError 2024-04-22 23:40:42 -05:00
e9a6a09629 [ox] Run liccor
All checks were successful
Build / build (push) Successful in 2m20s
2024-04-21 17:01:48 -05:00
d7f309750e Merge commit 'c0baf7efca0e4c3a86a018ad2564d9df7b07c133'
All checks were successful
Build / build (push) Successful in 2m22s
2024-04-21 13:13:26 -05:00
84205879d4 [olympic] Cleanup ItemMaker, remove unnecessary copy
All checks were successful
Build / build (push) Successful in 2m22s
2024-04-21 10:32:42 -05:00
ebf3a6961e [ox/std] Add String constructor that takes a StringLiteral 2024-04-21 10:31:26 -05:00
eeb2a5a151 [olympic/studio] Add new ImGui util functions 2024-04-21 10:24:53 -05:00
453f2750dd [nostalgia/core/studio] Cleanup context types 2024-04-21 10:24:29 -05:00
189ba4c545 [olympic/studio] Make studio::run static 2024-04-21 10:23:55 -05:00
057738088e [olympic] Change TypeId building to use constexpr globals 2024-04-21 10:23:22 -05:00
272eabc732 [nostalgia/core/opengl] Unbind vertex arrays when done with them 2024-04-21 10:22:32 -05:00
a02566697a [glutils] Remove trailing whitespace 2024-04-21 10:21:44 -05:00
dfd27afd67 [ox/std] Add implicit String constructor for str literals
All checks were successful
Build / build (push) Successful in 2m20s
Also make String more constexpr friendly
2024-04-18 23:59:47 -05:00
6bfe184261 [ox/std] Remove unnecessary copying from HashMap::expand
All checks were successful
Build / build (push) Successful in 2m21s
2024-04-18 23:39:33 -05:00
700d7016d5 [nostalgia] Update for Ox changes 2024-04-18 23:33:06 -05:00
922323833c [ox] Cleanup 2024-04-18 23:32:54 -05:00
3b8d13dce3 [nostalgia,olympic] Fixes for Ox update
All checks were successful
Build / build (push) Successful in 2m25s
2024-04-18 19:25:07 -05:00
a20d7fd923 [ox] Cleanup 2024-04-18 19:24:56 -05:00
6808adc8a1 [ox/std] Replace ox::ignore with std::ignore 2024-04-13 00:35:49 -05:00
abc076d657 [ox/std] Cleanup 2024-04-13 00:10:09 -05:00
1b790a34c4 [ox/std] Fix Signed_c and Unsigned_c 2024-04-13 00:07:40 -05:00
9220271630 [nostalgia/core] Update pack transforms to use ModelTypeId_v 2024-04-10 22:20:26 -05:00
7941a514ba [ox/model] Add constexpr ModelTypeId_v 2024-04-10 00:00:48 -05:00
0c09c5306e [ox/std] Fix sfmt constexpr problems 2024-04-09 23:47:18 -05:00
3ff91af86b [ox/std] Sort of fix custom assert 2024-04-09 23:46:54 -05:00
79b42e1df7 [ox/std] Fix some Vector constexpr problems 2024-04-09 23:46:12 -05:00
5eec9085f8 [ox/std] Add nodiscard to some string functions 2024-04-09 22:40:37 -05:00
af7c89564c [ox/std] Add ox::ignore 2024-04-09 22:40:20 -05:00
2c0e02277c [ox/std] Add assert to AnyPtr::Wrap::copyTo to ensure sufficiently large buff
All checks were successful
Build / build (push) Successful in 2m39s
2024-03-24 02:22:37 -05:00
e3c74637db [turbine] Make applicationData return const&
All checks were successful
Build / build (push) Successful in 2m35s
2024-03-23 17:19:33 -05:00
41e08d67aa [turbine] Make keyEventHandler nodiscard 2024-03-23 17:12:44 -05:00
50f3479d10 [ox/std] Make AnyPtr constexpr
All checks were successful
Build / build (push) Successful in 2m38s
2024-03-23 17:05:20 -05:00
1616ca7018 [turbine] Replace WrapPtr with ox::AnyPtr
All checks were successful
Build / build (push) Successful in 2m33s
2024-03-23 16:53:04 -05:00
3fa247e3d4 [ox/std] Add AnyPtr 2024-03-23 16:52:43 -05:00
27f1df8f33 [nostalgia,olympic] Further reduce use of applicationData 2024-03-23 16:07:49 -05:00
a4f0c7cdb5 [nostalgia/core/studio] Remove applicationData usages
All checks were successful
Build / build (push) Successful in 2m35s
2024-03-23 14:52:30 -05:00
6a52319156 [turbine] Cleanup applicationData
All checks were successful
Build / build (push) Successful in 2m38s
2024-03-17 20:59:14 -05:00
205f2a698c [turbine] Fix applicationData to properly return null 2024-03-17 20:05:01 -05:00
82f02896c9 [turbine] Cleanup type safety code for application data
All checks were successful
Build / build (push) Successful in 2m35s
2024-03-17 14:33:14 -05:00
aa43cb3d8d [turbine] Add some type safety to application data
All checks were successful
Build / build (push) Successful in 2m34s
2024-03-16 23:10:44 -05:00
05d08a7687 Merge commit 'd6403991d49292d4f2b7d441636949472ca2b249'
All checks were successful
Build / build (push) Successful in 2m22s
2024-03-14 23:33:20 -05:00
c6750d50fc [studio/modlib] Add ig::ChildStackItem 2024-03-14 23:32:05 -05:00
dade484d87 [olympic/studio] Make StudioContext::ui a ref instead of ptr 2024-03-14 23:31:01 -05:00
04f3d6b491 [keel] Fix some static const vars to be constexpr
All checks were successful
Build / build (push) Successful in 2m23s
2024-02-29 23:53:36 -06:00
b015fe88b7 [ox/std] Make ranges predicates const refs 2024-02-17 11:43:25 -06:00
db2dc28f92 [keel] Remove use of removed ModelValue operator
All checks were successful
Build / build (push) Successful in 2m24s
2024-02-11 20:35:48 -06:00
74fb051ef2 [ox] Remove panicing ModelValue operators 2024-02-11 20:35:19 -06:00
24fda7d589 [ox] Make serialize and allocate Writer_c functions take refs
All checks were successful
Build / build (push) Successful in 2m18s
2024-02-11 19:39:29 -06:00
a60cdf0a61 Merge commit '9c712cc38ae706b021807b271899bce56c234fa5' 2024-02-11 17:30:45 -06:00
b97d7d9956 [ox/preloader] Remove debug code
Some checks are pending
Build / build (push) Waiting to run
2024-02-11 17:29:54 -06:00
ce1eea817d [olympic/keel] Remove debug line 2024-02-11 17:28:19 -06:00
9a0a2fd46a Merge commit '56f9d7a4634c9de9b09df390c4385c67ab646607' 2024-02-11 17:24:22 -06:00
4e50889b5c [ox/model,ox/preloader] Add ability to handle inline arrays
Some checks are pending
Build / build (push) Waiting to run
2024-02-11 17:23:38 -06:00
9c0acf1b8f Merge commit 'ace68f7c1d870ed53e69c55ba53709a9425388be' 2024-02-04 10:21:12 -06:00
ee05118478 [ox] Add ability for ModelValue to represent inline arrays, add to preloader
Some checks failed
Build / build (push) Failing after 17s
2024-02-04 10:19:30 -06:00
a41e93c582 Merge commit '8e0467ca5fdb3f983738a97c17cba742a0d233fd' 2024-02-01 21:07:56 -06:00
59fa39070f [keel] Update pack for Preloader changes
All checks were successful
Build / build (push) Successful in 2m19s
2024-02-01 21:07:42 -06:00
c55994f67d [ox/std] Add Vector::capacity 2024-02-01 21:06:53 -06:00
e81d28a681 [ox] Fix various preloader problems 2024-02-01 21:06:35 -06:00
0626c2a815 [ox/fs] Add comparison operator for FileAddress 2024-02-01 21:02:46 -06:00
dbcd37d7ea Merge commit '0d61e5a064382a7076b62d32b25c70298ee0706e' 2024-01-31 23:18:13 -06:00
10a12f2ab2 [nostalgia/core] Add getTileCnt to header
All checks were successful
Build / build (push) Successful in 2m23s
2024-01-31 23:17:59 -06:00
2667be88f6 [nostalgia/core] Add largestPage function for Palette 2024-01-31 23:17:46 -06:00
5972d8acef [nostalgia/core] Fix TileSetEntry model 2024-01-31 23:17:28 -06:00
9c026e1a6c [nostalgia/core/studio] Add function to remove unused data from TileSheets 2024-01-31 23:17:09 -06:00
1dff26d895 [nostalgia/core] Add getTileCnt and fix getTileIdx 2024-01-31 23:16:41 -06:00
ff2eb5b11b [olympic/keel] Remove const r-value funcion from AssetRef 2024-01-31 23:15:53 -06:00
6a500345b4 Merge commit '057272347486efe5046691f32f51604e3a594e6a' 2024-01-31 23:13:34 -06:00
28b1c6dcf4 [ox/preloader] Fix case where alignOf always used NativePlatSpec
All checks were successful
Build / build (push) Successful in 2m21s
2024-01-31 23:07:40 -06:00
ef9cb8bea4 [olympic/modlib] Add ListBox to ImGui util 2024-01-30 21:46:38 -06:00
0d106bde21 [ox/oc] Fix objects to always write when members of arrays 2024-01-30 21:45:58 -06:00
f038b89ab4 Merge commit 'cfc27a384b00388fc1ce30ac47c266ddd1f8e6f1' 2024-01-28 18:05:09 -06:00
b75bbc4d20 [olympic,nostalgia] Change order of oxModelFieldRename args
All checks were successful
Build / build (push) Successful in 2m22s
2024-01-28 18:03:50 -06:00
227dd68a4f [ox/model] Change order of oxModelFieldRename args 2024-01-28 18:03:50 -06:00
02db760b8c [olympic] Add more ImGui helpers, studio::Editor::pushCommand 2024-01-28 18:03:12 -06:00
09c57545bc [ox/std] Add Vector::at
All checks were successful
Build / build (push) Successful in 2m22s
2024-01-28 16:29:39 -06:00
b9fddd47c2 Merge commit 'db978290f3465d2da30a27a98b12face50bbe091' 2024-01-27 23:55:20 -06:00
f128664a81 [olympic/studio] Add ig::IndentStackItem
All checks were successful
Build / build (push) Successful in 2m28s
2024-01-27 23:54:57 -06:00
e84df7801e [glutils] Add ProgramSource::vboLen 2024-01-27 23:53:32 -06:00
caa59f3724 [nostalgia/core] Add functions for mapping tile idx to subsheet 2024-01-27 23:52:40 -06:00
1cf09433e8 [nostalgia/core/studio] Cleanup TileSheetEditor with new GlUtils helpers 2024-01-27 23:51:51 -06:00
9948346ce4 [ox/model] Fix clangd false alarm 2024-01-27 23:40:16 -06:00
aa8200beed [glutils] Add helper functions for setting up shaders 2024-01-27 23:39:03 -06:00
961ab75662 Merge commit 'ae1f8ce11a81624f376be3a3dd56e80ba479dd89' 2024-01-20 15:41:04 -06:00
124c7029bd [olympic/studio] Change Studio modules to pass StudioContext instead of turbine::Context
All checks were successful
Build / build (push) Successful in 2m23s
2024-01-20 15:40:08 -06:00
d740609c8e Merge commit '6640e00ad9ee5b731a2ddb06da31436463c3ae65' 2024-01-20 15:02:16 -06:00
5d1f680a51 [nostalgia/core] Cleanup TileSheetEditor with new ImGui util functions
All checks were successful
Build / build (push) Successful in 2m21s
2024-01-20 14:59:43 -06:00
08be822bdd [ox/fs] Add FileAddress::operator==(FileAddress) 2024-01-19 20:22:52 -06:00
c2e34b6456 Merge commit 'a9128caf4ddd187f14496b84242dfe07ee9a6467'
All checks were successful
Build / build (push) Successful in 2m32s
2024-01-19 01:09:23 -06:00
173d3f4bc7 [olympic/studio] Add PushButton, PopupBtns, ComboBox, and IDStackItem to ImGui utils 2024-01-19 01:09:10 -06:00
8a29c0952c [olympic/studio] Fix imguiutil.hpp name, add StudioContext::tctx 2024-01-19 00:15:28 -06:00
5848bc8eb7 [nostalgia/core/studio] Change Subsheet Editor button position
All checks were successful
Build / build (push) Successful in 2m21s
2024-01-18 22:09:09 -06:00
7ba66787f8 [nostalgia/core/studio] Cleanup
All checks were successful
Build / build (push) Successful in 2m29s
2024-01-18 01:27:31 -06:00
e367575974 [olympic/studio] Fix NewMenu not to overwrite existing files or create a file without name
All checks were successful
Build / build (push) Successful in 2m30s
2024-01-18 00:24:11 -06:00
2bc2003caa [nostalgia/core/studio] Add key shortcuts for switching Palette pages
All checks were successful
Build / build (push) Successful in 2m22s
2024-01-17 22:48:53 -06:00
b31062e609 [nostalgia] Update liccor file 2024-01-17 22:36:09 -06:00
e4285bd48b [nostalgia/studio] Tweak background color of TileSheet editor
All checks were successful
Build / build (push) Successful in 2m20s
2024-01-17 22:23:22 -06:00
a76638cc86 [olympic/studio] Make Project::romFS return a reference 2024-01-17 22:08:22 -06:00
5433fd9b1d [nostalgia/core] Add new version of Palette with pages
All checks were successful
Build / build (push) Successful in 2m35s
2024-01-17 01:30:29 -06:00
b46cb65b7f [nostalgia/studio] Add version
All checks were successful
Build / build (push) Successful in 2m24s
2024-01-05 21:54:22 -06:00
877349df46 [nostalgia/core/studio] Increase max tilesheet export size, fix input handling when popups open 2024-01-04 22:47:57 -06:00
5418c06296 [olympic] Change olympic::s_version to olympic::appVersion
All checks were successful
Build / build (push) Successful in 2m17s
2024-01-01 14:14:16 -06:00
dd9c1100c3 [glutils] Update copyright for 2024
All checks were successful
Build / build (push) Successful in 2m16s
2024-01-01 12:06:57 -06:00
db82aee7c7 [teagba] Update copyright for 2024 2024-01-01 12:06:57 -06:00
edf15858ca [teagba] Update copyright for 2024
All checks were successful
Build / build (push) Successful in 2m19s
2024-01-01 12:04:09 -06:00
d1efbb2ffa [ox] Update copyright for 2024 2024-01-01 12:03:16 -06:00
051623f4b5 [olympic,nostalgia] Update copyright for 2024 2024-01-01 12:02:40 -06:00
352 changed files with 4365 additions and 1970 deletions

View File

@ -57,6 +57,7 @@ misc-*,
readability-duplicate-include, readability-duplicate-include,
-misc-non-private-member-variables-in-classes, -misc-non-private-member-variables-in-classes,
-misc-no-recursion, -misc-no-recursion,
-misc-include-cleaner,
bugprone-*, bugprone-*,
clang-analyzer-*, clang-analyzer-*,
modernize-*, modernize-*,

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
.stfolder .stfolder
.stignore .stignore
scripts/__pycache__ scripts/__pycache__
pyenv
CMakeLists.txt.user CMakeLists.txt.user
ROM.oxfs ROM.oxfs
Session.vim Session.vim

View File

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

6
deps/glutils/.liccor.yml vendored Normal file
View File

@ -0,0 +1,6 @@
---
source:
- include
- src
copyright_notice: |-
Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/ */
#pragma once #pragma once
@ -150,8 +150,39 @@ class FrameBufferBind {
void bind(const FrameBuffer &fb) noexcept; void bind(const FrameBuffer &fb) noexcept;
struct ShaderVarSet {
GLsizei len{};
ox::String name;
};
ox::Result<GLProgram> buildShaderProgram(ox::CStringView const&vert, ox::CStringView const&frag, ox::CStringView const&geo = "") noexcept; struct ProgramSource {
ox::Vector<glutils::ShaderVarSet> const shaderParams;
GLsizei const rowLen = [this] {
GLsizei len{};
for (auto const&v : shaderParams) {
len += v.len;
}
return len;
}();
GLsizei const vboLen = rowLen * 4;
ox::String const vertShader{};
ox::String const fragShader{};
ox::String const geomShader{};
};
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept;
ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&vert,
ox::CStringView const&frag,
ox::CStringView const&geo = "") noexcept;
void setupShaderParams(
GLProgram const&shader,
ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept;
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept;
glutils::GLVertexArray generateVertexArrayObject() noexcept; glutils::GLVertexArray generateVertexArrayObject() noexcept;
@ -160,6 +191,8 @@ glutils::GLBuffer generateBuffer() noexcept;
[[nodiscard]] [[nodiscard]]
FrameBuffer generateFrameBuffer(int width, int height) noexcept; FrameBuffer generateFrameBuffer(int width, int height) noexcept;
void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept;
/** /**
* Resizes a FrameBuffer, and creates if it does not already exist. * Resizes a FrameBuffer, and creates if it does not already exist.
*/ */
@ -177,7 +210,7 @@ struct BufferSet {
}; };
void sendVbo(BufferSet const&bs) noexcept; void sendVbo(BufferSet const&bs) noexcept;
void sendEbo(BufferSet const&bs) noexcept; void sendEbo(BufferSet const&bs) noexcept;
void clearScreen() noexcept; void clearScreen() noexcept;

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/ */
#include <ox/std/assert.hpp> #include <ox/std/assert.hpp>
#include <ox/std/bstring.hpp> #include <ox/std/istring.hpp>
#include <ox/std/trace.hpp> #include <ox/std/trace.hpp>
#include "glutils/glutils.hpp" #include "glutils/glutils.hpp"
@ -88,6 +88,40 @@ static ox::Result<GLShader> buildShader(
return shader; return shader;
} }
ox::Result<GLProgram> buildShaderProgram(ProgramSource const&src) noexcept {
oxRequireM(program, buildShaderProgram(
src.vertShader,
src.fragShader,
src.geomShader));
setupShaderParams(program, src.shaderParams, src.rowLen);
return std::move(program);
}
void setupShaderParams(
GLProgram const&shader,
ox::Vector<ShaderVarSet> const&vars,
GLsizei vertexRowLen) noexcept {
// setup vars
for (auto lenWritten = 0LU; auto const&v : vars) {
auto const attr = static_cast<GLuint>(glGetAttribLocation(shader, v.name.c_str()));
glEnableVertexAttribArray(attr);
glVertexAttribPointer(
attr, v.len, GL_FLOAT, GL_FALSE,
vertexRowLen * static_cast<GLsizei>(sizeof(float)),
std::bit_cast<void*>(uintptr_t{lenWritten * sizeof(float)}));
lenWritten += static_cast<size_t>(v.len);
}
}
void setupShaderParams(GLProgram const&shader, ox::Vector<ShaderVarSet> const&vars) noexcept {
// get row len
GLsizei vertexRowLen{};
for (auto const&v : vars) {
vertexRowLen += v.len;
}
setupShaderParams(shader, vars, vertexRowLen);
}
ox::Result<GLProgram> buildShaderProgram( ox::Result<GLProgram> buildShaderProgram(
ox::CStringView const&vert, ox::CStringView const&vert,
ox::CStringView const&frag, ox::CStringView const&frag,
@ -147,11 +181,7 @@ FrameBuffer generateFrameBuffer(int width, int height) noexcept {
return fb; return fb;
} }
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept { void resizeFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
if (!fb) {
fb = generateFrameBuffer(width, height);
return;
}
width = ox::max(1, width); width = ox::max(1, width);
height = ox::max(1, height); height = ox::max(1, height);
fb.width = width; fb.width = width;
@ -171,6 +201,14 @@ void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
} }
void resizeInitFrameBuffer(FrameBuffer &fb, int width, int height) noexcept {
if (!fb) {
fb = generateFrameBuffer(width, height);
return;
}
resizeFrameBuffer(fb, width, height);
}
void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept { void resizeInitFrameBuffer(FrameBuffer &fb, ox::Size const&sz) noexcept {
resizeInitFrameBuffer(fb, sz.width, sz.height); resizeInitFrameBuffer(fb, sz.width, sz.height);
} }

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

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

View File

@ -82,4 +82,5 @@ if(OX_USE_STDLIB)
set(JSONCPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/jsoncpp/include") set(JSONCPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/deps/jsoncpp/include")
add_subdirectory(deps/jsoncpp) add_subdirectory(deps/jsoncpp)
endif() endif()
add_subdirectory(deps/cityhash)
add_subdirectory(src) add_subdirectory(src)

30
deps/ox/deps/cityhash/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.19)
set(CMAKE_POLICY_DEFAULT_CMP0110 NEW) # requires CMake 3.19
project(CityHash CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
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)
if(APPLE)
set(CMAKE_MACOSX_RPATH OFF)
else()
if(UNIX)
set(BUILD_SHARED_LIBS ON)
endif()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
endif()
add_library(CityHash INTERFACE)
target_include_directories(CityHash INTERFACE include)

View File

@ -0,0 +1,674 @@
// Copyright (c) 2011 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// CityHash, by Geoff Pike and Jyrki Alakuijala
//
// http://code.google.com/p/cityhash/
//
// This file provides a few functions for hashing strings. All of them are
// high-quality functions in the sense that they pass standard tests such
// as Austin Appleby's SMHasher. They are also fast.
//
// For 64-bit x86 code, on short strings, we don't know of anything faster than
// CityHash64 that is of comparable quality. We believe our nearest competitor
// is Murmur3. For 64-bit x86 code, CityHash64 is an excellent choice for hash
// tables and most other hashing (excluding cryptography).
//
// For 64-bit x86 code, on long strings, the picture is more complicated.
// On many recent Intel CPUs, such as Nehalem, Westmere, Sandy Bridge, etc.,
// CityHashCrc128 appears to be faster than all competitors of comparable
// quality. CityHash128 is also good but not quite as fast. We believe our
// nearest competitor is Bob Jenkins' Spooky. We don't have great data for
// other 64-bit CPUs, but for long strings we know that Spooky is slightly
// faster than CityHash on some relatively recent AMD x86-64 CPUs, for example.
// Note that CityHashCrc128 is declared in citycrc.h.
//
// For 32-bit x86 code, we don't know of anything faster than CityHash32 that
// is of comparable quality. We believe our nearest competitor is Murmur3A.
// (On 64-bit CPUs, it is typically faster to use the other CityHash variants.)
//
// Functions in the CityHash family are not suitable for cryptography.
//
// Please see CityHash's README file for more details on our performance
// measurements and so on.
//
// WARNING: This code has been only lightly tested on big-endian platforms!
// It is known to work well on little-endian platforms that have a small penalty
// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
// It should work on all 32-bit and 64-bit platforms that allow unaligned reads;
// bug reports are welcome.
//
// By the way, for some hash functions, given strings a and b, the hash
// of a+b is easily derived from the hashes of a and b. This property
// doesn't hold for any hash functions in this file.
#ifndef CITY_HASH_H_
#define CITY_HASH_H_
#if __has_include(<cstdint>)
#include <cstdint>
#else
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned uint_t;
#if defined(__arm__) || defined(__ppc__)
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
#else
typedef long int64_t;
typedef unsigned long uint64_t;
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
#endif
#if defined(_LP64) || defined(__ppc64__) || defined(__aarch64__)
typedef long intptr_t;
typedef unsigned long uintptr_t;
#elif defined(_WIN64)
typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
#elif defined(_LP32) || defined(__ppc__) || defined(_WIN32) || defined(__arm__)
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
#else
#error intptr_t, and uintptr_t undefined
#endif
using size_t = decltype(alignof(int));
#endif
namespace cityhash::detail {
template<typename T>
struct remove_reference {
using type = T;
};
template<typename T>
struct remove_reference<T&> {
using type = T;
};
template<typename T>
struct remove_reference<T&&> {
using type = T;
};
template<typename T>
using remove_reference_t = typename remove_reference<T>::type;
template<typename T>
constexpr remove_reference_t<T> &&move(T &&t) noexcept {
return static_cast<remove_reference_t<T>&&>(t);
}
template<typename T>
using remove_reference_t = typename remove_reference<T>::type;
template<typename T1, typename T2>
struct pair {
T1 first{};
T2 second{};
constexpr pair() noexcept = default;
constexpr pair(T1 a, T2 b) noexcept: first(detail::move(a)), second(detail::move(b)) {}
};
template<typename T>
constexpr void swap(T &a, T &b) noexcept {
auto temp = detail::move(a);
a = detail::move(b);
b = detail::move(temp);
}
}
namespace cityhash {
using uint128 = cityhash::detail::pair<uint64_t, uint64_t>;
namespace detail {
template<typename T>
[[nodiscard]]
constexpr T byteSwap(T i) noexcept {
if constexpr(sizeof(T) == 1) {
return i;
} else if constexpr(sizeof(T) == 2) {
return static_cast<T>(i << 8) | static_cast<T>(i >> 8);
} else if constexpr(sizeof(T) == 4) {
return ((i >> 24) & 0x000000ff) |
((i >> 8) & 0x0000ff00) |
((i << 8) & 0x00ff0000) |
((i << 24) & 0xff000000);
} else if constexpr(sizeof(T) == 8) {
return ((i >> 56) & 0x00000000000000ff) |
((i >> 40) & 0x000000000000ff00) |
((i >> 24) & 0x0000000000ff0000) |
((i >> 8) & 0x00000000ff000000) |
((i << 8) & 0x000000ff00000000) |
((i << 24) & 0x0000ff0000000000) |
((i << 40) & 0x00ff000000000000) |
((i << 56) & 0xff00000000000000);
}
}
[[nodiscard]]
constexpr uint64_t Uint128Low64(const uint128& x) noexcept { return x.first; }
[[nodiscard]]
constexpr uint64_t Uint128High64(const uint128& x) noexcept { return x.second; }
// Hash 128 input bits down to 64 bits of output.
// This is intended to be a reasonably good hash function.
[[nodiscard]]
constexpr uint64_t Hash128to64(const uint128& x) noexcept {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t a = (detail::Uint128Low64(x) ^ detail::Uint128High64(x)) * kMul;
a ^= (a >> 47);
uint64_t b = (detail::Uint128High64(x) ^ a) * kMul;
b ^= (b >> 47);
b *= kMul;
return b;
}
[[nodiscard]]
constexpr uint64_t UNALIGNED_LOAD64(const char *p) noexcept {
uint64_t result{};
result |= static_cast<uint64_t>(p[0]);
result |= static_cast<uint64_t>(p[1]) << 8;
result |= static_cast<uint64_t>(p[2]) << 16;
result |= static_cast<uint64_t>(p[3]) << 24;
result |= static_cast<uint64_t>(p[4]) << 32;
result |= static_cast<uint64_t>(p[5]) << 40;
result |= static_cast<uint64_t>(p[6]) << 48;
result |= static_cast<uint64_t>(p[7]) << 56;
//memcpy(&result, p, sizeof(result));
return result;
}
[[nodiscard]]
constexpr uint32_t UNALIGNED_LOAD32(const char *p) noexcept {
uint32_t result{};
result |= static_cast<uint32_t>(p[0]);
result |= static_cast<uint32_t>(p[1]) << 8;
result |= static_cast<uint32_t>(p[2]) << 16;
result |= static_cast<uint32_t>(p[3]) << 24;
//memcpy(&result, p, sizeof(result));
return result;
}
#ifdef WORDS_BIGENDIAN
#define uint32_in_expected_order(x) (detail::byteSwap<uint32_t>(x))
#define uint64_in_expected_order(x) (detail::byteSwap<uint64_t>(x))
#else
#define uint32_in_expected_order(x) (x)
#define uint64_in_expected_order(x) (x)
#endif
#if !defined(LIKELY)
#if HAVE_BUILTIN_EXPECT
#define LIKELY(x) (__builtin_expect(!!(x), 1))
#else
#define LIKELY(x) (x)
#endif
#endif
[[nodiscard]]
constexpr uint64_t Fetch64(const char *p) noexcept {
return uint64_in_expected_order(UNALIGNED_LOAD64(p));
}
[[nodiscard]]
constexpr uint32_t Fetch32(const char *p) noexcept {
return uint32_in_expected_order(UNALIGNED_LOAD32(p));
}
// Some primes between 2^63 and 2^64 for various uses.
constexpr uint64_t k0 = 0xc3a5c85c97cb3127ULL;
constexpr uint64_t k1 = 0xb492b66fbe98f273ULL;
constexpr uint64_t k2 = 0x9ae16a3b2f90404fULL;
// Magic numbers for 32-bit hashing. Copied from Murmur3.
constexpr uint32_t c1 = 0xcc9e2d51;
constexpr uint32_t c2 = 0x1b873593;
// A 32-bit to 32-bit integer hash copied from Murmur3.
[[nodiscard]]
constexpr uint32_t fmix(uint32_t h) noexcept {
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
return h;
}
[[nodiscard]]
constexpr uint32_t Rotate32(uint32_t val, int shift) noexcept {
// Avoid shifting by 32: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
}
#undef PERMUTE3
#define PERMUTE3(a, b, c) do { detail::swap(a, b); detail::swap(a, c); } while (0)
[[nodiscard]]
constexpr uint32_t Mur(uint32_t a, uint32_t h) noexcept {
// Helper from Murmur3 for combining two 32-bit values.
a *= detail::c1;
a = Rotate32(a, 17);
a *= detail::c2;
h ^= a;
h = Rotate32(h, 19);
return h * 5 + 0xe6546b64;
}
[[nodiscard]]
constexpr uint32_t Hash32Len13to24(const char *s, size_t len) noexcept {
uint32_t a = Fetch32(s - 4 + (len >> 1));
uint32_t b = Fetch32(s + 4);
uint32_t c = Fetch32(s + len - 8);
uint32_t d = Fetch32(s + (len >> 1));
uint32_t e = Fetch32(s);
uint32_t f = Fetch32(s + len - 4);
uint32_t h = static_cast<uint32_t>(len);
return detail::fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h)))))));
}
[[nodiscard]]
constexpr uint32_t Hash32Len0to4(const char *s, size_t len) noexcept {
uint32_t b = 0;
uint32_t c = 9;
for (size_t i = 0; i < len; i++) {
auto const v = static_cast<signed char>(s[i]);
b = b * detail::c1 + static_cast<uint32_t>(v);
c ^= b;
}
return detail::fmix(Mur(b, Mur(static_cast<uint32_t>(len), c)));
}
[[nodiscard]]
constexpr uint32_t Hash32Len5to12(const char *s, size_t len) noexcept {
uint32_t a = static_cast<uint32_t>(len), b = a * 5, c = 9, d = b;
a += Fetch32(s);
b += Fetch32(s + len - 4);
c += Fetch32(s + ((len >> 1) & 4));
return detail::fmix(Mur(c, Mur(b, Mur(a, d))));
}
// Bitwise right rotate. Normally this will compile to a single
// instruction, especially if the shift is a manifest constant.
[[nodiscard]]
constexpr uint64_t Rotate(uint64_t val, int shift) noexcept {
// Avoid shifting by 64: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
}
[[nodiscard]]
constexpr uint64_t ShiftMix(uint64_t val) noexcept {
return val ^ (val >> 47);
}
[[nodiscard]]
constexpr uint64_t HashLen16(uint64_t u, uint64_t v) noexcept {
return Hash128to64(uint128(u, v));
}
[[nodiscard]]
constexpr uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) noexcept {
// Murmur-inspired hashing.
uint64_t a = (u ^ v) * mul;
a ^= (a >> 47);
uint64_t b = (v ^ a) * mul;
b ^= (b >> 47);
b *= mul;
return b;
}
[[nodiscard]]
constexpr uint64_t HashLen0to16(const char *s, size_t len) noexcept {
if (len >= 8) {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = detail::Fetch64(s) + detail::k2;
uint64_t b = detail::Fetch64(s + len - 8);
uint64_t c = detail::Rotate(b, 37) * mul + a;
uint64_t d = (detail::Rotate(a, 25) + b) * mul;
return HashLen16(c, d, mul);
}
if (len >= 4) {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = Fetch32(s);
return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul);
}
if (len > 0) {
uint8_t a = static_cast<uint8_t>(s[0]);
uint8_t b = static_cast<uint8_t>(s[len >> 1]);
uint8_t c = static_cast<uint8_t>(s[len - 1]);
uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2);
return ShiftMix(y * detail::k2 ^ z * detail::k0) * detail::k2;
}
return detail::k2;
}
// This probably works well for 16-byte strings as well, but it may be overkill
// in that case.
[[nodiscard]]
constexpr uint64_t HashLen17to32(const char *s, size_t len) noexcept {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = detail::Fetch64(s) * detail::k1;
uint64_t b = detail::Fetch64(s + 8);
uint64_t c = detail::Fetch64(s + len - 8) * mul;
uint64_t d = detail::Fetch64(s + len - 16) * detail::k2;
return HashLen16(detail::Rotate(a + b, 43) + detail::Rotate(c, 30) + d,
a + detail::Rotate(b + detail::k2, 18) + c, mul);
}
// Return a 16-byte hash for 48 bytes. Quick and dirty.
// Callers do best to use "random-looking" values for a and b.
[[nodiscard]]
constexpr detail::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(
uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) noexcept {
a += w;
b = detail::Rotate(b + a + z, 21);
uint64_t c = a;
a += x;
a += y;
b += detail::Rotate(a, 44);
return detail::pair(a + z, b + c);
}
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
[[nodiscard]]
constexpr detail::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(
const char* s, uint64_t a, uint64_t b) noexcept {
return WeakHashLen32WithSeeds(detail::Fetch64(s),
detail::Fetch64(s + 8),
detail::Fetch64(s + 16),
detail::Fetch64(s + 24),
a,
b);
}
// Return an 8-byte hash for 33 to 64 bytes.
[[nodiscard]]
constexpr uint64_t HashLen33to64(const char *s, size_t len) noexcept {
uint64_t mul = detail::k2 + len * 2;
uint64_t a = detail::Fetch64(s) * detail::k2;
uint64_t b = detail::Fetch64(s + 8);
uint64_t c = detail::Fetch64(s + len - 24);
uint64_t d = detail::Fetch64(s + len - 32);
uint64_t e = detail::Fetch64(s + 16) * detail::k2;
uint64_t f = detail::Fetch64(s + 24) * 9;
uint64_t g = detail::Fetch64(s + len - 8);
uint64_t h = detail::Fetch64(s + len - 16) * mul;
uint64_t u = detail::Rotate(a + g, 43) + (detail::Rotate(b, 30) + c) * 9;
uint64_t v = ((a + g) ^ d) + f + 1;
uint64_t w = detail::byteSwap((u + v) * mul) + h;
uint64_t x = detail::Rotate(e + f, 42) + c;
uint64_t y = (detail::byteSwap((v + w) * mul) + g) * mul;
uint64_t z = e + f + c;
a = detail::byteSwap((x + z) * mul + y) + b;
b = ShiftMix((z + a) * mul + d + h) * mul;
return b + x;
}
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
// of any length representable in signed long. Based on City and Murmur.
[[nodiscard]]
constexpr uint128 CityMurmur(const char *s, size_t len, uint128 seed) noexcept {
uint64_t a = detail::Uint128Low64(seed);
uint64_t b = detail::Uint128High64(seed);
uint64_t c = 0;
uint64_t d = 0;
if (len <= 16) {
a = ShiftMix(a * detail::k1) * detail::k1;
c = b * detail::k1 + HashLen0to16(s, len);
d = ShiftMix(a + (len >= 8 ? detail::Fetch64(s) : c));
} else {
c = HashLen16(detail::Fetch64(s + len - 8) + detail::k1, a);
d = HashLen16(b + len, c + detail::Fetch64(s + len - 16));
a += d;
// len > 16 here, so do...while is safe
do {
a ^= ShiftMix(detail::Fetch64(s) * detail::k1) * detail::k1;
a *= detail::k1;
b ^= a;
c ^= ShiftMix(detail::Fetch64(s + 8) * detail::k1) * detail::k1;
c *= detail::k1;
d ^= c;
s += 16;
len -= 16;
} while (len > 16);
}
a = HashLen16(a, c);
b = HashLen16(d, b);
return uint128(a ^ b, HashLen16(b, a));
}
}
[[nodiscard]]
constexpr uint32_t CityHash32(const char *s, size_t len) noexcept {
if (len <= 24) {
return len <= 12 ?
(len <= 4 ? detail::Hash32Len0to4(s, len) : detail::Hash32Len5to12(s, len)) :
detail::Hash32Len13to24(s, len);
}
// len > 24
uint32_t h = static_cast<uint32_t>(len), g = detail::c1 * h, f = g;
uint32_t a0 = detail::Rotate32(detail::Fetch32(s + len - 4) * detail::c1, 17) * detail::c2;
uint32_t a1 = detail::Rotate32(detail::Fetch32(s + len - 8) * detail::c1, 17) * detail::c2;
uint32_t a2 = detail::Rotate32(detail::Fetch32(s + len - 16) * detail::c1, 17) * detail::c2;
uint32_t a3 = detail::Rotate32(detail::Fetch32(s + len - 12) * detail::c1, 17) * detail::c2;
uint32_t a4 = detail::Rotate32(detail::Fetch32(s + len - 20) * detail::c1, 17) * detail::c2;
h ^= a0;
h = detail::Rotate32(h, 19);
h = h * 5 + 0xe6546b64;
h ^= a2;
h = detail::Rotate32(h, 19);
h = h * 5 + 0xe6546b64;
g ^= a1;
g = detail::Rotate32(g, 19);
g = g * 5 + 0xe6546b64;
g ^= a3;
g = detail::Rotate32(g, 19);
g = g * 5 + 0xe6546b64;
f += a4;
f = detail::Rotate32(f, 19);
f = f * 5 + 0xe6546b64;
size_t iters = (len - 1) / 20;
do {
uint32_t a0 = detail::Rotate32(detail::Fetch32(s) * detail::c1, 17) * detail::c2;
uint32_t a1 = detail::Fetch32(s + 4);
uint32_t a2 = detail::Rotate32(detail::Fetch32(s + 8) * detail::c1, 17) * detail::c2;
uint32_t a3 = detail::Rotate32(detail::Fetch32(s + 12) * detail::c1, 17) * detail::c2;
uint32_t a4 = detail::Fetch32(s + 16);
h ^= a0;
h = detail::Rotate32(h, 18);
h = h * 5 + 0xe6546b64;
f += a1;
f = detail::Rotate32(f, 19);
f = f * detail::c1;
g += a2;
g = detail::Rotate32(g, 18);
g = g * 5 + 0xe6546b64;
h ^= a3 + a1;
h = detail::Rotate32(h, 19);
h = h * 5 + 0xe6546b64;
g ^= a4;
g = detail::byteSwap(g) * 5;
h += a4 * 5;
h = detail::byteSwap(h);
f += a0;
PERMUTE3(f, h, g);
s += 20;
} while (--iters != 0);
g = detail::Rotate32(g, 11) * detail::c1;
g = detail::Rotate32(g, 17) * detail::c1;
f = detail::Rotate32(f, 11) * detail::c1;
f = detail::Rotate32(f, 17) * detail::c1;
h = detail::Rotate32(h + g, 19);
h = h * 5 + 0xe6546b64;
h = detail::Rotate32(h, 17) * detail::c1;
h = detail::Rotate32(h + f, 19);
h = h * 5 + 0xe6546b64;
h = detail::Rotate32(h, 17) * detail::c1;
return h;
}
[[nodiscard]]
constexpr uint64_t CityHash64(const char *s, size_t len) noexcept {
if (len <= 32) {
if (len <= 16) {
return detail::HashLen0to16(s, len);
} else {
return detail::HashLen17to32(s, len);
}
} else if (len <= 64) {
return detail::HashLen33to64(s, len);
}
// For strings over 64 bytes we hash the end first, and then as we
// loop we keep 56 bytes of state: v, w, x, y, and z.
uint64_t x = detail::Fetch64(s + len - 40);
uint64_t y = detail::Fetch64(s + len - 16) + detail::Fetch64(s + len - 56);
uint64_t z = detail::HashLen16(detail::Fetch64(s + len - 48) + len, detail::Fetch64(s + len - 24));
detail::pair<uint64_t, uint64_t> v = detail::WeakHashLen32WithSeeds(s + len - 64, len, z);
detail::pair<uint64_t, uint64_t> w = detail::WeakHashLen32WithSeeds(s + len - 32, y + detail::k1, x);
x = x * detail::k1 + detail::Fetch64(s);
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
len = (len - 1) & ~static_cast<size_t>(63);
do {
x = detail::Rotate(x + y + v.first + detail::Fetch64(s + 8), 37) * detail::k1;
y = detail::Rotate(y + v.second + detail::Fetch64(s + 48), 42) * detail::k1;
x ^= w.second;
y += v.first + detail::Fetch64(s + 40);
z = detail::Rotate(z + w.first, 33) * detail::k1;
v = detail::WeakHashLen32WithSeeds(s, v.second * detail::k1, x + w.first);
w = detail::WeakHashLen32WithSeeds(s + 32, z + w.second, y + detail::Fetch64(s + 16));
detail::swap(z, x);
s += 64;
len -= 64;
} while (len != 0);
return detail::HashLen16(detail::HashLen16(v.first, w.first) + detail::ShiftMix(y) * detail::k1 + z,
detail::HashLen16(v.second, w.second) + x);
}
[[nodiscard]]
constexpr uint64_t CityHash64WithSeeds(const char *s, size_t len,
uint64_t seed0, uint64_t seed1) noexcept {
return detail::HashLen16(CityHash64(s, len) - seed0, seed1);
}
[[nodiscard]]
constexpr uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) noexcept {
return CityHash64WithSeeds(s, len, detail::k2, seed);
}
[[nodiscard]]
constexpr uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) noexcept {
if (len < 128) {
return detail::CityMurmur(s, len, seed);
}
// We expect len >= 128 to be the common case. Keep 56 bytes of state:
// v, w, x, y, and z.
detail::pair<uint64_t, uint64_t> v, w;
uint64_t x = detail::Uint128Low64(seed);
uint64_t y = detail::Uint128High64(seed);
uint64_t z = len * detail::k1;
v.first = detail::Rotate(y ^ detail::k1, 49) * detail::k1 + detail::Fetch64(s);
v.second = detail::Rotate(v.first, 42) * detail::k1 + detail::Fetch64(s + 8);
w.first = detail::Rotate(y + z, 35) * detail::k1 + x;
w.second = detail::Rotate(x + detail::Fetch64(s + 88), 53) * detail::k1;
// This is the same inner loop as CityHash64(), manually unrolled.
do {
x = detail::Rotate(x + y + v.first + detail::Fetch64(s + 8), 37) * detail::k1;
y = detail::Rotate(y + v.second + detail::Fetch64(s + 48), 42) * detail::k1;
x ^= w.second;
y += v.first + detail::Fetch64(s + 40);
z = detail::Rotate(z + w.first, 33) * detail::k1;
v = detail::WeakHashLen32WithSeeds(s, v.second * detail::k1, x + w.first);
w = detail::WeakHashLen32WithSeeds(s + 32, z + w.second, y + detail::Fetch64(s + 16));
detail::swap(z, x);
s += 64;
x = detail::Rotate(x + y + v.first + detail::Fetch64(s + 8), 37) * detail::k1;
y = detail::Rotate(y + v.second + detail::Fetch64(s + 48), 42) * detail::k1;
x ^= w.second;
y += v.first + detail::Fetch64(s + 40);
z = detail::Rotate(z + w.first, 33) * detail::k1;
v = detail::WeakHashLen32WithSeeds(s, v.second * detail::k1, x + w.first);
w = detail::WeakHashLen32WithSeeds(s + 32, z + w.second, y + detail::Fetch64(s + 16));
detail::swap(z, x);
s += 64;
len -= 128;
} while (LIKELY(len >= 128));
x += detail::Rotate(v.first + z, 49) * detail::k0;
y = y * detail::k0 + detail::Rotate(w.second, 37);
z = z * detail::k0 + detail::Rotate(w.first, 27);
w.first *= 9;
v.first *= detail::k0;
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
for (size_t tail_done = 0; tail_done < len; ) {
tail_done += 32;
y = detail::Rotate(x + y, 42) * detail::k0 + v.second;
w.first += detail::Fetch64(s + len - tail_done + 16);
x = x * detail::k0 + w.first;
z += w.second + detail::Fetch64(s + len - tail_done);
w.second += v.first;
v = detail::WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second);
v.first *= detail::k0;
}
// At this point our 56 bytes of state should contain more than
// enough information for a strong 128-bit hash. We use two
// different 56-byte-to-8-byte hashes to get a 16-byte final result.
x = detail::HashLen16(x, v.first);
y = detail::HashLen16(y + z, w.first);
return uint128(detail::HashLen16(x + v.second, w.second) + y,
detail::HashLen16(x + w.second, y + v.second));
}
[[nodiscard]]
constexpr uint128 CityHash128(const char *s, size_t len) noexcept {
return len >= 16 ?
CityHash128WithSeed(s + 16, len - 16,
uint128(detail::Fetch64(s), detail::Fetch64(s + 8) + detail::k0)) :
CityHash128WithSeed(s, len, uint128(detail::k0, detail::k1));
}
}
#endif // CITY_HASH_H_

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
@ -27,7 +27,7 @@ ClArgs::ClArgs(int argc, const char **args) noexcept {
m_bools[arg] = false; m_bools[arg] = false;
} }
m_strings[arg] = val; m_strings[arg] = val;
if (auto r = ox_atoi(val.c_str()); r.error == 0) { if (auto r = ox::atoi(val.c_str()); r.error == 0) {
m_ints[arg] = r.value; m_ints[arg] = r.value;
} }
++i; ++i;

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -13,7 +13,7 @@
namespace ox { namespace ox {
Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcept { Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcept {
const auto s1End = ox_strchr(buff, ';', buffLen); const auto s1End = ox::strchr(buff, ';', buffLen);
if (!s1End) { if (!s1End) {
return OxError(1, "Could not read Claw header"); return OxError(1, "Could not read Claw header");
} }
@ -22,7 +22,7 @@ Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcep
buff += s1Size + 1; buff += s1Size + 1;
buffLen -= s1Size + 1; buffLen -= s1Size + 1;
const auto s2End = ox_strchr(buff, ';', buffLen); const auto s2End = ox::strchr(buff, ';', buffLen);
if (!s2End) { if (!s2End) {
return OxError(2, "Could not read Claw header"); return OxError(2, "Could not read Claw header");
} }
@ -31,7 +31,7 @@ Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcep
buff += s2Size + 1; buff += s2Size + 1;
buffLen -= s2Size + 1; buffLen -= s2Size + 1;
const auto s3End = ox_strchr(buff, ';', buffLen); const auto s3End = ox::strchr(buff, ';', buffLen);
if (!s3End) { if (!s3End) {
return OxError(3, "Could not read Claw header"); return OxError(3, "Could not read Claw header");
} }
@ -49,7 +49,7 @@ Result<ClawHeader> readClawHeader(const char *buff, std::size_t buffLen) noexcep
return OxError(4, "Claw format does not match any supported format/version combo"); return OxError(4, "Claw format does not match any supported format/version combo");
} }
hdr.typeName = typeName; hdr.typeName = typeName;
if (auto r = ox_atoi(versionStr.c_str()); r.error == 0) { if (auto r = ox::atoi(versionStr.c_str()); r.error == 0) {
hdr.typeVersion = r.value; hdr.typeVersion = r.value;
} }
hdr.data = buff; hdr.data = buff;
@ -64,7 +64,7 @@ Result<ClawHeader> readClawHeader(const ox::Buffer &buff) noexcept {
Result<Buffer> stripClawHeader(const char *buff, std::size_t buffLen) noexcept { Result<Buffer> stripClawHeader(const char *buff, std::size_t buffLen) noexcept {
oxRequire(header, readClawHeader(buff, buffLen)); oxRequire(header, readClawHeader(buff, buffLen));
Buffer out(header.dataSize); Buffer out(header.dataSize);
ox_memcpy(out.data(), header.data, out.size()); ox::listcpy(out.data(), header.data, out.size());
return out; return out;
} }

View File

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

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <cstdio> #include <cstdio>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -29,7 +29,7 @@ struct TestStructNest {
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
uint32_t Int = 0; uint32_t Int = 0;
ox::BString<32> String = ""; ox::IString<32> String = "";
}; };
struct TestStruct { struct TestStruct {
@ -47,7 +47,7 @@ struct TestStruct {
int32_t Int8 = 0; int32_t Int8 = 0;
int unionIdx = 1; int unionIdx = 1;
TestUnion Union; TestUnion Union;
ox::BString<32> String = ""; ox::IString<32> String = "";
uint32_t List[4] = {0, 0, 0, 0}; uint32_t List[4] = {0, 0, 0, 0};
TestStructNest EmptyStruct; TestStructNest EmptyStruct;
TestStructNest Struct; TestStructNest Struct;

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "write.hpp" #include "write.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -61,14 +61,14 @@ struct type_version<T, decltype((void) T::TypeVersion, -1)> {
template<typename T> template<typename T>
constexpr const char *getTypeName(const T *t) noexcept { constexpr const char *getTypeName(const T *t) noexcept {
TypeInfoCatcher tnc; TypeInfoCatcher tnc;
oxIgnoreError(model(&tnc, t)); std::ignore = model(&tnc, t);
return tnc.name; return tnc.name;
} }
template<typename T> template<typename T>
constexpr int getTypeVersion(const T *t) noexcept { constexpr int getTypeVersion(const T *t) noexcept {
TypeInfoCatcher tnc; TypeInfoCatcher tnc;
oxIgnoreError(model(&tnc, t)); std::ignore = model(&tnc, t);
return tnc.version; return tnc.version;
} }
@ -88,7 +88,7 @@ ox::Error writeClawHeader(Writer_c auto &writer, const T *t, ClawFormat fmt) noe
oxReturnError(writer.put(';')); oxReturnError(writer.put(';'));
const auto tn = detail::getTypeVersion(t); const auto tn = detail::getTypeVersion(t);
if (tn > -1) { if (tn > -1) {
oxReturnError(ox::itoa(tn, writer)); oxReturnError(ox::writeItoa(tn, writer));
} }
oxReturnError(writer.put(';')); oxReturnError(writer.put(';'));
return {}; return {};

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "signal.hpp" #include "signal.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -391,7 +391,7 @@ Error Signal<Error(Args...)>::disconnectObject(const void *receiver) const noexc
template<class... Args> template<class... Args>
void Signal<Error(Args...)>::emit(Args... args) const noexcept { void Signal<Error(Args...)>::emit(Args... args) const noexcept {
for (auto &f : m_slots) { for (auto &f : m_slots) {
oxIgnoreError(f->call(ox::forward<Args>(args)...)); std::ignore = f->call(ox::forward<Args>(args)...);
} }
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#undef NDEBUG #undef NDEBUG

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "filestoretemplate.hpp" #include "filestoretemplate.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -279,7 +279,7 @@ Error FileStoreTemplate<size_t>::write(uint64_t id64, const void *data, FsSize_t
oxAssert(destData.size() == dataSize, "Allocation size does not match data."); oxAssert(destData.size() == dataSize, "Allocation size does not match data.");
// write data if any was provided // write data if any was provided
if (data != nullptr) { if (data != nullptr) {
ox_memcpy(destData, data, dest->size()); ox::memcpy(destData, data, dest->size());
oxTrace("ox.fs.FileStoreTemplate.write", "Data written"); oxTrace("ox.fs.FileStoreTemplate.write", "Data written");
} }
auto fsData = fileStoreData(); auto fsData = fileStoreData();
@ -336,7 +336,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, void *out, FsSize_t outSize,
return OxError(1); return OxError(1);
} }
ox_memcpy(out, srcData, srcData.size()); ox::memcpy(out, srcData, srcData.size());
if (size) { if (size) {
*size = src.size(); *size = src.size();
} }
@ -367,7 +367,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart, FsSize_t
return OxError(1); return OxError(1);
} }
ox_memcpy(out, srcData.get() + readStart, readSize); ox::memcpy(out, srcData.get() + readStart, readSize);
if (size) { if (size) {
*size = src.size(); *size = src.size();
} }
@ -400,7 +400,7 @@ Error FileStoreTemplate<size_t>::read(uint64_t id, FsSize_t readStart,
return OxError(1); return OxError(1);
} }
ox_memcpy(out, srcData.get() + readStart, readSize); ox::memcpy(out, srcData.get() + readStart, readSize);
if (size) { if (size) {
*size = src.size(); *size = src.size();
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "directory.hpp" #include "directory.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -48,7 +48,7 @@ struct OX_PACKED DirectoryEntry {
auto d = data(); auto d = data();
if (d.valid()) { if (d.valid()) {
d->inode = inode; d->inode = inode;
ox_strncpy(d->name, name, ox::min(bufferSize, static_cast<InodeId_t>(MaxFileNameLength))); ox::strncpy(d->name, name, ox::min(bufferSize, static_cast<InodeId_t>(MaxFileNameLength)));
return OxError(0); return OxError(0);
} }
return OxError(1); return OxError(1);

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <ox/model/modelops.hpp> #include <ox/model/modelops.hpp>
@ -46,9 +46,9 @@ FileAddress &FileAddress::operator=(const FileAddress &other) noexcept {
case FileAddressType::Path: case FileAddressType::Path:
{ {
if (other.m_data.path) { if (other.m_data.path) {
auto strSize = ox_strlen(other.m_data.path) + 1; auto strSize = ox::strlen(other.m_data.path) + 1;
m_data.path = new char[strSize]; m_data.path = new char[strSize];
ox_memcpy(m_data.path, other.m_data.path, strSize); ox::memcpy(m_data.path, other.m_data.path, strSize);
} else { } else {
m_data.constPath = ""; m_data.constPath = "";
m_type = FileAddressType::ConstPath; m_type = FileAddressType::ConstPath;
@ -88,6 +88,32 @@ FileAddress &FileAddress::operator=(FileAddress &&other) noexcept {
return *this; return *this;
} }
bool FileAddress::operator==(FileAddress const&other) const noexcept {
if (m_type != other.m_type) {
auto const aIsPath =
m_type == FileAddressType::Path || m_type == FileAddressType::ConstPath;
auto const bIsPath =
other.m_type == FileAddressType::Path || other.m_type == FileAddressType::ConstPath;
if (!(aIsPath && bIsPath)) {
return false;
}
}
switch (m_type) {
case FileAddressType::ConstPath:
case FileAddressType::Path: {
auto const a = getPath();
auto const b = other.getPath();
return (other.m_type == FileAddressType::ConstPath || other.m_type == FileAddressType::Path)
&& (a.value == b.value);
}
case FileAddressType::Inode:
return m_data.inode == other.m_data.inode;
case FileAddressType::None:
return true;
}
return true;
}
bool FileAddress::operator==(CRStringView path) const noexcept { bool FileAddress::operator==(CRStringView path) const noexcept {
auto [p, err] = getPath(); auto [p, err] = getPath();
if (err) { if (err) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -22,6 +22,9 @@ enum class FileAddressType: int8_t {
Inode, Inode,
}; };
template<typename T>
constexpr Error model(T *h, CommonPtrWith<class FileAddress> auto *fa) noexcept;
class FileAddress { class FileAddress {
template<typename T> template<typename T>
@ -41,13 +44,10 @@ class FileAddress {
protected: protected:
FileAddressType m_type = FileAddressType::None; FileAddressType m_type = FileAddressType::None;
Data m_data; Data m_data{};
public: public:
constexpr FileAddress() noexcept { constexpr FileAddress() noexcept = default;
m_data.inode = 0;
m_type = FileAddressType::None;
}
FileAddress(const FileAddress &other) noexcept; FileAddress(const FileAddress &other) noexcept;
@ -67,6 +67,8 @@ class FileAddress {
FileAddress &operator=(FileAddress &&other) noexcept; FileAddress &operator=(FileAddress &&other) noexcept;
bool operator==(const FileAddress &other) const noexcept;
bool operator==(CRStringView path) const noexcept; bool operator==(CRStringView path) const noexcept;
[[nodiscard]] [[nodiscard]]
@ -89,12 +91,12 @@ class FileAddress {
} }
} }
constexpr Result<ox::StringView> getPath() const noexcept { constexpr Result<ox::CStringView> getPath() const noexcept {
switch (m_type) { switch (m_type) {
case FileAddressType::Path: case FileAddressType::Path:
return ox::StringView(m_data.path); return ox::CStringView(m_data.path);
case FileAddressType::ConstPath: case FileAddressType::ConstPath:
return ox::StringView(m_data.constPath); return ox::CStringView(m_data.constPath);
default: default:
return OxError(1); return OxError(1);
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <ox/std/error.hpp> #include <ox/std/error.hpp>

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <ox/std/error.hpp> #include <ox/std/error.hpp>
@ -186,7 +186,7 @@ Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) n
} }
std::string_view PassThroughFS::stripSlash(StringView path) noexcept { std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
const auto pathLen = ox_strlen(path); const auto pathLen = ox::strlen(path);
for (auto i = 0u; i < pathLen && path[0] == '/'; i++) { for (auto i = 0u; i < pathLen && path[0] == '/'; i++) {
path = substr(path, 1); path = substr(path, 1);
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <ox/std/memops.hpp> #include <ox/std/memops.hpp>
@ -19,7 +19,7 @@ PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t it
m_iterator = iterator; m_iterator = iterator;
} }
PathIterator::PathIterator(const char *path): PathIterator(path, ox_strlen(path)) { PathIterator::PathIterator(const char *path): PathIterator(path, ox::strlen(path)) {
} }
PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.bytes()) { PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.bytes()) {
@ -29,10 +29,10 @@ PathIterator::PathIterator(CRStringView path): PathIterator(path.data(), path.by
* @return 0 if no error * @return 0 if no error
*/ */
Error PathIterator::dirPath(char *out, std::size_t outSize) { Error PathIterator::dirPath(char *out, std::size_t outSize) {
const auto idx = ox_lastIndexOf(m_path, '/', m_maxSize); 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) { if (idx >= 0 && size < outSize) {
ox_memcpy(out, m_path, size); ox::memcpy(out, m_path, size);
out[size] = 0; out[size] = 0;
return OxError(0); return OxError(0);
} else { } else {
@ -44,12 +44,12 @@ Error PathIterator::dirPath(char *out, std::size_t outSize) {
* @return 0 if no error * @return 0 if no error
*/ */
Error PathIterator::fileName(char *out, std::size_t outSize) { Error PathIterator::fileName(char *out, std::size_t outSize) {
auto idx = ox_lastIndexOf(m_path, '/', m_maxSize); auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
if (idx >= 0) { if (idx >= 0) {
idx++; // pass up the preceding / idx++; // pass up the preceding /
std::size_t fileNameSize = static_cast<size_t>(ox_strlen(&m_path[idx])); std::size_t fileNameSize = static_cast<size_t>(ox::strlen(&m_path[idx]));
if (fileNameSize < outSize) { if (fileNameSize < outSize) {
ox_memcpy(out, &m_path[idx], fileNameSize); ox::memcpy(out, &m_path[idx], fileNameSize);
out[fileNameSize] = 0; out[fileNameSize] = 0;
return OxError(0); return OxError(0);
} else { } else {
@ -67,8 +67,8 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize); oxTracef("ox.fs.PathIterator.get", "m_iterator ({}) >= m_maxSize ({})", m_iterator, m_maxSize);
return OxError(1); return OxError(1);
} }
if (!ox_strlen(&m_path[m_iterator])) { if (!ox::strlen(&m_path[m_iterator])) {
oxTrace("ox.fs.PathIterator.get", "!ox_strlen(&m_path[m_iterator])"); oxTrace("ox.fs.PathIterator.get", "!ox::strlen(&m_path[m_iterator])");
return OxError(1); return OxError(1);
} }
auto start = m_iterator; auto start = m_iterator;
@ -76,10 +76,10 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
start++; start++;
} }
// end is at the next / // end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next / // correct end if it is invalid, which happens if there is no next /
if (!substr) { if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start); substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
} }
const auto end = static_cast<size_t>(substr - m_path); const auto end = static_cast<size_t>(substr - m_path);
size = end - start; size = end - start;
@ -87,7 +87,7 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
if (size >= pathOutSize || size == 0) { if (size >= pathOutSize || size == 0) {
return OxError(1); return OxError(1);
} }
ox_memcpy(pathOut, &m_path[start], size); ox::memcpy(pathOut, &m_path[start], size);
// truncate trailing / // truncate trailing /
if (size && pathOut[size - 1] == '/') { if (size && pathOut[size - 1] == '/') {
size--; size--;
@ -100,17 +100,17 @@ Error PathIterator::get(char *pathOut, std::size_t pathOutSize) {
Error PathIterator::next(char *pathOut, std::size_t pathOutSize) { Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
std::size_t size = 0; std::size_t size = 0;
auto retval = OxError(1); auto retval = OxError(1);
if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) { if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
retval = OxError(0); retval = OxError(0);
if (m_path[m_iterator] == '/') { if (m_path[m_iterator] == '/') {
m_iterator++; m_iterator++;
} }
const auto start = m_iterator; const auto start = m_iterator;
// end is at the next / // end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next / // correct end if it is invalid, which happens if there is no next /
if (!substr) { if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start); substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
} }
const auto end = static_cast<size_t>(substr - m_path); const auto end = static_cast<size_t>(substr - m_path);
size = end - start; size = end - start;
@ -118,7 +118,7 @@ Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
if (size >= pathOutSize) { if (size >= pathOutSize) {
return OxError(1); return OxError(1);
} }
ox_memcpy(pathOut, &m_path[start], size); ox::memcpy(pathOut, &m_path[start], size);
} }
// truncate trailing / // truncate trailing /
if (size && pathOut[size - 1] == '/') { if (size && pathOut[size - 1] == '/') {
@ -132,14 +132,14 @@ Error PathIterator::next(char *pathOut, std::size_t pathOutSize) {
/** /**
* @return 0 if no error * @return 0 if no error
*/ */
Error PathIterator::get(BString<MaxFileNameLength> *fileName) { Error PathIterator::get(IString<MaxFileNameLength> *fileName) {
return get(fileName->data(), fileName->cap()); return get(fileName->data(), fileName->cap());
} }
/** /**
* @return 0 if no error * @return 0 if no error
*/ */
Error PathIterator::next(BString<MaxFileNameLength> *fileName) { Error PathIterator::next(IString<MaxFileNameLength> *fileName) {
return next(fileName->data(), fileName->cap()); return next(fileName->data(), fileName->cap());
} }
@ -147,17 +147,17 @@ Result<std::size_t> PathIterator::nextSize() const {
std::size_t size = 0; std::size_t size = 0;
auto retval = OxError(1); auto retval = OxError(1);
auto it = m_iterator; auto it = m_iterator;
if (it < m_maxSize && ox_strlen(&m_path[it])) { if (it < m_maxSize && ox::strlen(&m_path[it])) {
retval = OxError(0); retval = OxError(0);
if (m_path[it] == '/') { if (m_path[it] == '/') {
it++; it++;
} }
const auto start = it; const auto start = it;
// end is at the next / // end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next / // correct end if it is invalid, which happens if there is no next /
if (!substr) { if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start); substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
} }
const auto end = static_cast<std::size_t>(substr - m_path); const auto end = static_cast<std::size_t>(substr - m_path);
size = end - start; size = end - start;
@ -168,16 +168,16 @@ Result<std::size_t> PathIterator::nextSize() const {
bool PathIterator::hasNext() const { bool PathIterator::hasNext() const {
std::size_t size = 0; std::size_t size = 0;
if (m_iterator < m_maxSize && ox_strlen(&m_path[m_iterator])) { if (m_iterator < m_maxSize && ox::strlen(&m_path[m_iterator])) {
std::size_t start = m_iterator; std::size_t start = m_iterator;
if (m_path[start] == '/') { if (m_path[start] == '/') {
start++; start++;
} }
// end is at the next / // end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next / // correct end if it is invalid, which happens if there is no next /
if (!substr) { if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start); substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
} }
const auto end = static_cast<std::size_t>(substr - m_path); const auto end = static_cast<std::size_t>(substr - m_path);
size = end - start; size = end - start;
@ -192,16 +192,16 @@ bool PathIterator::valid() const {
PathIterator PathIterator::next() const { PathIterator PathIterator::next() const {
std::size_t size = 0; std::size_t size = 0;
auto iterator = m_iterator; auto iterator = m_iterator;
if (iterator < m_maxSize && ox_strlen(&m_path[iterator])) { if (iterator < m_maxSize && ox::strlen(&m_path[iterator])) {
if (m_path[iterator] == '/') { if (m_path[iterator] == '/') {
iterator++; iterator++;
} }
const auto start = iterator; const auto start = iterator;
// end is at the next / // end is at the next /
const char *substr = ox_strchr(&m_path[start], '/', m_maxSize - start); const char *substr = ox::strchr(&m_path[start], '/', m_maxSize - start);
// correct end if it is invalid, which happens if there is no next / // correct end if it is invalid, which happens if there is no next /
if (!substr) { if (!substr) {
substr = ox_strchr(&m_path[start], 0, m_maxSize - start); substr = ox::strchr(&m_path[start], 0, m_maxSize - start);
} }
const auto end = static_cast<std::size_t>(substr - m_path); const auto end = static_cast<std::size_t>(substr - m_path);
size = end - start; size = end - start;

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -13,7 +13,7 @@
namespace ox { namespace ox {
constexpr std::size_t MaxFileNameLength = 255; constexpr std::size_t MaxFileNameLength = 255;
using FileName = BString<MaxFileNameLength>; using FileName = IString<MaxFileNameLength>;
class PathIterator { class PathIterator {
private: private:

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -173,15 +173,15 @@ class OX_PACKED NodeBuffer {
template<typename size_t, typename Item> template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(std::size_t size) noexcept { NodeBuffer<size_t, Item>::NodeBuffer(std::size_t size) noexcept {
m_header.size = static_cast<size_t>(size); m_header.size = static_cast<size_t>(size);
ox_memset(this + 1, 0, size - sizeof(*this)); ox::memset(this + 1, 0, size - sizeof(*this));
oxTracef("ox.NodeBuffer.constructor", "{}", m_header.firstItem.get()); oxTracef("ox.NodeBuffer.constructor", "{}", m_header.firstItem.get());
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other, std::size_t size) noexcept { NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other, std::size_t size) noexcept {
oxTracef("ox.ptrarith.NodeBuffer.copy", "other.m_header.firstItem: {}", other.m_header.firstItem.get()); oxTracef("ox.ptrarith.NodeBuffer.copy", "other.m_header.firstItem: {}", other.m_header.firstItem.get());
ox_memset(this + 1, 0, size - sizeof(*this)); ox::memset(this + 1, 0, size - sizeof(*this));
ox_memcpy(this, &other, size); ox::memcpy(this, &other, size);
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
@ -291,7 +291,7 @@ Result<typename NodeBuffer<size_t, Item>::ItemPtr> NodeBuffer<size_t, Item>::mal
oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "Unknown"); oxTrace("ox.ptrarith.NodeBuffer.malloc.fail", "Unknown");
return OxError(1, "NodeBuffer::malloc: unknown failure"); return OxError(1, "NodeBuffer::malloc: unknown failure");
} }
ox_memset(out, 0, fullSize); ox::memset(out, 0, fullSize);
new (out) Item; new (out) Item;
out->setSize(sz); out->setSize(sz);
@ -367,7 +367,7 @@ Error NodeBuffer<size_t, Item>::setSize(std::size_t size) noexcept {
} else { } else {
m_header.size = static_cast<size_t>(size); m_header.size = static_cast<size_t>(size);
auto data = reinterpret_cast<uint8_t*>(this) + end; auto data = reinterpret_cast<uint8_t*>(this) + end;
ox_memset(data, 0, size - end); ox::memset(data, 0, size - end);
return OxError(0); return OxError(0);
} }
} }
@ -405,7 +405,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
return OxError(2); return OxError(2);
} }
// move node // move node
ox_memcpy(dest, src, src->fullSize()); ox::memcpy(dest, src, src->fullSize());
oxReturnError(cb(src, dest)); oxReturnError(cb(src, dest));
// update surrounding nodes // update surrounding nodes
auto prev = ptr(dest->prev); auto prev = ptr(dest->prev);

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
// make sure asserts are enabled for the test file // make sure asserts are enabled for the test file
@ -34,7 +34,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
using BuffPtr_t = uint32_t; using BuffPtr_t = uint32_t;
ox::Vector<char> buff(5 * ox::units::MB); ox::Vector<char> buff(5 * ox::units::MB);
auto buffer = new (buff.data()) ox::ptrarith::NodeBuffer<BuffPtr_t, NodeType<BuffPtr_t>>(buff.size()); auto buffer = new (buff.data()) ox::ptrarith::NodeBuffer<BuffPtr_t, NodeType<BuffPtr_t>>(buff.size());
using String = ox::BString<6>; using String = ox::IString<6>;
auto a1 = buffer->malloc(sizeof(String)).value; auto a1 = buffer->malloc(sizeof(String)).value;
auto a2 = buffer->malloc(sizeof(String)).value; auto a2 = buffer->malloc(sizeof(String)).value;
oxAssert(a1.valid(), "Allocation 1 failed."); oxAssert(a1.valid(), "Allocation 1 failed.");
@ -61,9 +61,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/charset.gbag"); auto const path = ox::String("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next");
return OxError(0); return OxError(0);
} }
}, },
@ -73,8 +73,8 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/"); auto const path = ox::String("/usr/share/");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
return OxError(0); return OxError(0);
} }
}, },
@ -84,7 +84,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/"); auto const path = ox::String("/");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "\0") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "\0") == 0, "PathIterator shows wrong next");
return OxError(0); return OxError(0);
} }
}, },
@ -94,9 +94,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("usr/share/charset.gbag"); auto const path = ox::String("usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows wrong next");
return OxError(0); return OxError(0);
} }
}, },
@ -106,8 +106,8 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("usr/share/"); auto const path = ox::String("usr/share/");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "usr") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "usr") == 0, "PathIterator shows wrong next");
oxAssert(it.next(buff, path.len()) == 0 && ox_strcmp(buff, "share") == 0, "PathIterator shows wrong next"); oxAssert(it.next(buff, path.len()) == 0 && ox::strcmp(buff, "share") == 0, "PathIterator shows wrong next");
return OxError(0); return OxError(0);
} }
}, },
@ -117,7 +117,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/charset.gbag"); auto const path = ox::String("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.dirPath(buff, path.len()) == 0 && ox_strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path"); oxAssert(it.dirPath(buff, path.len()) == 0 && ox::strcmp(buff, "/usr/share/") == 0, "PathIterator shows incorrect dir path");
return OxError(0); return OxError(0);
} }
}, },
@ -127,7 +127,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
auto const path = ox::String("/usr/share/charset.gbag"); auto const path = ox::String("/usr/share/charset.gbag");
ox::PathIterator it(path.c_str(), path.len()); ox::PathIterator it(path.c_str(), path.len());
auto buff = static_cast<char*>(ox_alloca(path.len() + 1)); auto buff = static_cast<char*>(ox_alloca(path.len() + 1));
oxAssert(it.fileName(buff, path.len()) == 0 && ox_strcmp(buff, "charset.gbag") == 0, "PathIterator shows incorrect file name"); oxAssert(it.fileName(buff, path.len()) == 0 && ox::strcmp(buff, "charset.gbag") == 0, "PathIterator shows incorrect file name");
return OxError(0); return OxError(0);
} }
}, },
@ -135,7 +135,7 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
"PathIterator::hasNext", "PathIterator::hasNext",
[](ox::StringView) { [](ox::StringView) {
const auto path = "/file1"; const auto path = "/file1";
ox::PathIterator it(path, ox_strlen(path)); ox::PathIterator it(path, ox::strlen(path));
oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext"); oxAssert(it.hasNext(), "PathIterator shows incorrect hasNext");
oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext"); oxAssert(!it.next().hasNext(), "PathIterator shows incorrect hasNext");
return OxError(0); return OxError(0);
@ -171,9 +171,9 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
[](ox::StringView) { [](ox::StringView) {
constexpr auto buffLen = 5000; constexpr auto buffLen = 5000;
constexpr auto str1 = "Hello, World!"; constexpr auto str1 = "Hello, World!";
constexpr auto str1Len = ox_strlen(str1) + 1; constexpr auto str1Len = ox::strlen(str1) + 1;
constexpr auto str2 = "Hello, Moon!"; constexpr auto str2 = "Hello, Moon!";
constexpr auto str2Len = ox_strlen(str2) + 1; constexpr auto str2Len = ox::strlen(str2) + 1;
auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen); auto list = new (ox_alloca(buffLen)) ox::ptrarith::NodeBuffer<uint32_t, ox::FileStoreItem<uint32_t>>(buffLen);
oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed."); oxAssert(ox::FileStore32::format(list, buffLen), "FileStore::format failed.");
ox::FileStore32 fileStore(list, buffLen); ox::FileStore32 fileStore(list, buffLen);

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include <cstdio> #include <cstdio>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -47,13 +47,13 @@ class CirculerBuffer {
} }
// write seg 1 // write seg 1
const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt); const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
ox_memcpy(&m_buff[m_writePt], &buff[0], seg1Sz); ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
m_writePt += sz; m_writePt += sz;
if (seg1Sz != sz) { if (seg1Sz != sz) {
m_writePt -= m_buff.size(); m_writePt -= m_buff.size();
// write seg 2 // write seg 2
const auto seg2Sz = sz - seg1Sz; const auto seg2Sz = sz - seg1Sz;
ox_memcpy(&m_buff[0], &buff[seg1Sz], seg2Sz); ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
oxAssert(m_buff[0] == buff[seg1Sz], "break"); oxAssert(m_buff[0] == buff[seg1Sz], "break");
} }
return {}; return {};
@ -70,7 +70,7 @@ class CirculerBuffer {
return {}; return {};
} }
constexpr ox::Error seekp(int, ios_base::seekdir) { constexpr ox::Error seekp(int, ios_base::seekdir) noexcept {
return OxError(1, "Unimplemented"); return OxError(1, "Unimplemented");
} }
@ -84,13 +84,13 @@ class CirculerBuffer {
const auto bytesRead = ox::min(outSize, m_buff.size() - avail()); const auto bytesRead = ox::min(outSize, m_buff.size() - avail());
// read seg 1 // read seg 1
const auto seg1Sz = ox::min(bytesRead, m_buff.size() - m_readPt); const auto seg1Sz = ox::min(bytesRead, m_buff.size() - m_readPt);
ox_memcpy(&out[0], &m_buff[m_readPt], seg1Sz); ox::listcpy(&out[0], &m_buff[m_readPt], seg1Sz);
m_readPt += bytesRead; m_readPt += bytesRead;
if (seg1Sz != bytesRead) { if (seg1Sz != bytesRead) {
m_readPt -= m_buff.size(); m_readPt -= m_buff.size();
// read seg 2 // read seg 2
const auto seg2Sz = bytesRead - seg1Sz; const auto seg2Sz = bytesRead - seg1Sz;
ox_memcpy(&out[seg1Sz], &m_buff[0], seg2Sz); ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
} }
return bytesRead; return bytesRead;
} }

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -98,7 +98,7 @@ void LoggerConn::msgSend() noexcept {
break; break;
} }
//std::printf("LoggerConn: sending %lu bytes\n", read); //std::printf("LoggerConn: sending %lu bytes\n", read);
oxIgnoreError(send(tmp.data(), read)); std::ignore = send(tmp.data(), read);
} }
} }
} }

View File

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

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -71,7 +71,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
// move input to uint64_t to allow consistent bit manipulation, and to avoid // move input to uint64_t to allow consistent bit manipulation, and to avoid
// overflow concerns // overflow concerns
uint64_t val = 0; uint64_t val = 0;
ox_memcpy(&val, &input, sizeof(input)); ox::memcpy(&val, &input, sizeof(input));
if (val) { if (val) {
// bits needed to represent number factoring in space possibly // bits needed to represent number factoring in space possibly
// needed for signed bit // needed for signed bit
@ -94,7 +94,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
} }
if (bytes == 9) { if (bytes == 9) {
out.data[0] = bytesIndicator; out.data[0] = bytesIndicator;
ox_memcpy(&out.data[1], &leVal, 8); ox::memcpy(&out.data[1], &leVal, 8);
if (inputNegative) { if (inputNegative) {
out.data[1] |= 0b1000'0000; out.data[1] |= 0b1000'0000;
} }
@ -104,7 +104,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
auto intermediate = auto intermediate =
static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes | static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
static_cast<uint64_t>(bytesIndicator); static_cast<uint64_t>(bytesIndicator);
ox_memcpy(out.data, &intermediate, sizeof(intermediate)); ox::memcpy(out.data, &intermediate, sizeof(intermediate));
} }
out.length = bytes; out.length = bytes;
} }
@ -160,7 +160,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
ox::Array<uint32_t, 2> d = {}; ox::Array<uint32_t, 2> d = {};
//d[0] = decoded & 0xffff'ffff; //d[0] = decoded & 0xffff'ffff;
//d[1] = decoded >> 32; //d[1] = decoded >> 32;
ox_memcpy(d.data(), &decoded, sizeof(decoded)); ox::memcpy(d.data(), &decoded, sizeof(decoded));
auto bit = negBit; auto bit = negBit;
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) { for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
d[0] |= 1 << 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[0] = d[1];
d[1] = d0Tmp; d[1] = d0Tmp;
} }
ox_memcpy(&out, d.data(), sizeof(out)); ox::memcpy(&out, d.data(), sizeof(out));
return out; return out;
} }
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "err.hpp" #include "err.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -77,7 +77,7 @@ class MetalClawReaderTemplate: public ModelHandlerBase<MetalClawReaderTemplate<R
constexpr Error field(const char*, BasicString<SmallStringSize> *val) noexcept; constexpr Error field(const char*, BasicString<SmallStringSize> *val) noexcept;
template<std::size_t L> template<std::size_t L>
constexpr Error field(const char*, BString<L> *val) noexcept; constexpr Error field(const char*, IString<L> *val) noexcept;
constexpr Error fieldCString(const char*, char *val, std::size_t buffLen) noexcept; constexpr Error fieldCString(const char*, char *val, std::size_t buffLen) noexcept;
@ -336,7 +336,7 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char*, BasicString<
template<Reader_c Reader> template<Reader_c Reader>
template<std::size_t L> template<std::size_t L>
constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, BString<L> *val) noexcept { constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, IString<L> *val) noexcept {
return fieldCString(name, val->data(), val->cap()); return fieldCString(name, val->data(), val->cap());
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -27,7 +27,7 @@ struct TestStructNest {
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
uint32_t Int = 0; uint32_t Int = 0;
ox::BString<32> BString = ""; ox::IString<32> IString = "";
}; };
struct TestStruct { struct TestStruct {
@ -46,7 +46,7 @@ struct TestStruct {
int unionIdx = 1; int unionIdx = 1;
TestUnion Union; TestUnion Union;
ox::String String; ox::String String;
ox::BString<32> BString = ""; ox::IString<32> IString = "";
uint32_t List[4] = {0, 0, 0, 0}; uint32_t List[4] = {0, 0, 0, 0};
ox::Vector<uint32_t> Vector = {1, 2, 3, 4, 5}; ox::Vector<uint32_t> Vector = {1, 2, 3, 4, 5};
ox::Vector<uint32_t> Vector2 = {1, 2, 3, 4, 5}; ox::Vector<uint32_t> Vector2 = {1, 2, 3, 4, 5};
@ -72,7 +72,7 @@ constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcep
oxModelBegin(TestStructNest) oxModelBegin(TestStructNest)
oxModelField(Bool) oxModelField(Bool)
oxModelField(Int) oxModelField(Int)
oxModelField(BString) oxModelField(IString)
oxModelEnd() oxModelEnd()
template<typename T> template<typename T>
@ -95,7 +95,7 @@ constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexce
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx})); oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
} }
oxReturnError(io->field("String", &obj->String)); oxReturnError(io->field("String", &obj->String));
oxReturnError(io->field("BString", &obj->BString)); oxReturnError(io->field("IString", &obj->IString));
oxReturnError(io->field("List", obj->List, 4)); oxReturnError(io->field("List", obj->List, 4));
oxReturnError(io->field("Vector", &obj->Vector)); oxReturnError(io->field("Vector", &obj->Vector));
oxReturnError(io->field("Vector2", &obj->Vector2)); oxReturnError(io->field("Vector2", &obj->Vector2));
@ -127,7 +127,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
TestStruct testIn, testOut; TestStruct testIn, testOut;
testIn.Bool = true; testIn.Bool = true;
testIn.Int = 42; testIn.Int = 42;
testIn.BString = "Test String 1"; testIn.IString = "Test String 1";
testIn.String = "Test String 2"; testIn.String = "Test String 2";
testIn.Vector = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; testIn.Vector = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
testIn.Vector2 = {}; testIn.Vector2 = {};
@ -137,7 +137,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
testIn.List[3] = 4; testIn.List[3] = 4;
testIn.Struct.Bool = true; testIn.Struct.Bool = true;
testIn.Struct.Int = 300; testIn.Struct.Int = 300;
testIn.Struct.BString = "Test String 3"; testIn.Struct.IString = "Test String 3";
testIn.unionIdx = 1; testIn.unionIdx = 1;
testIn.Union.Int = 93; testIn.Union.Int = 93;
// run tests // run tests
@ -157,7 +157,7 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch"); oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch");
oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch"); oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch");
oxAssert(testIn.String == testOut.String, "String value mismatch"); oxAssert(testIn.String == testOut.String, "String value mismatch");
oxAssert(testIn.BString == testOut.BString, "BString value mismatch"); oxAssert(testIn.IString == testOut.IString, "IString value mismatch");
oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch"); oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch");
oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch"); oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch");
oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch"); oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch");
@ -171,9 +171,9 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
oxAssert(testIn.Map["aoeu"] == testOut.Map["aoeu"], "Map[\"aoeu\"] value mismatch"); oxAssert(testIn.Map["aoeu"] == testOut.Map["aoeu"], "Map[\"aoeu\"] value mismatch");
oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch"); oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch");
oxAssert(testIn.EmptyStruct.Int == testOut.EmptyStruct.Int, "EmptyStruct.Int value mismatch"); oxAssert(testIn.EmptyStruct.Int == testOut.EmptyStruct.Int, "EmptyStruct.Int value mismatch");
oxAssert(testIn.EmptyStruct.BString == testOut.EmptyStruct.BString, "EmptyStruct.BString value mismatch"); oxAssert(testIn.EmptyStruct.IString == testOut.EmptyStruct.IString, "EmptyStruct.IString value mismatch");
oxAssert(testIn.Struct.Int == testOut.Struct.Int, "Struct.Int value mismatch"); oxAssert(testIn.Struct.Int == testOut.Struct.Int, "Struct.Int value mismatch");
oxAssert(testIn.Struct.BString == testOut.Struct.BString, "Struct.BString value mismatch"); oxAssert(testIn.Struct.IString == testOut.Struct.IString, "Struct.IString value mismatch");
oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch"); oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch");
return OxError(0); return OxError(0);
} }
@ -303,14 +303,14 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
TestStruct testIn; TestStruct testIn;
testIn.Bool = true; testIn.Bool = true;
testIn.Int = 42; testIn.Int = 42;
testIn.BString = "Test String 1"; testIn.IString = "Test String 1";
testIn.List[0] = 1; testIn.List[0] = 1;
testIn.List[1] = 2; testIn.List[1] = 2;
testIn.List[2] = 3; testIn.List[2] = 3;
testIn.List[3] = 4; testIn.List[3] = 4;
testIn.Struct.Bool = true; testIn.Struct.Bool = true;
testIn.Struct.Int = 300; testIn.Struct.Int = 300;
testIn.Struct.BString = "Test String 2"; testIn.Struct.IString = "Test String 2";
testIn.unionIdx = 1; testIn.unionIdx = 1;
testIn.Union.Int = 93; testIn.Union.Int = 93;
oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), testIn), "Data generation failed"); oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), testIn), "Data generation failed");
@ -320,27 +320,27 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
ox::ModelObject testOut; ox::ModelObject testOut;
oxReturnError(testOut.setType(type)); oxReturnError(testOut.setType(type));
oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed"); oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed");
oxAssert(testOut["Int"].get<int>() == testIn.Int, "testOut.Int failed"); oxAssert(testOut.at("Int").unwrap()->get<int>() == testIn.Int, "testOut.Int failed");
oxAssert(testOut["Bool"].get<bool>() == testIn.Bool, "testOut.Bool failed"); oxAssert(testOut.at("Bool").unwrap()->get<bool>() == testIn.Bool, "testOut.Bool failed");
oxAssert(testOut["BString"].get<ox::String>() == testIn.BString.c_str(), "testOut.String failed"); oxAssert(testOut.at("IString").unwrap()->get<ox::String>() == testIn.IString.c_str(), "testOut.String failed");
oxAssert(testOut["String"].get<ox::String>() == testIn.String, "testOut.String failed"); oxAssert(testOut.at("String").unwrap()->get<ox::String>() == testIn.String, "testOut.String failed");
auto &testOutStruct = testOut["Struct"].get<ox::ModelObject>(); auto &testOutStruct = testOut.at("Struct").unwrap()->get<ox::ModelObject>();
auto &testOutUnion = testOut["Union"].get<ox::ModelUnion>(); auto &testOutUnion = testOut.at("Union").unwrap()->get<ox::ModelUnion>();
auto &testOutList = testOut["List"].get<ox::ModelValueVector>(); auto &testOutList = testOut.at("List").unwrap()->get<ox::ModelValueVector>();
auto testOutStructCopy = testOut["Struct"].get<ox::ModelObject>(); auto testOutStructCopy = testOut.at("Struct").unwrap()->get<ox::ModelObject>();
auto testOutUnionCopy = testOut["Union"].get<ox::ModelUnion>(); auto testOutUnionCopy = testOut.at("Union").unwrap()->get<ox::ModelUnion>();
auto testOutListCopy = testOut["List"].get<ox::ModelValueVector>(); auto testOutListCopy = testOut.at("List").unwrap()->get<ox::ModelValueVector>();
oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed"); oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed");
oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed"); oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed");
oxAssert(testOutStruct["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed"); oxAssert(testOutStruct.at("Bool").unwrap()->get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed");
oxAssert(testOutStruct["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString failed"); oxAssert(testOutStruct.at("IString").unwrap()->get<ox::String>() == testIn.Struct.IString.c_str(), "testOut.Struct.IString failed");
oxAssert(testOut["unionIdx"].get<int>() == testIn.unionIdx, "testOut.unionIdx failed"); oxAssert(testOut.at("unionIdx").unwrap()->get<int>() == testIn.unionIdx, "testOut.unionIdx failed");
oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong"); oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong");
oxAssert(testOutUnion["Int"].get<uint32_t>() == testIn.Union.Int, "testOut.Union.Int failed"); oxAssert(testOutUnion.at("Int").unwrap()->get<uint32_t>() == testIn.Union.Int, "testOut.Union.Int failed");
oxAssert(testOutList[0].get<uint32_t>() == testIn.List[0], "testOut.List[0] failed"); oxAssert(testOutList[0].get<uint32_t>() == testIn.List[0], "testOut.List[0] failed");
oxAssert(testOutList[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] failed"); oxAssert(testOutList[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] failed");
oxAssert(testOutStructCopy["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool (copy) failed"); oxAssert(testOutStructCopy.at("Bool").unwrap()->get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool (copy) failed");
oxAssert(testOutStructCopy["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString (copy) failed"); 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[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"); oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
return OxError(0); return OxError(0);
@ -357,14 +357,14 @@ std::map<ox::StringView, ox::Error(*)()> tests = {
TestStruct testIn, testOut; TestStruct testIn, testOut;
testIn.Bool = true; testIn.Bool = true;
testIn.Int = 42; testIn.Int = 42;
testIn.BString = "Test String 1"; testIn.IString = "Test String 1";
testIn.List[0] = 1; testIn.List[0] = 1;
testIn.List[1] = 2; testIn.List[1] = 2;
testIn.List[2] = 3; testIn.List[2] = 3;
testIn.List[3] = 4; testIn.List[3] = 4;
testIn.Struct.Bool = false; testIn.Struct.Bool = false;
testIn.Struct.Int = 300; testIn.Struct.Int = 300;
testIn.Struct.BString = "Test String 2"; testIn.Struct.IString = "Test String 2";
oxAssert(ox::writeMC(dataBuff, dataBuffLen, testIn), "Data generation failed"); oxAssert(ox::writeMC(dataBuff, dataBuffLen, testIn), "Data generation failed");
ox::TypeStore typeStore; ox::TypeStore typeStore;
const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn); const auto [type, typeErr] = ox::buildTypeDef(&typeStore, &testIn);

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -66,7 +66,7 @@ class MetalClawWriter {
constexpr Error field(const char*, const BasicString<SmallStringSize> *val) noexcept; constexpr Error field(const char*, const BasicString<SmallStringSize> *val) noexcept;
template<std::size_t L> template<std::size_t L>
constexpr Error field(const char*, const BString<L> *val) noexcept; constexpr Error field(const char*, const IString<L> *val) noexcept;
constexpr Error fieldCString(const char *name, const char *const*val, std::size_t buffLen) noexcept; constexpr Error fieldCString(const char *name, const char *const*val, std::size_t buffLen) noexcept;
@ -206,7 +206,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<Sm
template<Writer_c Writer> template<Writer_c Writer>
template<std::size_t L> template<std::size_t L>
constexpr Error MetalClawWriter<Writer>::field(const char *name, const BString<L> *val) noexcept { constexpr Error MetalClawWriter<Writer>::field(const char *name, const IString<L> *val) noexcept {
return fieldCString(name, val->data(), val->cap()); return fieldCString(name, val->data(), val->cap());
} }
@ -214,7 +214,7 @@ template<Writer_c Writer>
constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept { constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *const*val, std::size_t) noexcept {
bool fieldSet = false; bool fieldSet = false;
if (!m_unionIdx.has_value() || *m_unionIdx == m_field) { if (!m_unionIdx.has_value() || *m_unionIdx == m_field) {
const auto strLen = *val ? ox_strlen(*val) : 0; const auto strLen = *val ? ox::strlen(*val) : 0;
// write the length // write the length
const auto strLenBuff = mc::encodeInteger(strLen); const auto strLenBuff = mc::encodeInteger(strLen);
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length)); oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -13,5 +13,5 @@
#define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { oxReturnError(io->template setTypeInfo<modelName>()); #define oxModelBegin(modelName) constexpr ox::Error model(auto *io, [[maybe_unused]] ox::CommonPtrWith<modelName> auto *o) noexcept { oxReturnError(io->template setTypeInfo<modelName>());
#define oxModelEnd() return OxError(0); } #define oxModelEnd() return OxError(0); }
#define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName)); #define oxModelField(fieldName) oxReturnError(io->field(#fieldName, &o->fieldName));
#define oxModelFieldRename(serFieldName, objFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName)); #define oxModelFieldRename(objFieldName, serFieldName) oxReturnError(io->field(#serFieldName, &o->objFieldName));
#define oxModelFriend(modelName) friend constexpr ox::Error model(auto*, ox::CommonPtrWith<modelName> auto*) noexcept #define oxModelFriend(modelName) friend constexpr ox::Error model(auto*, ox::CommonPtrWith<modelName> auto*) noexcept

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "desctypes.hpp" #include "desctypes.hpp"

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -9,7 +9,7 @@
#pragma once #pragma once
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/bstring.hpp> #include <ox/std/istring.hpp>
#include <ox/std/memory.hpp> #include <ox/std/memory.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/trace.hpp> #include <ox/std/trace.hpp>
@ -152,7 +152,7 @@ class TypeDescWriter {
template<std::size_t sz> template<std::size_t sz>
[[nodiscard]] [[nodiscard]]
constexpr const DescriptorType *type(const BString<sz> *val) const noexcept; constexpr const DescriptorType *type(const IString<sz> *val) const noexcept;
template<typename T> template<typename T>
[[nodiscard]] [[nodiscard]]
@ -334,7 +334,7 @@ constexpr const DescriptorType *TypeDescWriter::type(const char*) const noexcept
} }
template<std::size_t sz> template<std::size_t sz>
constexpr const DescriptorType *TypeDescWriter::type(const BString<sz>*) const noexcept { constexpr const DescriptorType *TypeDescWriter::type(const IString<sz>*) const noexcept {
constexpr auto PT = PrimitiveType::String; constexpr auto PT = PrimitiveType::String;
return getType(types::BString, 0, PT, 0); return getType(types::BString, 0, PT, 0);
} }

View File

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

View File

@ -1,15 +1,15 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/bstring.hpp> #include <ox/std/istring.hpp>
#include <ox/std/memory.hpp> #include <ox/std/memory.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/trace.hpp> #include <ox/std/trace.hpp>

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -131,6 +131,8 @@ class ModelHandlerInterface {
} }
case ModelValue::Type::Vector: case ModelValue::Type::Vector:
return m_handler->field(name, &v->template get<ModelValueVector>()); return m_handler->field(name, &v->template get<ModelValueVector>());
case ModelValue::Type::InlineArray:
return m_handler->field(name, &v->template get<ModelValueArray>());
} }
oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type())); oxErrf("invalid type: {}: {}\n", name, static_cast<int>(v->type()));
oxPanic(OxError(1), "invalid type"); oxPanic(OxError(1), "invalid type");

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -276,8 +276,8 @@ constexpr void moveModel(T *dst, T *src) noexcept {
constexpr auto size = ModelFieldCount_v<T>; constexpr auto size = ModelFieldCount_v<T>;
detail::MemberList<size> dstFields; detail::MemberList<size> dstFields;
detail::Mover<size> mover(&dstFields); detail::Mover<size> mover(&dstFields);
oxIgnoreError(model(&dstFields, dst)); std::ignore = model(&dstFields, dst);
oxIgnoreError(model(&mover, src)); std::ignore = model(&mover, src);
} }
template<typename T> template<typename T>
@ -285,8 +285,8 @@ constexpr void copyModel(T *dst, const T *src) noexcept {
constexpr auto size = ModelFieldCount_v<T>; constexpr auto size = ModelFieldCount_v<T>;
detail::MemberList<size> dstFields; detail::MemberList<size> dstFields;
detail::Copier<size> copier(&dstFields); detail::Copier<size> copier(&dstFields);
oxIgnoreError(model(&dstFields, dst)); std::ignore = model(&dstFields, dst);
oxIgnoreError(model(&copier, src)); std::ignore = model(&copier, src);
} }
template<typename T> template<typename T>
@ -295,8 +295,8 @@ constexpr bool equalsModel(T *a, T *b) noexcept {
constexpr auto size = T::Fields; constexpr auto size = T::Fields;
detail::MemberList<size> aFields; detail::MemberList<size> aFields;
detail::Equals<size> equals(&aFields); detail::Equals<size> equals(&aFields);
oxIgnoreError(model(&aFields, a)); std::ignore = model(&aFields, a);
oxIgnoreError(model(&equals, b)); std::ignore = model(&equals, b);
return equals.value; return equals.value;
} }

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -31,6 +31,7 @@ namespace ox {
class ModelObject; class ModelObject;
class ModelUnion; class ModelUnion;
class ModelValue; class ModelValue;
class ModelValueArray;
class ModelValueVector; class ModelValueVector;
class ModelValue { class ModelValue {
@ -50,6 +51,7 @@ class ModelValue {
Object, Object,
Union, Union,
Vector, Vector,
InlineArray,
}; };
private: private:
@ -68,6 +70,7 @@ class ModelValue {
ModelObject *obj; ModelObject *obj;
ModelUnion *uni; ModelUnion *uni;
ModelValueVector *vec; ModelValueVector *vec;
ModelValueArray *array;
} m_data; } m_data;
template<typename T> template<typename T>
@ -101,6 +104,8 @@ class ModelValue {
return Type::String; return Type::String;
} else if constexpr(is_same_v<U, ModelValueVector>) { } else if constexpr(is_same_v<U, ModelValueVector>) {
return Type::Vector; return Type::Vector;
} else if constexpr(is_same_v<U, ModelValueArray>) {
return Type::InlineArray;
} else { } else {
return Type::Undefined; return Type::Undefined;
} }
@ -134,6 +139,8 @@ class ModelValue {
return *t.m_data.obj; return *t.m_data.obj;
} else if constexpr(type == Type::Vector) { } else if constexpr(type == Type::Vector) {
return *t.m_data.vec; return *t.m_data.vec;
} else if constexpr(type == Type::InlineArray) {
return *t.m_data.array;
} else { } else {
return t.m_data.i32; return t.m_data.i32;
} }
@ -147,10 +154,12 @@ class ModelValue {
constexpr ModelValue(ModelValue &&other) noexcept; constexpr ModelValue(ModelValue &&other) noexcept;
template<typename T> template<typename T>
explicit constexpr ModelValue(const T &val) noexcept; explicit constexpr ModelValue(const T &val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>);
template<typename T> template<typename T>
explicit constexpr ModelValue(T &&val) noexcept; explicit constexpr ModelValue(T &&val) noexcept
requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>);
constexpr ~ModelValue() noexcept; constexpr ~ModelValue() noexcept;
@ -177,7 +186,10 @@ class ModelValue {
[[nodiscard]] [[nodiscard]]
constexpr Type type() const noexcept; constexpr Type type() const noexcept;
constexpr Error setType(const DescriptorType *type, int subscriptLevels = 0) noexcept; constexpr Error setType(
DescriptorType const*type,
int subscriptLevels = 0,
SubscriptStack const& = {}) noexcept;
template<typename T> template<typename T>
constexpr Error setType() noexcept; constexpr Error setType() noexcept;
@ -199,11 +211,166 @@ class ModelValue {
}; };
class ModelValueArray {
private:
Vector<ModelValue> m_vec;
const DescriptorType *m_type = nullptr;
int m_typeSubscriptLevels = 0;
SubscriptStack m_subscriptStack;
String m_typeName;
int m_typeVersion = 0;
public:
constexpr explicit ModelValueArray() noexcept = default;
constexpr ModelValueArray(ModelValueArray const&other) noexcept {
for (auto &v : other.m_vec) {
m_vec.emplace_back(v);
}
m_typeName = other.m_typeName;
m_typeVersion = other.m_typeVersion;
}
constexpr ModelValueArray(ModelValueArray &&other) noexcept {
m_vec = std::move(other.m_vec);
m_typeName = std::move(other.m_typeName);
m_typeVersion = other.m_typeVersion;
}
constexpr ox::Error setSize(std::size_t sz) noexcept {
const auto oldSz = m_vec.size();
m_vec.resize(sz);
if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) {
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
}
}
return {};
}
[[nodiscard]]
constexpr auto data() const noexcept {
return m_vec.data();
}
[[nodiscard]]
constexpr auto data() noexcept {
return m_vec.data();
}
constexpr static ox::Result<ModelValueArray> make(size_t sz) noexcept {
ox::Result<ModelValueArray> out;
out.error = out.value.setSize(sz);
return out;
}
[[nodiscard]]
constexpr auto &get() noexcept {
return m_vec;
}
[[nodiscard]]
constexpr auto const&get() const noexcept {
return m_vec;
}
constexpr Error setType(
DescriptorType const*type,
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
return {};
}
[[nodiscard]]
constexpr String const&typeName() const noexcept {
return m_typeName;
}
[[nodiscard]]
constexpr int typeVersion() const noexcept {
return m_typeVersion;
}
[[nodiscard]]
constexpr std::size_t size() const noexcept {
return m_vec.size();
}
constexpr auto &operator[](std::size_t i) noexcept {
return m_vec[i];
}
constexpr auto &operator[](std::size_t i) const noexcept {
return m_vec[i];
}
[[nodiscard]]
auto begin() noexcept {
return m_vec.begin();
}
[[nodiscard]]
auto begin() const noexcept {
return m_vec.cbegin();
}
[[nodiscard]]
auto cbegin() const noexcept {
return m_vec.cbegin();
}
[[nodiscard]]
auto rbegin() noexcept {
return m_vec.rbegin();
}
[[nodiscard]]
auto crbegin() const noexcept {
return m_vec.crbegin();
}
[[nodiscard]]
auto end() noexcept {
return m_vec.end();
}
[[nodiscard]]
auto end() const noexcept {
return m_vec.cend();
}
[[nodiscard]]
auto cend() const noexcept {
return m_vec.cend();
}
[[nodiscard]]
auto rend() noexcept {
return m_vec.rend();
}
[[nodiscard]]
auto crend() const noexcept {
return m_vec.crend();
}
};
template<>
[[nodiscard]]
consteval bool isArray(ModelValueArray*) noexcept {
return true;
}
class ModelValueVector { class ModelValueVector {
private: private:
Vector<ModelValue> m_vec; Vector<ModelValue> m_vec;
const DescriptorType *m_type = nullptr; const DescriptorType *m_type = nullptr;
int m_typeSubscriptLevels = 0; int m_typeSubscriptLevels = 0;
SubscriptStack m_subscriptStack;
String m_typeName; String m_typeName;
int m_typeVersion = 0; int m_typeVersion = 0;
@ -233,7 +400,7 @@ class ModelValueVector {
m_vec.resize(sz); m_vec.resize(sz);
if (sz > oldSz) { if (sz > oldSz) {
for (auto i = oldSz; i < sz; ++i) { for (auto i = oldSz; i < sz; ++i) {
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels)); oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
} }
} }
return {}; return {};
@ -249,9 +416,13 @@ class ModelValueVector {
return m_vec; return m_vec;
} }
constexpr Error setType(const DescriptorType *type, int subscriptLevels) noexcept { constexpr Error setType(
DescriptorType const*type,
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
m_type = type; m_type = type;
m_typeSubscriptLevels = subscriptLevels; m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
return {}; return {};
} }
@ -334,7 +505,12 @@ consteval bool isVector(const ModelValueVector*) noexcept {
return true; return true;
} }
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept;
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept;
class ModelObject { class ModelObject {
friend constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept;
public: public:
struct Field { struct Field {
String name; String name;
@ -466,12 +642,9 @@ class ModelObject {
return {}; return {};
} }
constexpr auto &operator[](StringView const&k) noexcept { constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
auto [v, err] = m_fields.at(k); oxRequire(v, m_fields.at(k));
if (err) [[unlikely]] { return *v;
oxPanic(err, ox::sfmt("field {} does not exist in type {}", k, buildTypeId(*m_type)).c_str());
}
return **v;
} }
constexpr auto &operator[](const std::size_t i) noexcept { constexpr auto &operator[](const std::size_t i) noexcept {
@ -501,7 +674,7 @@ class ModelObject {
for (const auto &f : type->fieldList) { for (const auto &f : type->fieldList) {
auto field = make_unique<Field>(); auto field = make_unique<Field>();
field->name = f.fieldName; field->name = f.fieldName;
oxReturnError(field->value.setType(f.type, f.subscriptLevels)); oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
m_fields[field->name] = &field->value; m_fields[field->name] = &field->value;
m_fieldsOrder.emplace_back(std::move(field)); m_fieldsOrder.emplace_back(std::move(field));
} }
@ -517,7 +690,7 @@ class ModelUnion {
String name; String name;
ModelValue value; ModelValue value;
}; };
oxModelFriend(ModelUnion); friend constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept;
friend ModelValue; friend ModelValue;
Vector<UniquePtr<Field>> m_fieldsOrder; Vector<UniquePtr<Field>> m_fieldsOrder;
HashMap<String, Field*> m_fields; HashMap<String, Field*> m_fields;
@ -555,12 +728,9 @@ class ModelUnion {
return UniquePtr<ModelUnion>(new ModelUnion(other)); return UniquePtr<ModelUnion>(new ModelUnion(other));
} }
constexpr auto &operator[](StringView const&k) noexcept { constexpr ox::Result<ModelValue*> at(StringView const&k) noexcept {
const auto [v, err] = m_fields.at(k); oxRequire(v, m_fields.at(k));
if (err) [[unlikely]] { return &(*v)->value;
oxPanic(err, ox::sfmt("field {} does not exist in type {}", k, buildTypeId(*m_type)).c_str());
}
return (*v)->value;
} }
constexpr auto &operator[](const std::size_t i) noexcept { constexpr auto &operator[](const std::size_t i) noexcept {
@ -647,6 +817,12 @@ class ModelUnion {
}; };
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t sizeOf(ModelValueArray const*v) noexcept {
return sizeOf<PlatSpec>(&(*v)[0]) * v->size();
}
template<typename PlatSpec> template<typename PlatSpec>
[[nodiscard]] [[nodiscard]]
constexpr std::size_t sizeOf(const ModelValueVector*) noexcept { constexpr std::size_t sizeOf(const ModelValueVector*) noexcept {
@ -708,10 +884,22 @@ constexpr std::size_t sizeOf(const ModelValue *t) noexcept {
case ModelValue::Type::Vector: case ModelValue::Type::Vector:
size = sizeOf<PlatSpec>(&t->get<ox::ModelValueVector>()); size = sizeOf<PlatSpec>(&t->get<ox::ModelValueVector>());
break; break;
case ModelValue::Type::InlineArray:
{
auto &list = t->get<ox::ModelValueArray>();
size = sizeOf<PlatSpec>(&list[0]) * list.size();
break;
}
} }
return size; return size;
} }
template<typename PlatSpec>
[[nodiscard]]
constexpr std::size_t alignOf(ModelValueArray const&v) noexcept {
return alignOf<PlatSpec>(v[0]);
}
template<typename PlatSpec> template<typename PlatSpec>
[[nodiscard]] [[nodiscard]]
constexpr std::size_t alignOf(const ModelValueVector&) noexcept { constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
@ -722,56 +910,63 @@ constexpr std::size_t alignOf(const ModelValueVector&) noexcept {
template<typename PlatSpec> template<typename PlatSpec>
[[nodiscard]] [[nodiscard]]
constexpr std::size_t alignOf(const ModelValue &t) noexcept { constexpr std::size_t alignOf(const ModelValue &t) noexcept {
std::size_t size = 0; std::size_t alignment = 0;
switch (t.type()) { switch (t.type()) {
case ModelValue::Type::Bool: case ModelValue::Type::Bool:
size = PlatSpec::alignOf(t.get<bool>()); alignment = PlatSpec::alignOf(t.get<bool>());
break; break;
case ModelValue::Type::Undefined: case ModelValue::Type::Undefined:
size = 1; alignment = 1;
break; break;
case ModelValue::Type::UnsignedInteger8: case ModelValue::Type::UnsignedInteger8:
size = PlatSpec::alignOf(t.get<uint8_t>()); alignment = PlatSpec::alignOf(t.get<uint8_t>());
break; break;
case ModelValue::Type::UnsignedInteger16: case ModelValue::Type::UnsignedInteger16:
size = PlatSpec::alignOf(t.get<uint16_t>()); alignment = PlatSpec::alignOf(t.get<uint16_t>());
break; break;
case ModelValue::Type::UnsignedInteger32: case ModelValue::Type::UnsignedInteger32:
size = PlatSpec::alignOf(t.get<uint32_t>()); alignment = PlatSpec::alignOf(t.get<uint32_t>());
break; break;
case ModelValue::Type::UnsignedInteger64: case ModelValue::Type::UnsignedInteger64:
size = PlatSpec::alignOf(t.get<uint64_t>()); alignment = PlatSpec::alignOf(t.get<uint64_t>());
break; break;
case ModelValue::Type::SignedInteger8: case ModelValue::Type::SignedInteger8:
size = PlatSpec::alignOf(t.get<int8_t>()); alignment = PlatSpec::alignOf(t.get<int8_t>());
break; break;
case ModelValue::Type::SignedInteger16: case ModelValue::Type::SignedInteger16:
size = PlatSpec::alignOf(t.get<int16_t>()); alignment = PlatSpec::alignOf(t.get<int16_t>());
break; break;
case ModelValue::Type::SignedInteger32: case ModelValue::Type::SignedInteger32:
size = PlatSpec::alignOf(t.get<int32_t>()); alignment = PlatSpec::alignOf(t.get<int32_t>());
break; break;
case ModelValue::Type::SignedInteger64: case ModelValue::Type::SignedInteger64:
size = PlatSpec::alignOf(t.get<int64_t>()); alignment = PlatSpec::alignOf(t.get<int64_t>());
break; break;
case ModelValue::Type::String: case ModelValue::Type::String:
size = PlatSpec::alignOf(t.get<ox::String>()); alignment = alignOf<PlatSpec>(t.get<ox::String>());
break; break;
case ModelValue::Type::Object: case ModelValue::Type::Object:
size = alignOf<PlatSpec>(t.get<ox::ModelObject>()); alignment = alignOf<PlatSpec>(t.get<ox::ModelObject>());
break; break;
case ModelValue::Type::Union: case ModelValue::Type::Union:
size = alignOf<PlatSpec>(t.get<ox::ModelUnion>()); alignment = alignOf<PlatSpec>(t.get<ox::ModelUnion>());
break; break;
case ModelValue::Type::Vector: case ModelValue::Type::Vector:
size = alignOf<PlatSpec>(t.get<ox::ModelValueVector>()); alignment = alignOf<PlatSpec>(t.get<ox::ModelValueVector>());
break; break;
case ModelValue::Type::InlineArray:
{
auto &list = t.get<ox::ModelValueArray>();
alignment = alignOf<PlatSpec>(list[0]);
break;
}
} }
return size; return alignment;
} }
constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept { constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelObject>(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); oxReturnError(h->template setTypeInfo<ModelObject>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) { for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value)); oxReturnError(h->field(f->name.c_str(), &f->value));
} }
@ -779,7 +974,8 @@ constexpr Error model(auto *h, CommonPtrWith<ModelObject> auto *obj) noexcept {
} }
constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept { constexpr Error model(auto *h, CommonPtrWith<ModelUnion> auto *obj) noexcept {
oxReturnError(h->template setTypeInfo<ModelUnion>(obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size())); oxReturnError(h->template setTypeInfo<ModelUnion>(
obj->typeName().c_str(), obj->typeVersion(), {}, obj->m_fieldsOrder.size()));
for (auto &f : obj->m_fieldsOrder) { for (auto &f : obj->m_fieldsOrder) {
oxReturnError(h->field(f->name.c_str(), &f->value)); oxReturnError(h->field(f->name.c_str(), &f->value));
} }
@ -799,7 +995,7 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data)); ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = new String(other.get<String>()); m_data.str = new String(other.get<String>());
@ -813,6 +1009,9 @@ constexpr ModelValue::ModelValue(const ModelValue &other) noexcept {
case Type::Vector: case Type::Vector:
m_data.vec = new ModelValueVector(*other.m_data.vec); m_data.vec = new ModelValueVector(*other.m_data.vec);
break; break;
case Type::InlineArray:
m_data.array = new ModelValueArray(*other.m_data.array);
break;
} }
} }
@ -829,8 +1028,8 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data)); ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
ox_memset(&other.m_data, 0, sizeof(m_data)); ox::memset(&other.m_data, 0, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = other.m_data.str; m_data.str = other.m_data.str;
@ -848,17 +1047,23 @@ constexpr ModelValue::ModelValue(ModelValue &&other) noexcept {
m_data.vec = other.m_data.vec; m_data.vec = other.m_data.vec;
other.m_data.vec = new ModelValueVector; other.m_data.vec = new ModelValueVector;
break; break;
case Type::InlineArray:
m_data.array = other.m_data.array;
other.m_data.array = new ModelValueArray();
break;
} }
} }
template<typename T> template<typename T>
constexpr ModelValue::ModelValue(const T &val) noexcept { constexpr ModelValue::ModelValue(const T &val) noexcept
set(val); requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
std::ignore = set(val);
} }
template<typename T> template<typename T>
constexpr ModelValue::ModelValue(T &&val) noexcept { constexpr ModelValue::ModelValue(T &&val) noexcept
set(ox::forward(val)); requires(!ox::is_same_v<ox::remove_reference_t<T>, ModelValue>) {
std::ignore = set(ox::forward<T>(val));
} }
constexpr ModelValue::~ModelValue() noexcept { constexpr ModelValue::~ModelValue() noexcept {
@ -869,12 +1074,24 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
return m_type; return m_type;
} }
constexpr Error ModelValue::setType(const DescriptorType *type, int subscriptLevels) noexcept { constexpr Error ModelValue::setType(
const DescriptorType *type,
int subscriptLevels,
SubscriptStack const&subscriptStack) noexcept {
freeResources(); freeResources();
if (subscriptLevels) { if (subscriptLevels) {
m_type = Type::Vector; auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
m_data.vec = new ModelValueVector; if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
return m_data.vec->setType(type, subscriptLevels - 1); 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)));
} else {
m_type = Type::Vector;
m_data.vec = new ModelValueVector;
oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
}
return {};
} else if (type->typeName == types::Bool) { } else if (type->typeName == types::Bool) {
m_type = Type::Bool; m_type = Type::Bool;
} else if (type->typeName == types::BasicString || } else if (type->typeName == types::BasicString ||
@ -917,7 +1134,8 @@ constexpr Error ModelValue::setType() noexcept {
constexpr auto type = getType<T>(); constexpr auto type = getType<T>();
freeResources(); freeResources();
m_type = type; m_type = type;
// 2022.09.04: Clang retardedly requires initializing the union values directly, rather than using getValue<type>() // 2022.09.04: Clang retardedly requires initializing the union values directly,
// rather than using getValue<type>()
if constexpr(type == Type::Object) { if constexpr(type == Type::Object) {
m_data.obj = new ModelObject; m_data.obj = new ModelObject;
oxReturnError(m_data.obj->setType(type)); oxReturnError(m_data.obj->setType(type));
@ -959,7 +1177,7 @@ constexpr Error ModelValue::set(const T &v) noexcept {
} }
auto &value = getValue<type>(*this); auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object || if constexpr(type == Type::Vector || type == Type::Object ||
type == Type::Union || type == Type::String) { type == Type::Union || type == Type::String || type == Type::InlineArray) {
safeDelete(&value); safeDelete(&value);
} }
value = v; value = v;
@ -974,10 +1192,10 @@ constexpr Error ModelValue::set(T &&v) noexcept {
} }
auto &value = getValue<type>(*this); auto &value = getValue<type>(*this);
if constexpr(type == Type::Vector || type == Type::Object || if constexpr(type == Type::Vector || type == Type::Object ||
type == Type::Union || type == Type::String) { type == Type::Union || type == Type::String || type == Type::InlineArray) {
safeDelete(&value); safeDelete(&value);
} }
value = ox::forward<T>(v); value = std::move(v);
return OxError(0); return OxError(0);
} }
@ -1002,7 +1220,7 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data)); ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = new String(other.get<String>()); m_data.str = new String(other.get<String>());
@ -1016,6 +1234,9 @@ constexpr ModelValue &ModelValue::operator=(const ModelValue &other) noexcept {
case Type::Vector: case Type::Vector:
m_data.vec = new ModelValueVector(*other.m_data.vec); m_data.vec = new ModelValueVector(*other.m_data.vec);
break; break;
case Type::InlineArray:
m_data.array = new ModelValueArray(*other.m_data.array);
break;
} }
return *this; return *this;
} }
@ -1037,8 +1258,8 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
case Type::SignedInteger16: case Type::SignedInteger16:
case Type::SignedInteger32: case Type::SignedInteger32:
case Type::SignedInteger64: case Type::SignedInteger64:
ox_memcpy(&m_data, &other.m_data, sizeof(m_data)); ox::memcpy(&m_data, &other.m_data, sizeof(m_data));
ox_memset(&other.m_data, 0, sizeof(m_data)); ox::memset(&other.m_data, 0, sizeof(m_data));
break; break;
case Type::String: case Type::String:
m_data.str = other.m_data.str; m_data.str = other.m_data.str;
@ -1056,6 +1277,10 @@ constexpr ModelValue &ModelValue::operator=(ModelValue &&other) noexcept {
m_data.vec = other.m_data.vec; m_data.vec = other.m_data.vec;
other.m_data.vec = new ModelValueVector; other.m_data.vec = new ModelValueVector;
break; break;
case Type::InlineArray:
m_data.array = other.m_data.array;
other.m_data.array = new ModelValueArray;
break;
} }
return *this; return *this;
} }
@ -1085,6 +1310,9 @@ constexpr void ModelValue::freeResources() noexcept {
case Type::Vector: case Type::Vector:
safeDelete(m_data.vec); safeDelete(m_data.vec);
break; break;
case Type::InlineArray:
safeDelete(m_data.array);
break;
} }
m_type = Type::Undefined; m_type = Type::Undefined;
} }

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -99,7 +99,7 @@ struct TypeInfoCatcher {
template<typename T> template<typename T>
constexpr int getModelTypeVersion(T *val) noexcept { constexpr int getModelTypeVersion(T *val) noexcept {
TypeInfoCatcher nc; TypeInfoCatcher nc;
oxIgnoreError(model(&nc, val)); std::ignore = model(&nc, val);
return nc.version; return nc.version;
} }
@ -122,7 +122,7 @@ consteval int requireModelTypeVersion() noexcept {
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr Str getModelTypeName(T *val) noexcept { constexpr Str getModelTypeName(T *val) noexcept {
TypeNameCatcher nc; TypeNameCatcher nc;
oxIgnoreError(model(&nc, val)); std::ignore = model(&nc, val);
return nc.name; return nc.name;
} }
@ -147,4 +147,12 @@ constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>(); constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
template<typename T>
constexpr auto ModelTypeId_v = [] {
constexpr auto name = ModelTypeName_v<T, ox::StringView>;
constexpr auto version = ModelTypeVersion_v<T>;
constexpr auto versionStr = ox::sfmt<ox::IString<19>>("{}", version);
return ox::sfmt<ox::IString<name.len() + versionStr.len() + 1>>("{};{}", name, versionStr);
}();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -21,7 +21,7 @@
#endif #endif
#include <ox/std/array.hpp> #include <ox/std/array.hpp>
#include <ox/std/bstring.hpp> #include <ox/std/istring.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/strops.hpp> #include <ox/std/strops.hpp>
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
@ -131,7 +131,12 @@ template<typename T, std::size_t sz>
constexpr bool isBareArray_v<T[sz]> = true; constexpr bool isBareArray_v<T[sz]> = true;
template<typename T> template<typename T>
constexpr bool isArray_v = false; consteval bool isArray(T*) noexcept {
return false;
}
template<typename T>
constexpr bool isArray_v = isArray(static_cast<T*>(nullptr));
template<typename T> template<typename T>
constexpr bool isArray_v<T[]> = true; constexpr bool isArray_v<T[]> = true;
@ -142,6 +147,16 @@ constexpr bool isArray_v<T[sz]> = true;
template<typename T, std::size_t sz> template<typename T, std::size_t sz>
constexpr bool isArray_v<Array<T, sz>> = true; constexpr bool isArray_v<Array<T, sz>> = true;
template<typename T, std::size_t sz>
consteval bool isArray(T[sz]) noexcept {
return true;
}
template<typename T, std::size_t sz>
consteval bool isArray(Array<T, sz>) noexcept {
return true;
}
template<typename T> template<typename T>
constexpr bool isSmartPtr_v = false; constexpr bool isSmartPtr_v = false;

View File

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

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -64,7 +64,7 @@ constexpr Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rd
template<typename Reader, typename T> template<typename Reader, typename T>
constexpr void DataWalker<Reader, T>::pushNamePath(const FieldName &fn) noexcept { constexpr void DataWalker<Reader, T>::pushNamePath(const FieldName &fn) noexcept {
m_path.push_back(fn); m_path.emplace_back(fn);
} }
template<typename Reader, typename T> template<typename Reader, typename T>

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -15,7 +15,7 @@ namespace ox {
OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) { OrganicClawReader::OrganicClawReader(const uint8_t *buff, std::size_t buffSize) {
auto json = reinterpret_cast<const char*>(buff); auto json = reinterpret_cast<const char*>(buff);
auto jsonLen = ox_strnlen(json, buffSize); auto jsonLen = ox::strnlen(json, buffSize);
Json::CharReaderBuilder parserBuilder; Json::CharReaderBuilder parserBuilder;
auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader()); auto parser = std::unique_ptr<Json::CharReader>(parserBuilder.newCharReader());
if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) { if (!parser->parse(json, json + jsonLen, &m_json, nullptr)) {
@ -198,7 +198,7 @@ Error OrganicClawReader::fieldCString(const char *key, char *val, std::size_t bu
if (strSize >= buffLen) { if (strSize >= buffLen) {
err = OxError(2, "String size exceeds capacity of destination"); err = OxError(2, "String size exceeds capacity of destination");
} else { } else {
ox_memcpy(data, begin, static_cast<std::size_t>(strSize)); ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0; data[strSize] = 0;
} }
} else { } else {
@ -224,7 +224,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val) noexcept {
const auto strSize = static_cast<std::size_t>(end - begin); const auto strSize = static_cast<std::size_t>(end - begin);
safeDelete(*val); safeDelete(*val);
*val = new char[strSize + 1]; *val = new char[strSize + 1];
ox_memcpy(data, begin, static_cast<std::size_t>(strSize)); ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0; data[strSize] = 0;
} else { } else {
err = OxError(1, "Type mismatch"); err = OxError(1, "Type mismatch");
@ -242,7 +242,7 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
if (jv.empty()) { if (jv.empty()) {
auto data = val; auto data = val;
if (data) { if (data) {
data[0] = 0; data[0] = nullptr;
} }
} else if (jv.isString()) { } else if (jv.isString()) {
jv.getString(&begin, &end); jv.getString(&begin, &end);
@ -252,8 +252,8 @@ Error OrganicClawReader::fieldCString(const char *key, char **val, std::size_t b
safeDelete(*val); safeDelete(*val);
*val = new char[strSize + 1]; *val = new char[strSize + 1];
} }
ox_memcpy(data, begin, static_cast<std::size_t>(strSize)); ox::memcpy(data, begin, static_cast<std::size_t>(strSize));
data[strSize] = 0; data[strSize] = nullptr;
} else { } else {
err = OxError(1, "Type mismatch"); err = OxError(1, "Type mismatch");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -70,7 +70,7 @@ class OrganicClawReader {
Error field(const char *key, BasicString<L> *val) noexcept; Error field(const char *key, BasicString<L> *val) noexcept;
template<std::size_t L> template<std::size_t L>
Error field(const char *key, BString<L> *val) noexcept; Error field(const char *key, IString<L> *val) noexcept;
Error fieldCString(const char *key, char *val, std::size_t buffLen) noexcept; Error fieldCString(const char *key, char *val, std::size_t buffLen) noexcept;
@ -206,7 +206,7 @@ Error OrganicClawReader::field(const char *key, BasicString<L> *val) noexcept {
} }
template<std::size_t L> template<std::size_t L>
Error OrganicClawReader::field(const char *key, BString<L> *val) noexcept { Error OrganicClawReader::field(const char *key, IString<L> *val) noexcept {
return fieldCString(key, val->data(), val->cap()); return fieldCString(key, val->data(), val->cap());
} }
@ -274,7 +274,7 @@ Result<T> readOC(const char *json, std::size_t jsonLen) noexcept {
template<typename T> template<typename T>
Result<T> readOC(const char *json) noexcept { Result<T> readOC(const char *json) noexcept {
return readOC<T>(json, ox_strlen(json)); return readOC<T>(json, ox::strlen(json));
} }
template<typename T> template<typename T>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -35,7 +35,7 @@ struct TestStructNest {
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
uint32_t Int = 0; uint32_t Int = 0;
ox::BString<32> String = ""; ox::IString<32> String = "";
}; };
struct TestStruct { struct TestStruct {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -27,7 +27,7 @@ Error OrganicClawWriter::fieldCString(const char *key, const char *const*val, in
} }
Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept { Error OrganicClawWriter::fieldCString(const char *key, const char *const*val) noexcept {
return fieldCString(key, const_cast<const char**>(val), static_cast<int>(ox_strlen(val))); return fieldCString(key, const_cast<const char**>(val), static_cast<int>(ox::strlen(val)));
} }
Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept { Error OrganicClawWriter::field(const char *key, const UUID *uuid) noexcept {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -27,7 +27,7 @@ class OrganicClawWriter {
friend Result<Buffer> writeOC(const auto &val) noexcept; friend Result<Buffer> writeOC(const auto &val) noexcept;
protected: protected:
Json::Value m_json; Json::Value m_json{Json::Value(Json::objectValue)};
Json::ArrayIndex m_fieldIt = 0; Json::ArrayIndex m_fieldIt = 0;
int m_unionIdx = -1; int m_unionIdx = -1;
@ -132,7 +132,7 @@ class OrganicClawWriter {
} }
template<std::size_t L> template<std::size_t L>
Error field(char const*key, BString<L> const*val) noexcept { Error field(char const*key, IString<L> const*val) noexcept {
if (targetValid() && val->len()) { if (targetValid() && val->len()) {
value(key) = val->c_str(); value(key) = val->c_str();
} }
@ -215,7 +215,7 @@ Error OrganicClawWriter::field(const char *key, const T *val) noexcept {
OrganicClawWriter w; OrganicClawWriter w;
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w}; ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
oxReturnError(model(&handler, val)); oxReturnError(model(&handler, val));
if (!w.m_json.isNull()) { if (!w.m_json.empty() || m_json.isArray()) {
value(key) = w.m_json; value(key) = w.m_json;
} }
} }

View File

@ -1,5 +1,9 @@
/* /*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2015 - 2024 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/.
*/ */
#pragma once #pragma once

View File

@ -1,10 +1,15 @@
/* /*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2015 - 2024 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/.
*/ */
#pragma once #pragma once
#include <ox/std/serialize.hpp> #include <ox/std/serialize.hpp>
#include <ox/std/string.hpp>
#include <ox/std/typetraits.hpp> #include <ox/std/typetraits.hpp>
#include "alignmentcatcher.hpp" #include "alignmentcatcher.hpp"
@ -47,7 +52,7 @@ constexpr std::size_t alignOf(const T &v) noexcept {
typename PlatSpec::PtrType p = 0; typename PlatSpec::PtrType p = 0;
return PlatSpec::alignOf(p); return PlatSpec::alignOf(p);
} else { } else {
AlignmentCatcher<NativePlatSpec> c; AlignmentCatcher<PlatSpec> c;
oxAssert(model(c.interface(), &v), "Could not get alignment for type"); oxAssert(model(c.interface(), &v), "Could not get alignment for type");
return c.biggestAlignment; return c.biggestAlignment;
} }

View File

@ -1,5 +1,9 @@
/* /*
* Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2015 - 2024 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 "preloader.hpp" #include "preloader.hpp"

View File

@ -1,5 +1,9 @@
/* /*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2015 - 2024 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/.
*/ */
#pragma once #pragma once
@ -10,10 +14,12 @@
#include <ox/std/error.hpp> #include <ox/std/error.hpp>
#include <ox/std/memops.hpp> #include <ox/std/memops.hpp>
#include <ox/std/memory.hpp> #include <ox/std/memory.hpp>
#include <ox/std/string.hpp>
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
#include <ox/std/typetraits.hpp> #include <ox/std/typetraits.hpp>
#include <ox/std/units.hpp> #include <ox/std/units.hpp>
#include <ox/model/modelhandleradaptor.hpp> #include <ox/model/modelhandleradaptor.hpp>
#include <ox/model/modelvalue.hpp>
#include "platspecs.hpp" #include "platspecs.hpp"
@ -58,6 +64,7 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
restore(pRestore), seekdir(pSeekdir) {} restore(pRestore), seekdir(pSeekdir) {}
}; };
ox::Vector<AllocStackItem, 8> m_allocStack; ox::Vector<AllocStackItem, 8> m_allocStack;
ox::Vector<size_t> m_allocStart{};
constexpr Preloader() noexcept: m_writer(&m_buff) {} constexpr Preloader() noexcept: m_writer(&m_buff) {}
@ -101,9 +108,9 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
template<typename T> template<typename T>
constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept; constexpr ox::Error field(CRStringView, const T **val, std::size_t cnt) noexcept;
constexpr ox::Result<std::size_t> startAlloc(std::size_t sz) noexcept; constexpr ox::Result<std::size_t> startAlloc(size_t sz, size_t align) noexcept;
constexpr ox::Result<std::size_t> startAlloc(std::size_t sz, std::size_t restore) noexcept; constexpr ox::Result<std::size_t> startAlloc(size_t sz, size_t align, std::size_t restore) noexcept;
constexpr ox::Error endAlloc() noexcept; constexpr ox::Error endAlloc() noexcept;
@ -125,6 +132,8 @@ class Preloader: public ModelHandlerBase<Preloader<PlatSpec>, OpType::Reflect> {
constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept; constexpr ox::Error fieldVector(CRStringView, const auto *val, ox::VectorMemMap<PlatSpec> vecVal) noexcept;
constexpr ox::Error fieldArray(CRStringView name, ox::ModelValueArray const*val) noexcept;
constexpr bool unionCheckAndIt() noexcept; constexpr bool unionCheckAndIt() noexcept;
}; };
@ -165,15 +174,19 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const T *val)
} }
oxReturnError(pad(val)); oxReturnError(pad(val));
if constexpr(ox::is_integral_v<T>) { if constexpr(ox::is_integral_v<T>) {
//oxDebugf("Preloader::field(name, val): {}", name); return ox::serialize(m_writer, PlatSpec::correctEndianness(*val));
return ox::serialize(&m_writer, PlatSpec::correctEndianness(*val));
} else if constexpr(ox::is_pointer_v<T>) { } else if constexpr(ox::is_pointer_v<T>) {
const PtrType a = startAlloc(sizeOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart; const PtrType a = startAlloc(sizeOf<PlatSpec>(val), alignOf<PlatSpec>(*val), m_writer.tellp()) + PlatSpec::RomStart;
oxReturnError(field(name, *val)); oxReturnError(field(name, *val));
oxReturnError(endAlloc()); oxReturnError(endAlloc());
return ox::serialize(&m_writer, PlatSpec::correctEndianness(a)); return ox::serialize(m_writer, PlatSpec::correctEndianness(a));
} else if constexpr(ox::isVector_v<T> || ox::is_same_v<T, ox::ModelValueVector>) { } else if constexpr(ox::isVector_v<T>) {
return fieldVector(name, val); return fieldVector(name, val);
} else if constexpr(ox::is_same_v<T, ox::ModelValueVector>) {
val->types();
return fieldVector(name, val);
} else if constexpr(ox::is_same_v<T, ox::ModelValueArray>) {
return fieldArray(name, val);
} else { } else {
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
const auto out = preload<PlatSpec, T>(this, val); const auto out = preload<PlatSpec, T>(this, val);
@ -199,7 +212,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
const auto restore = m_writer.tellp(); const auto restore = m_writer.tellp();
std::size_t a = 0; std::size_t a = 0;
if (sz && sz >= SmallStringSize) { if (sz && sz >= SmallStringSize) {
oxReturnError(ox::allocate(&m_writer, sz).moveTo(a)); oxReturnError(ox::allocate(m_writer, sz).moveTo(a));
} else { } else {
a = restore; a = restore;
} }
@ -207,7 +220,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const ox::BasicStri
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
oxReturnError(m_writer.write(val->data(), sz)); oxReturnError(m_writer.write(val->data(), sz));
oxReturnError(m_writer.seekp(restore)); oxReturnError(m_writer.seekp(restore));
oxReturnError(serialize(&m_writer, vecVal)); oxReturnError(serialize(m_writer, vecVal));
m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items); m_ptrs.emplace_back(restore + offsetof(VecMap, items), vecVal.items);
return {}; return {};
} }
@ -218,6 +231,7 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView name, const ox::Arra
if (!unionCheckAndIt()) { if (!unionCheckAndIt()) {
return {}; return {};
} }
oxReturnError(pad(&(*val)[0]));
// serialize the Array elements // serialize the Array elements
if constexpr(sz) { if constexpr(sz) {
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
@ -235,28 +249,40 @@ constexpr ox::Error Preloader<PlatSpec>::field(CRStringView, const T **val, std:
if (!unionCheckAndIt()) { if (!unionCheckAndIt()) {
return {}; return {};
} }
// serialize the array if (cnt) {
m_unionIdx.emplace_back(-1); oxReturnError(pad(*val));
for (std::size_t i = 0; i < cnt; ++i) { // serialize the array
oxReturnError(this->interface()->field(nullptr, &val[i])); m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < cnt; ++i) {
oxReturnError(this->interface()->field(nullptr, &val[i]));
}
m_unionIdx.pop_back();
} }
m_unionIdx.pop_back();
return {}; return {};
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz) noexcept { constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(size_t sz, size_t align) noexcept {
oxRequire(a, ox::allocate(&m_writer, sz));
m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp())); m_allocStack.emplace_back(static_cast<typename PlatSpec::PtrType>(m_writer.tellp()));
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
const auto padding = m_writer.tellp() % align;
oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding;
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a);
return a; return a;
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(std::size_t sz, std::size_t restore) noexcept { constexpr ox::Result<std::size_t> Preloader<PlatSpec>::startAlloc(
oxRequire(a, ox::allocate(&m_writer, sz)); std::size_t sz, size_t align, std::size_t restore) noexcept {
m_allocStack.emplace_back(restore, ox::ios_base::beg); m_allocStack.emplace_back(restore, ox::ios_base::beg);
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
const auto padding = m_writer.tellp() % align;
oxRequireM(a, ox::allocate(m_writer, sz + padding));
a += padding;
oxReturnError(m_writer.seekp(a)); oxReturnError(m_writer.seekp(a));
m_allocStart.push_back(a);
return a; return a;
} }
@ -268,6 +294,7 @@ constexpr ox::Error Preloader<PlatSpec>::endAlloc() noexcept {
const auto &si = *m_allocStack.back().unwrap(); const auto &si = *m_allocStack.back().unwrap();
oxReturnError(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir)); oxReturnError(m_writer.seekp(static_cast<ox::ssize_t>(si.restore), si.seekdir));
m_allocStack.pop_back(); m_allocStack.pop_back();
m_allocStart.pop_back();
return {}; return {};
} }
@ -275,8 +302,9 @@ template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept { constexpr ox::Error Preloader<PlatSpec>::offsetPtrs(std::size_t offset) noexcept {
for (const auto &p : m_ptrs) { for (const auto &p : m_ptrs) {
oxReturnError(m_writer.seekp(p.loc)); oxReturnError(m_writer.seekp(p.loc));
const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(static_cast<typename PlatSpec::PtrType>(p.value + offset)); const auto val = PlatSpec::template correctEndianness<typename PlatSpec::PtrType>(
oxReturnError(ox::serialize(&m_writer, val)); static_cast<typename PlatSpec::PtrType>(p.value + offset));
oxReturnError(ox::serialize(m_writer, val));
} }
oxReturnError(m_writer.seekp(0, ox::ios_base::end)); oxReturnError(m_writer.seekp(0, ox::ios_base::end));
return {}; return {};
@ -295,11 +323,12 @@ constexpr ox::Error Preloader<PlatSpec>::pad(const T *v) noexcept {
} }
template<typename PlatSpec> template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldVector(CRStringView name, const ox::ModelValueVector *val) noexcept { constexpr ox::Error Preloader<PlatSpec>::fieldVector(
CRStringView name, const ox::ModelValueVector *val) noexcept {
// serialize the Vector // serialize the Vector
ox::VectorMemMap<PlatSpec> vecVal{ ox::VectorMemMap<PlatSpec> vecVal{
.size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())), .size = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
.cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())), .cap = PlatSpec::correctEndianness(static_cast<typename PlatSpec::size_t>(val->size())),
}; };
return fieldVector(name, val, vecVal); return fieldVector(name, val, vecVal);
} }
@ -327,7 +356,11 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
// serialize the Vector elements // serialize the Vector elements
if (val->size()) { if (val->size()) {
const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size(); const auto sz = sizeOf<PlatSpec>(&(*val)[0]) * val->size();
oxRequire(p, ox::allocate(&m_writer, sz)); const auto align = alignOf<PlatSpec>((*val)[0]);
oxReturnError(m_writer.seekp(0, ox::ios_base::end));
const auto padding = m_writer.tellp() % align;
oxRequireM(p, ox::allocate(m_writer, sz + padding));
p += padding;
oxReturnError(m_writer.seekp(p)); oxReturnError(m_writer.seekp(p));
m_unionIdx.emplace_back(-1); m_unionIdx.emplace_back(-1);
for (std::size_t i = 0; i < val->size(); ++i) { for (std::size_t i = 0; i < val->size(); ++i) {
@ -341,11 +374,22 @@ constexpr ox::Error Preloader<PlatSpec>::fieldVector(
vecVal.items = 0; vecVal.items = 0;
} }
// serialize the Vector // serialize the Vector
oxReturnError(serialize(&m_writer, vecVal)); oxReturnError(serialize(m_writer, vecVal));
m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items); m_ptrs.emplace_back(m_writer.tellp() - PtrSize, vecVal.items);
return {}; return {};
} }
template<typename PlatSpec>
constexpr ox::Error Preloader<PlatSpec>::fieldArray(CRStringView, ox::ModelValueArray const*val) noexcept {
oxDebugf("array size: {}", val->size());
oxDebugf("array sizeOf: {}", sizeOf<PlatSpec>(val));
oxReturnError(pad(&(*val)[0]));
for (auto const&v : *val) {
oxReturnError(this->interface()->field({}, &v));
}
return {};
}
template<typename PlatSpec> template<typename PlatSpec>
constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept { constexpr bool Preloader<PlatSpec>::unionCheckAndIt() noexcept {
auto &u = *m_unionIdx.back().unwrap(); auto &u = *m_unionIdx.back().unwrap();

View File

@ -1,5 +1,9 @@
/* /*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2015 - 2024 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/.
*/ */
#pragma once #pragma once

View File

@ -1,5 +1,9 @@
/* /*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. * Copyright 2015 - 2024 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/.
*/ */
#pragma once #pragma once

View File

@ -81,6 +81,7 @@ target_link_libraries(
OxStd PUBLIC OxStd PUBLIC
$<$<CXX_COMPILER_ID:GNU>:gcc> $<$<CXX_COMPILER_ID:GNU>:gcc>
OxTraceHook OxTraceHook
CityHash
) )
install( install(
@ -90,7 +91,7 @@ install(
assert.hpp assert.hpp
bit.hpp bit.hpp
bounds.hpp bounds.hpp
bstring.hpp istring.hpp
buffer.hpp buffer.hpp
buildinfo.hpp buildinfo.hpp
byteswap.hpp byteswap.hpp
@ -103,8 +104,10 @@ install(
hardware.hpp hardware.hpp
hashmap.hpp hashmap.hpp
heapmgr.hpp heapmgr.hpp
ignore.hpp
iterator.hpp iterator.hpp
math.hpp math.hpp
maybeview.hpp
memops.hpp memops.hpp
memory.hpp memory.hpp
new.hpp new.hpp

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

109
deps/ox/src/ox/std/anyptr.hpp vendored Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright 2015 - 2024 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/.
*/
#pragma once
#include "assert.hpp"
#include "array.hpp"
#include "def.hpp"
#include "span.hpp"
namespace ox {
class AnyPtr {
private:
struct WrapBase {
virtual constexpr ~WrapBase() = default;
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
virtual constexpr operator bool() const noexcept = 0;
};
template<typename T>
struct Wrap: public WrapBase {
T *data{};
constexpr Wrap(T *pData) noexcept: data(pData) {
}
constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override {
oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
if (std::is_constant_evaluated()) {
return new Wrap(data);
} else {
return new(s.data()) Wrap(data);
}
}
constexpr operator bool() const noexcept override {
return data != nullptr;
}
};
WrapBase *m_wrapPtr{};
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData;
public:
constexpr AnyPtr() noexcept = default;
template<typename T>
constexpr AnyPtr(T *ptr) noexcept {
if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap(ptr);
} else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
}
}
constexpr AnyPtr(AnyPtr const&other) noexcept {
if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
}
}
constexpr ~AnyPtr() noexcept {
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
}
}
template<typename T>
constexpr AnyPtr &operator=(T *ptr) noexcept {
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
m_wrapPtr = new Wrap(ptr);
} else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
}
return *this;
}
constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept {
if (this != &ptr) {
if (ptr) {
ox::safeDelete(m_wrapPtr);
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
} else {
m_wrapPtr = nullptr;
}
}
return *this;
}
constexpr operator bool() const noexcept {
return m_wrapPtr && *m_wrapPtr;
}
template<typename T>
[[nodiscard]]
constexpr T *get() const noexcept {
#ifdef OX_BARE_METAL
return static_cast<Wrap<T>*>(m_wrapPtr)->data;
#else
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
#endif
}
};
}

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -13,7 +13,6 @@
#include "initializerlist.hpp" #include "initializerlist.hpp"
#include "iterator.hpp" #include "iterator.hpp"
#include "math.hpp" #include "math.hpp"
#include "memory.hpp"
#include "new.hpp" #include "new.hpp"
#include "types.hpp" #include "types.hpp"
#include "utility.hpp" #include "utility.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "stacktrace.hpp" #include "stacktrace.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
@ -131,7 +131,7 @@ class BaseStringView {
constexpr explicit BaseStringView(std::nullptr_t) noexcept {} constexpr explicit BaseStringView(std::nullptr_t) noexcept {}
constexpr explicit BaseStringView(const char *str) noexcept: m_str(str), m_len(str ? ox_strlen(str) : 0) {} constexpr explicit BaseStringView(const char *str) noexcept: m_str(str), m_len(str ? ox::strlen(str) : 0) {}
constexpr explicit BaseStringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {} constexpr explicit BaseStringView(const char *str, std::size_t len) noexcept: m_str(str), m_len(len) {}

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "bit.hpp" #include "bit.hpp"

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
@ -34,7 +34,7 @@ namespace ox {
template<typename To, typename From> template<typename To, typename From>
constexpr typename enable_if<sizeof(To) == sizeof(From), To>::type cbit_cast(From src) noexcept { constexpr typename enable_if<sizeof(To) == sizeof(From), To>::type cbit_cast(From src) noexcept {
To dst = {}; To dst = {};
ox_memcpy(&dst, &src, sizeof(src)); ox::memcpy(&dst, &src, sizeof(src));
return dst; return dst;
} }

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2023 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once

View File

@ -1,281 +0,0 @@
/*
* Copyright 2015 - 2022 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 http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "memops.hpp"
#include "stringview.hpp"
#include "strops.hpp"
#include "typetraits.hpp"
namespace ox {
// Bounded String
template<std::size_t buffLen>
class BString {
private:
char m_buff[buffLen + 1];
public:
constexpr BString() noexcept;
constexpr BString(StringView str) noexcept;
constexpr BString(const char *str) noexcept;
constexpr BString &operator=(CRStringView str) noexcept;
constexpr BString &operator=(const char *str) noexcept;
constexpr BString &operator=(char *str) noexcept;
constexpr BString &operator=(Integer_c auto i) noexcept;
constexpr BString &operator+=(const char *str) noexcept;
constexpr BString &operator+=(char *str) noexcept;
constexpr BString &operator+=(Integer_c auto i) noexcept;
constexpr BString &operator+=(StringView s) noexcept;
constexpr BString operator+(const char *str) const noexcept;
constexpr BString operator+(char *str) const noexcept;
constexpr BString operator+(Integer_c auto i) const noexcept;
constexpr bool operator==(const char *other) const noexcept;
constexpr bool operator==(const OxString_c auto &other) const noexcept;
constexpr bool operator!=(const char *other) const noexcept;
constexpr bool operator!=(const OxString_c auto &other) noexcept;
constexpr char operator[](std::size_t i) const noexcept;
constexpr char &operator[](std::size_t i) noexcept;
constexpr Error append(const char *str, std::size_t strLen) noexcept;
[[nodiscard]]
constexpr const char *data() const noexcept;
[[nodiscard]]
constexpr char *data() noexcept;
[[nodiscard]]
constexpr const char *c_str() const noexcept;
/**
* Returns the number of characters in this string.
*/
[[nodiscard]]
constexpr std::size_t len() const noexcept;
/**
* Returns the number of bytes used for this string.
*/
[[nodiscard]]
constexpr std::size_t bytes() const noexcept;
/**
* Returns the capacity of bytes for this string.
*/
[[nodiscard]]
constexpr std::size_t cap() const noexcept;
};
template<std::size_t size>
constexpr BString<size>::BString() noexcept: m_buff{{0}} {
}
template<std::size_t size>
constexpr BString<size>::BString(StringView str) noexcept: m_buff{{0}} {
operator=(str);
}
template<std::size_t size>
constexpr BString<size>::BString(const char *str) noexcept: m_buff{{0}} {
operator=(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(Integer_c auto i) noexcept {
char str[65] = {};
ox_itoa(i, str);
return this->operator=(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(ox::CRStringView str) noexcept {
std::size_t strLen = str.bytes() + 1;
if (cap() < strLen) {
strLen = cap();
}
ox_memcpy(m_buff, str.data(), strLen);
// make sure last element is a null terminator
m_buff[strLen] = 0;
return *this;
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(const char *str) noexcept {
std::size_t strLen = ox_strlen(str) + 1;
if (cap() < strLen) {
strLen = cap();
}
ox_memcpy(m_buff, str, strLen);
// make sure last element is a null terminator
m_buff[cap()] = 0;
return *this;
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator=(char *str) noexcept {
return *this = static_cast<const char*>(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(const char *str) noexcept {
std::size_t strLen = ox_strlen(str) + 1;
oxIgnoreError(append(str, strLen));
return *this;
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(char *str) noexcept {
return *this += static_cast<const char*>(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(Integer_c auto i) noexcept {
char str[65] = {};
ox_itoa(i, str);
return this->operator+=(str);
}
template<std::size_t size>
constexpr BString<size> &BString<size>::operator+=(StringView s) noexcept {
std::size_t strLen = s.bytes();
oxIgnoreError(append(s.data(), strLen));
return *this;
}
template<std::size_t size>
constexpr BString<size> BString<size>::operator+(const char *str) const noexcept {
auto out = *this;
std::size_t strLen = ox_strlen(str) + 1;
oxIgnoreError(out.append(str, strLen));
return out;
}
template<std::size_t size>
constexpr BString<size> BString<size>::operator+(char *str) const noexcept {
return *this + static_cast<const char*>(str);
}
template<std::size_t size>
constexpr BString<size> BString<size>::operator+(Integer_c auto i) const noexcept {
char str[65] = {};
ox_itoa(i, str);
return this->operator+(str);
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator==(const char *other) const noexcept {
return ox::StringView(*this) == other;
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator==(const OxString_c auto &other) const noexcept {
return ox::StringView(*this) == ox::StringView(other);
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator!=(const char *other) const noexcept {
return !operator==(other);
}
template<std::size_t buffLen>
constexpr bool BString<buffLen>::operator!=(const OxString_c auto &other) noexcept {
return !operator==(other);
}
template<std::size_t buffLen>
constexpr char BString<buffLen>::operator[](std::size_t i) const noexcept {
return m_buff[i];
}
template<std::size_t buffLen>
constexpr char &BString<buffLen>::operator[](std::size_t i) noexcept {
return m_buff[i];
}
template<std::size_t buffLen>
constexpr Error BString<buffLen>::append(const char *str, std::size_t strLen) noexcept {
Error err;
auto currentLen = len();
if (cap() < currentLen + strLen + 1) {
strLen = cap() - currentLen;
err = OxError(1, "Insufficient space for full string");
}
ox_strncpy(m_buff + currentLen, str, strLen);
// make sure last element is a null terminator
m_buff[currentLen + strLen] = 0;
return err;
}
template<std::size_t buffLen>
constexpr const char *BString<buffLen>::data() const noexcept {
return static_cast<const char*>(m_buff);
}
template<std::size_t buffLen>
constexpr char *BString<buffLen>::data() noexcept {
return static_cast<char*>(m_buff);
}
template<std::size_t buffLen>
constexpr const char *BString<buffLen>::c_str() const noexcept {
return static_cast<const char*>(m_buff);
}
template<std::size_t buffLen>
constexpr std::size_t BString<buffLen>::len() const noexcept {
std::size_t length = 0;
for (std::size_t i = 0; i < buffLen; i++) {
uint8_t b = static_cast<uint8_t>(m_buff[i]);
if (b) {
const auto asciiChar = (b & 128) == 0;
const auto utf8Char = (b & (256 << 6)) == (256 << 6);
if (asciiChar || utf8Char) {
length++;
}
} else {
break;
}
}
return length;
}
template<std::size_t buffLen>
constexpr std::size_t BString<buffLen>::bytes() const noexcept {
std::size_t i = 0;
for (i = 0; i < buffLen && m_buff[i]; i++);
return i + 1; // add one for null terminator
}
template<std::size_t buffLen>
constexpr std::size_t BString<buffLen>::cap() const noexcept {
return buffLen;
}
}

View File

@ -1,9 +1,9 @@
/* /*
* Copyright 2015 - 2022 gary@drinkingtea.net * Copyright 2015 - 2024 gary@drinkingtea.net
* *
* This Source Code Form is subject to the terms of the Mozilla Public * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
#include "error.hpp" #include "error.hpp"

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