summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-07-20 17:02:05 +0200
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-07-20 17:02:05 +0200
commitfac9e8bec1983fa9dff8f447fef106e427dfec26 (patch)
tree2221d4216873fa8250dd5ff45f00d0d6b46eab26 /src
parent398164432abcf599eaa51ebc4088024b7f46b97f (diff)
c++: Renamed src to c++
Diffstat (limited to 'src')
-rw-r--r--src/SConscript8
-rw-r--r--src/async/.nix/derivation.nix30
-rw-r--r--src/async/SConscript38
-rw-r--r--src/async/SConstruct66
-rw-r--r--src/async/async.cpp419
-rw-r--r--src/async/async.h1023
-rw-r--r--src/async/async.tmpl.h767
-rw-r--r--src/codec-json/.nix/derivation.nix32
-rw-r--r--src/codec-json/SConscript38
-rw-r--r--src/codec-json/SConstruct66
-rw-r--r--src/codec-json/json.h116
-rw-r--r--src/codec-json/json.tmpl.h734
-rw-r--r--src/codec/.nix/derivation.nix30
-rw-r--r--src/codec/SConscript38
-rw-r--r--src/codec/SConstruct66
-rw-r--r--src/codec/data.h317
-rw-r--r--src/codec/forst.h13
-rw-r--r--src/codec/schema.h93
-rw-r--r--src/codec/simple.h389
-rw-r--r--src/codec/stream_value.h64
-rw-r--r--src/core/.nix/derivation.nix23
-rw-r--r--src/core/SConscript38
-rw-r--r--src/core/SConstruct66
-rw-r--r--src/core/buffer.cpp436
-rw-r--r--src/core/buffer.h199
-rw-r--r--src/core/common.h75
-rw-r--r--src/core/error.cpp156
-rw-r--r--src/core/error.h248
-rw-r--r--src/core/string_literal.h40
-rw-r--r--src/core/templates.h76
-rw-r--r--src/io-tls/.nix/derivation.nix34
-rw-r--r--src/io-tls/SConscript38
-rw-r--r--src/io-tls/SConstruct66
-rw-r--r--src/io-tls/tls.cpp252
-rw-r--r--src/io-tls/tls.h68
-rw-r--r--src/io/.nix/derivation.nix31
-rw-r--r--src/io/SConscript38
-rw-r--r--src/io/SConstruct66
-rw-r--r--src/io/io.cpp70
-rw-r--r--src/io/io.h219
-rw-r--r--src/io/io_helpers.cpp85
-rw-r--r--src/io/io_helpers.h53
-rw-r--r--src/io/io_unix.cpp894
-rw-r--r--src/io_codec/.nix/derivation.nix33
-rw-r--r--src/io_codec/SConscript38
-rw-r--r--src/io_codec/SConstruct66
-rw-r--r--src/io_codec/io_peer.h104
-rw-r--r--src/io_codec/io_peer.tmpl.h117
-rw-r--r--src/test/.nix/derivation.nix30
-rw-r--r--src/test/SConscript33
-rw-r--r--src/test/SConstruct66
-rw-r--r--src/test/suite.cpp107
-rw-r--r--src/test/suite.h43
-rw-r--r--src/window-opengl/.nix/derivation.nix37
-rw-r--r--src/window-opengl/SConscript38
-rw-r--r--src/window-opengl/SConstruct66
-rw-r--r--src/window/.nix/derivation.nix36
-rw-r--r--src/window/SConscript38
-rw-r--r--src/window/SConstruct66
-rw-r--r--src/window/backends.h10
-rw-r--r--src/window/device.h18
-rw-r--r--src/window/linux_xcb.h5
-rw-r--r--src/window/old.dummy399
-rw-r--r--src/window/video_mode.h11
-rw-r--r--src/window/window.h79
-rw-r--r--src/window/xcb.cpp238
-rw-r--r--src/window/xcb.h91
67 files changed, 0 insertions, 9387 deletions
diff --git a/src/SConscript b/src/SConscript
deleted file mode 100644
index 8da5a3d..0000000
--- a/src/SConscript
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/false
-
-Import('env')
-
-# Export to other libs
-Export('env');
-SConscript('core/SConscript');
-SConscript('async/SConscript');
diff --git a/src/async/.nix/derivation.nix b/src/async/.nix/derivation.nix
deleted file mode 100644
index b1c6ecc..0000000
--- a/src/async/.nix/derivation.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-async";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/async/SConscript b/src/async/SConscript
deleted file mode 100644
index 69f8950..0000000
--- a/src/async/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-async_env = env.Clone();
-
-async_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-async_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += async_env.sources;
-env.headers += async_env.headers;
-
-## Shared lib
-objects_shared = []
-async_env.add_source_files(objects_shared, async_env.sources, shared=True);
-async_env.library_shared = async_env.SharedLibrary('#build/forstio-async', [objects_shared]);
-
-## Static lib
-objects_static = []
-async_env.add_source_files(objects_static, async_env.sources, shared=False);
-async_env.library_static = async_env.StaticLibrary('#build/forstio-async', [objects_static]);
-
-# Set Alias
-env.Alias('library_async', [async_env.library_shared, async_env.library_static]);
-
-env.targets += ['library_async'];
-
-# Install
-env.Install('$prefix/lib/', [async_env.library_shared, async_env.library_static]);
-env.Install('$prefix/include/forstio/async/', [async_env.headers]);
diff --git a/src/async/SConstruct b/src/async/SConstruct
deleted file mode 100644
index 0d7b7c6..0000000
--- a/src/async/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-core'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/async/async.cpp b/src/async/async.cpp
deleted file mode 100644
index 360e455..0000000
--- a/src/async/async.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-#include "async.h"
-#include <forstio/core/common.h>
-#include <forstio/core/error.h>
-
-#include <algorithm>
-#include <cassert>
-
-namespace saw {
-namespace {
-thread_local event_loop *local_loop = nullptr;
-
-event_loop &current_event_loop() {
- event_loop *loop = local_loop;
- assert(loop);
- return *loop;
-}
-} // namespace
-
-conveyor_node::conveyor_node() {}
-
-conveyor_node_with_child_mixin::conveyor_node_with_child_mixin(
- own<conveyor_node> &&child_, conveyor_node &owner)
- : child{std::move(child_)} {
- assert(child);
-
- child->notify_parent_attached(owner);
-}
-
-error_or<own<conveyor_node>>
-conveyor_node_with_child_mixin::swap_child(own<conveyor_node> &&swapee) {
- SAW_ASSERT(child) {
- return make_error<err::invalid_state>("Child should exist if this function is called");
- }
- own<conveyor_node> old_child = std::move(child);
-
- /**
- * We need the parent of the old_child's next storage
- */
- conveyor_storage *old_storage = old_child->next_storage();
- conveyor_storage *old_storage_parent =
- old_storage ? old_storage->get_parent() : nullptr;
-
- /**
- * Swap in the new child
- */
- if (swapee) {
- child = std::move(swapee);
-
- /**
- * Then we need to set the new child's storage parent since the next
- * storage has a nullptr set And if the old_storage_parent is a nullptr,
- * then it doesn't matter. So we don't check for it
- */
- conveyor_storage *swapee_storage = child->next_storage();
- if (swapee_storage) {
- swapee_storage->set_parent(old_storage_parent);
- }
- }
-
- return old_child;
-}
-
-conveyor_storage::conveyor_storage() {}
-
-conveyor_storage::~conveyor_storage() {}
-
-conveyor_storage *conveyor_storage::get_parent() const { return parent_; }
-
-void conveyor_event_storage::set_parent(conveyor_storage *p) {
- /*
- * parent check isn't needed, but is used
- * for the assert, because the storage should
- * be armed if there was an element present
- * and a valid parent
- */
- if (/*!parent && */ p && !is_armed() && queued() > 0) {
- assert(!parent_);
- if (p->space() > 0) {
- arm_later();
- }
- }
-
- parent_ = p;
-}
-
-conveyor_event_storage::conveyor_event_storage() : conveyor_storage{} {}
-
-conveyor_base::conveyor_base(own<conveyor_node> &&node_p)
- : node_{std::move(node_p)} {}
-
-error propagate_error::operator()(const error &error) const {
- return error.copy_error();
-}
-
-error propagate_error::operator()(error &&err) { return std::move(err); }
-
-event::event() : event(current_event_loop()) {}
-
-event::event(event_loop &loop) : loop_{loop} {}
-
-event::~event() { disarm(); }
-
-void event::arm_next() {
- assert(&loop_ == local_loop);
- if (prev_ == nullptr) {
- // Push the next_insert_point back by one
- // and inserts itself before that
- next_ = *loop_.next_insert_point_;
- prev_ = loop_.next_insert_point_;
- *prev_ = this;
- if (next_) {
- next_->prev_ = &next_;
- }
-
- // Set the new insertion ptr location to next
- loop_.next_insert_point_ = &next_;
-
- // Pushes back the later insert point if it was pointing at the
- // previous event
- if (loop_.later_insert_point_ == prev_) {
- loop_.later_insert_point_ = &next_;
- }
-
- // If tail_ points at the same location then
- // we are at the end and have to update tail_ then.
- // Technically should be possible by checking if
- // next is a `nullptr`
- if (loop_.tail_ == prev_) {
- loop_.tail_ = &next_;
- }
-
- loop_.set_runnable(true);
- }
-}
-
-void event::arm_later() {
- assert(&loop_ == local_loop);
-
- if (prev_ == nullptr) {
- next_ = *loop_.later_insert_point_;
- prev_ = loop_.later_insert_point_;
- *prev_ = this;
- if (next_) {
- next_->prev_ = &next_;
- }
-
- loop_.later_insert_point_ = &next_;
- if (loop_.tail_ == prev_) {
- loop_.tail_ = &next_;
- }
-
- loop_.set_runnable(true);
- }
-}
-
-void event::arm_last() {
- assert(&loop_ == local_loop);
-
- if (prev_ == nullptr) {
- next_ = *loop_.later_insert_point_;
- prev_ = loop_.later_insert_point_;
- *prev_ = this;
- if (next_) {
- next_->prev_ = &next_;
- }
-
- if (loop_.tail_ == prev_) {
- loop_.tail_ = &next_;
- }
-
- loop_.set_runnable(true);
- }
-}
-
-void event::disarm() {
- if (prev_ != nullptr) {
- if (loop_.tail_ == &next_) {
- loop_.tail_ = prev_;
- }
-
- if (loop_.next_insert_point_ == &next_) {
- loop_.next_insert_point_ = prev_;
- }
-
- *prev_ = next_;
- if (next_) {
- next_->prev_ = prev_;
- }
-
- prev_ = nullptr;
- next_ = nullptr;
- }
-}
-
-bool event::is_armed() const { return prev_ != nullptr; }
-
-conveyor_sink::conveyor_sink() : node_{nullptr} {}
-
-conveyor_sink::conveyor_sink(own<conveyor_node> &&node_p)
- : node_{std::move(node_p)} {}
-
-void event_loop::set_runnable(bool runnable) { is_runnable_ = runnable; }
-
-event_loop::event_loop() {}
-
-event_loop::event_loop(own<class event_port> &&ep)
- : event_port_{std::move(ep)} {}
-
-event_loop::~event_loop() { assert(local_loop != this); }
-
-void event_loop::enter_scope() {
- assert(!local_loop);
- local_loop = this;
-}
-
-void event_loop::leave_scope() {
- assert(local_loop == this);
- local_loop = nullptr;
-}
-
-bool event_loop::turn_loop() {
- size_t turn_step = 0;
- while (head_ && turn_step < 65536) {
- if (!turn()) {
- return false;
- }
- ++turn_step;
- }
- return true;
-}
-
-bool event_loop::turn() {
- event *event = head_;
-
- if (!event) {
- return false;
- }
-
- head_ = event->next_;
- if (head_) {
- head_->prev_ = &head_;
- }
-
- next_insert_point_ = &head_;
- if (later_insert_point_ == &event->next_) {
- later_insert_point_ = &head_;
- }
- if (tail_ == &event->next_) {
- tail_ = &head_;
- }
-
- event->next_ = nullptr;
- event->prev_ = nullptr;
-
- next_insert_point_ = &head_;
-
- event->fire();
-
- return true;
-}
-
-bool event_loop::wait(const std::chrono::steady_clock::duration &duration) {
- if (event_port_) {
- event_port_->wait(duration);
- }
-
- return turn_loop();
-}
-
-bool event_loop::wait(const std::chrono::steady_clock::time_point &time_point) {
- if (event_port_) {
- event_port_->wait(time_point);
- }
-
- return turn_loop();
-}
-
-bool event_loop::wait() {
- if (event_port_) {
- event_port_->wait();
- }
-
- return turn_loop();
-}
-
-bool event_loop::poll() {
- if (event_port_) {
- event_port_->poll();
- }
-
- return turn_loop();
-}
-
-event_port *event_loop::get_event_port() { return event_port_.get(); }
-
-conveyor_sink_set &event_loop::daemon() {
- if (!daemon_sink_) {
- daemon_sink_ = heap<conveyor_sink_set>();
- }
- return *daemon_sink_;
-}
-
-wait_scope::wait_scope(event_loop &loop) : loop_{loop} { loop_.enter_scope(); }
-
-wait_scope::~wait_scope() { loop_.leave_scope(); }
-
-void wait_scope::wait() { loop_.wait(); }
-
-void wait_scope::wait(const std::chrono::steady_clock::duration &duration) {
- loop_.wait(duration);
-}
-
-void wait_scope::wait(const std::chrono::steady_clock::time_point &time_point) {
- loop_.wait(time_point);
-}
-
-void wait_scope::poll() { loop_.poll(); }
-
-error_or<own<conveyor_node>>
-convert_conveyor_node_base::swap_child(own<conveyor_node> &&swapee) noexcept {
- return child_mixin_.swap_child(std::move(swapee));
-}
-
-conveyor_storage *convert_conveyor_node_base::next_storage() noexcept {
- if (!child_mixin_.child) {
- return nullptr;
- }
- return child_mixin_.child->next_storage();
-}
-
-immediate_conveyor_node_base::immediate_conveyor_node_base()
- : conveyor_event_storage{} {}
-
-merge_conveyor_node_base::merge_conveyor_node_base()
- : conveyor_event_storage{} {}
-
-error_or<own<conveyor_node>> queue_buffer_conveyor_node_base::swap_child(
- own<conveyor_node> &&swapee_) noexcept {
- return child_mixin_.swap_child(std::move(swapee_));
-}
-
-void conveyor_sink_set::destroy_sink_conveyor_node(conveyor_node &node) {
- if (!is_armed()) {
- arm_last();
- }
-
- delete_nodes_.push(&node);
-}
-
-void conveyor_sink_set::fail(error &&error) {
- /// @todo call error_handler
-}
-
-conveyor_sink_set::conveyor_sink_set(event_loop &event_loop)
- : event{event_loop} {}
-
-void conveyor_sink_set::add(conveyor<void> &&sink) {
- auto nas = conveyor<void>::from_conveyor(std::move(sink));
- SAW_ASSERT(nas) { return; }
- conveyor_storage *storage = nas->next_storage();
-
- own<sink_conveyor_node> sink_node = nullptr;
- try {
- sink_node = heap<sink_conveyor_node>(std::move(nas), *this);
- } catch (std::bad_alloc &) {
- return;
- }
- if (storage) {
- storage->set_parent(sink_node.get());
- }
-
- sink_nodes_.emplace_back(std::move(sink_node));
-}
-
-void conveyor_sink_set::fire() {
- while (!delete_nodes_.empty()) {
- conveyor_node *node = delete_nodes_.front();
- /*auto erased = */ std::remove_if(sink_nodes_.begin(),
- sink_nodes_.end(),
- [node](own<conveyor_node> &element) {
- return node == element.get();
- });
- delete_nodes_.pop();
- }
-}
-
-convert_conveyor_node_base::convert_conveyor_node_base(own<conveyor_node> &&dep)
- : child_mixin_{std::move(dep), *this} {}
-
-void convert_conveyor_node_base::get_result(error_or_value &err_or_val) {
- get_impl(err_or_val);
-}
-
-void attach_conveyor_node_base::get_result(
- error_or_value &err_or_val) noexcept {
- if (child_mixin_.child) {
- child_mixin_.child->get_result(err_or_val);
- }
-}
-
-error_or<own<conveyor_node>>
-attach_conveyor_node_base::swap_child(own<conveyor_node> &&swapee_) noexcept {
- return child_mixin_.swap_child(std::move(swapee_));
-}
-
-conveyor_storage *attach_conveyor_node_base::next_storage() noexcept {
- if (!child_mixin_.child) {
- return nullptr;
- }
-
- return child_mixin_.child->next_storage();
-}
-
-void detach_conveyor(conveyor<void> &&conveyor) {
- event_loop &loop = current_event_loop();
- conveyor_sink_set &sink = loop.daemon();
- sink.add(std::move(conveyor));
-}
-} // namespace saw
diff --git a/src/async/async.h b/src/async/async.h
deleted file mode 100644
index 8190be0..0000000
--- a/src/async/async.h
+++ /dev/null
@@ -1,1023 +0,0 @@
-#pragma once
-
-#include <forstio/core/common.h>
-#include <forstio/core/error.h>
-
-#include <chrono>
-#include <functional>
-#include <limits>
-#include <list>
-#include <queue>
-#include <type_traits>
-
-namespace saw {
-class conveyor_storage;
-class conveyor_node {
-public:
- conveyor_node();
- virtual ~conveyor_node() = default;
-
- /**
- * Internal method to retrieve results from children
- */
- virtual void get_result(error_or_value &err_or_val) = 0;
-
- /**
- * Swap out child with another one
- */
- virtual error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee_) = 0;
-
- /**
- * Retrieve the next storage node
- */
- virtual conveyor_storage *next_storage() = 0;
-
- /**
- * Notify that a new parent was attached
- * Only relevant for the feeding nodes
- */
- virtual void notify_parent_attached(conveyor_node &){};
-};
-
-class conveyor_node_with_child_mixin final {
-public:
- own<conveyor_node> child = nullptr;
-
- conveyor_node_with_child_mixin(own<conveyor_node> &&child_,
- conveyor_node &owner_);
- ~conveyor_node_with_child_mixin() = default;
-
- /**
- * Swap out children and return the child ptr, since the caller is the child
- * itself. Stack needs to be cleared before the child is destroyed, so the
- * swapped out node is returned as well.
- */
- error_or<own<conveyor_node>> swap_child(own<conveyor_node> &&swapee);
-};
-
-class conveyor_node_with_parent_mixin final {
-public:
- conveyor_node *parent = nullptr;
-
- error_or<own<conveyor_node>>
- swap_child_of_parent(own<conveyor_node> &&swapee) {
- SAW_ASSERT(parent) {
- return make_error<err::invalid_state>(
- "Can't swap child, because parent doesn't exist");
- }
-
- return parent->swap_child(std::move(swapee));
- }
- void change_parent(conveyor_node *p) { parent = p; }
-};
-
-class event_loop;
-class wait_scope;
-/*
- * Event class similar to capn'proto.
- * https://github.com/capnproto/capnproto
- */
-class event {
-private:
- event_loop &loop_;
- event **prev_ = nullptr;
- event *next_ = nullptr;
-
- friend class event_loop;
-
-public:
- event();
- event(event_loop &loop);
- virtual ~event();
-
- virtual void fire() = 0;
-
- void arm_next();
- void arm_later();
- void arm_last();
- void disarm();
-
- bool is_armed() const;
-};
-
-class conveyor_storage {
-protected:
- conveyor_storage *parent_ = nullptr;
-
-public:
- conveyor_storage();
- virtual ~conveyor_storage();
-
- virtual size_t space() const = 0;
- virtual size_t queued() const = 0;
- virtual void child_has_fired() = 0;
- virtual void parent_has_fired() = 0;
-
- virtual void set_parent(conveyor_storage *parent) = 0;
- conveyor_storage *get_parent() const;
-};
-
-class conveyor_event_storage : public conveyor_storage, public event {
-public:
- conveyor_event_storage();
- virtual ~conveyor_event_storage() = default;
-
- void set_parent(conveyor_storage *parent) override;
-};
-
-class conveyor_base {
-protected:
- own<conveyor_node> node_;
-
-public:
- conveyor_base(own<conveyor_node> &&node_p);
- virtual ~conveyor_base() = default;
-
- conveyor_base(conveyor_base &&) = default;
- conveyor_base &operator=(conveyor_base &&) = default;
-
- void get(error_or_value &err_or_val);
-};
-
-template <typename T> class conveyor;
-
-template <typename T> conveyor<T> chained_conveyor_type(T *);
-
-// template <typename T> Conveyor<T> chainedConveyorType(Conveyor<T> *);
-
-template <typename T> T remove_error_or_type(T *);
-
-template <typename T> T remove_error_or_type(error_or<T> *);
-
-template <typename T>
-using remove_error_or = decltype(remove_error_or_type((T *)nullptr));
-
-template <typename T>
-using chained_conveyors = decltype(chained_conveyor_type((T *)nullptr));
-
-template <typename Func, typename T>
-using conveyor_result =
- chained_conveyors<remove_error_or<return_type<Func, T>>>;
-
-struct propagate_error {
-public:
- error operator()(const error &err) const;
- error operator()(error &&err);
-};
-
-class conveyor_sink {
-private:
- own<conveyor_node> node_;
-
-public:
- conveyor_sink();
- conveyor_sink(own<conveyor_node> &&node);
-
- conveyor_sink(conveyor_sink &&) = default;
- conveyor_sink &operator=(conveyor_sink &&) = default;
-};
-
-template <typename T> class merge_conveyor_node_data;
-
-template <typename T> class merge_conveyor {
-private:
- lent<merge_conveyor_node_data<T>> data_;
-
-public:
- merge_conveyor() = default;
- merge_conveyor(lent<merge_conveyor_node_data<T>> d);
- ~merge_conveyor();
-
- void attach(conveyor<T> conv);
-};
-
-/**
- * Main interface for async operations.
- */
-template <typename T> class conveyor final : public conveyor_base {
-public:
- /**
- * Construct an immediately fulfilled node
- */
- conveyor(fix_void<T> value);
-
- /**
- * Construct an immediately failed node
- */
- conveyor(error &&err);
-
- /**
- * Construct a conveyor with a child node
- */
- conveyor(own<conveyor_node> node_p);
-
- conveyor(conveyor<T> &&) = default;
- conveyor<T> &operator=(conveyor<T> &&) = default;
-
- /**
- * This method converts values or errors from children
- */
- template <typename Func, typename ErrorFunc = propagate_error>
- [[nodiscard]] conveyor_result<Func, T>
- then(Func &&func, ErrorFunc &&error_func = propagate_error());
-
- /**
- * This method adds a buffer node in the conveyor chains which acts as a
- * scheduler interrupt point and collects elements up to the supplied limit.
- */
- [[nodiscard]] conveyor<T>
- buffer(size_t limit = std::numeric_limits<size_t>::max());
-
- /**
- * This method just takes ownership of any supplied types,
- * which are destroyed when the chain gets destroyed.
- * Useful for resource lifetime control.
- */
- template <typename... Args>
- [[nodiscard]] conveyor<T> attach(Args &&...args);
-
- /** @todo implement
- * This method limits the total amount of passed elements
- * Be careful where you place this node into the chain.
- * If you meant to fork it and destroy paths you shouldn't place
- * an interrupt point between the fork and this limiter
- */
- [[nodiscard]] conveyor<T> limit(size_t val = 1);
-
- /**
- *
- */
- [[nodiscard]] std::pair<conveyor<T>, merge_conveyor<T>> merge();
-
- /**
- * Moves the conveyor chain into a thread local storage point which drops
- * every element. Use sink() if you want to control the lifetime of a
- * conveyor chain
- */
- template <typename ErrorFunc = propagate_error>
- void detach(ErrorFunc &&err_func = propagate_error());
- /**
- * Creates a local sink which drops elements, but lifetime control remains
- * in your hand.
- */
- template <typename ErrorFunc = propagate_error>
- [[nodiscard]] conveyor_sink
- sink(ErrorFunc &&error_func = propagate_error());
-
- /**
- * If no sink() or detach() is used you have to take elements out of the
- * chain yourself.
- */
- error_or<fix_void<T>> take();
-
- /** @todo implement
- * Specifically pump elements through this chain with the provided
- * wait_scope
- */
- void poll(wait_scope &wait_scope);
-
- // helper
- static conveyor<T> to_conveyor(own<conveyor_node> node);
-
- // helper
- static own<conveyor_node> from_conveyor(conveyor<T> conveyor);
-};
-
-template <typename Func> conveyor_result<Func, void> exec_later(Func &&func);
-
-/*
- * Join Conveyors into a single one
- */
-template <typename... Args>
-conveyor<std::tuple<Args...>>
-join_conveyors(std::tuple<conveyor<Args>...> &conveyors);
-
-template <typename T> class conveyor_feeder {
-public:
- virtual ~conveyor_feeder() = default;
-
- virtual void feed(T &&data) = 0;
- virtual void fail(error &&error) = 0;
-
- virtual size_t space() const = 0;
- virtual size_t queued() const = 0;
-
- virtual error swap(conveyor<T> &&conveyor) noexcept = 0;
-};
-
-template <> class conveyor_feeder<void> {
-public:
- virtual ~conveyor_feeder() = default;
-
- virtual void feed(void_t &&value = void_t{}) = 0;
- virtual void fail(error &&error) = 0;
-
- virtual size_t space() const = 0;
- virtual size_t queued() const = 0;
-
- virtual error swap(conveyor<void_t> &&conveyor) noexcept = 0;
-};
-
-template <typename T> struct conveyor_and_feeder {
- own<conveyor_feeder<T>> feeder;
- class conveyor<T> conveyor;
-};
-
-template <typename T> conveyor_and_feeder<T> new_conveyor_and_feeder();
-
-template <typename T> conveyor_and_feeder<T> one_time_conveyor_and_feeder();
-
-enum class Signal : uint8_t { Terminate, User1 };
-
-/**
- * Class which acts as a correspondent between the running framework and outside
- * events which may be signals from the operating system or just other threads.
- * Default EventPorts are supplied by setupAsyncIo() in io.h
- */
-class event_port {
-public:
- virtual ~event_port() = default;
-
- virtual conveyor<void> on_signal(Signal signal) = 0;
-
- virtual void poll() = 0;
- virtual void wait() = 0;
- virtual void wait(const std::chrono::steady_clock::duration &) = 0;
- virtual void wait(const std::chrono::steady_clock::time_point &) = 0;
-
- virtual void wake() = 0;
-};
-
-class sink_conveyor_node;
-
-class conveyor_sink_set final : public event {
-private:
- /*
- class Helper final : public Event {
- private:
- void destroySinkConveyorNode(ConveyorNode& sink);
- void fail(Error&& error);
-
- std::vector<Own<ConveyorNode>> sink_nodes;
- std::queue<ConveyorNode*> delete_nodes;
- std::function<void(Error&& error)> error_handler;
-
- public:
- ConveyorSinks() = default;
- ConveyorSinks(EventLoop& event_loop);
-
- void add(Conveyor<void> node);
-
- void fire() override {}
- };
-
- gin::Own<Helper> helper;
- */
- friend class sink_conveyor_node;
-
- void destroy_sink_conveyor_node(conveyor_node &sink_node);
- void fail(error &&err);
-
- std::list<own<conveyor_node>> sink_nodes_;
-
- std::queue<conveyor_node *> delete_nodes_;
-
- std::function<void(error &&)> error_handler_;
-
-public:
- // ConveyorSinks();
- // ConveyorSinks(EventLoop& event_loop);
- conveyor_sink_set() = default;
- conveyor_sink_set(event_loop &event_loop);
-
- void add(conveyor<void> &&node);
-
- void fire() override;
-};
-
-/*
- * EventLoop class similar to capn'proto.
- * https://github.com/capnproto/capnproto
- */
-class event_loop {
-private:
- friend class event;
- event *head_ = nullptr;
- event **tail_ = &head_;
- event **next_insert_point_ = &head_;
- event **later_insert_point_ = &head_;
-
- bool is_runnable_ = false;
-
- own<event_port> event_port_ = nullptr;
-
- own<conveyor_sink_set> daemon_sink_ = nullptr;
-
- // functions
- void set_runnable(bool runnable);
-
- friend class wait_scope;
- void enter_scope();
- void leave_scope();
-
- bool turn_loop();
- bool turn();
-
-public:
- event_loop();
- event_loop(own<event_port> &&port);
- ~event_loop();
-
- event_loop(event_loop &&) = default;
- event_loop &operator=(event_loop &&) = default;
-
- bool wait();
- bool wait(const std::chrono::steady_clock::duration &);
- bool wait(const std::chrono::steady_clock::time_point &);
- bool poll();
-
- event_port *get_event_port();
-
- conveyor_sink_set &daemon();
-};
-
-/*
- * WaitScope class similar to capn'proto.
- * https://github.com/capnproto/capnproto
- */
-class wait_scope {
-private:
- event_loop &loop_;
-
-public:
- wait_scope(event_loop &loop);
- ~wait_scope();
-
- void wait();
- void wait(const std::chrono::steady_clock::duration &);
- void wait(const std::chrono::steady_clock::time_point &);
- void poll();
-};
-
-template <typename Func> conveyor_result<Func, void> yield_next(Func &&func);
-
-template <typename Func> conveyor_result<Func, void> yield_later(Func &&func);
-
-template <typename Func> conveyor_result<Func, void> yield_last(Func &&func);
-} // namespace saw
-
-// Secret stuff
-// Aka private semi hidden classes
-namespace saw {
-
-template <typename Out, typename In> struct fix_void_caller {
- template <typename Func> static Out apply(Func &func, In &&in) {
- return func(std::move(in));
- }
-};
-
-template <typename Out> struct fix_void_caller<Out, void_t> {
- template <typename Func> static Out apply(Func &func, void_t &&in) {
- (void)in;
- return func();
- }
-};
-
-template <typename In> struct fix_void_caller<void_t, In> {
- template <typename Func> static void_t apply(Func &func, In &&in) {
- func(std::move(in));
- return void_t{};
- }
-};
-
-template <> struct fix_void_caller<void_t, void_t> {
- template <typename Func> static void_t apply(Func &func, void_t &&in) {
- (void)in;
- func();
- return void_t{};
- }
-};
-
-template <typename T> class adapt_conveyor_node;
-
-template <typename T>
-class adapt_conveyor_feeder final : public conveyor_feeder<unfix_void<T>> {
-private:
- adapt_conveyor_node<T> *feedee_ = nullptr;
-
-public:
- ~adapt_conveyor_feeder();
-
- void set_feedee(adapt_conveyor_node<T> *feedee);
-
- void feed(T &&value) override;
- void fail(error &&error) override;
-
- size_t space() const override;
- size_t queued() const override;
-
- error swap(conveyor<T> &&conv) noexcept override;
-};
-
-template <typename T>
-class adapt_conveyor_node final : public conveyor_node,
- public conveyor_event_storage {
-private:
- adapt_conveyor_feeder<T> *feeder_ = nullptr;
-
- std::queue<error_or<unfix_void<T>>> storage_;
-
- conveyor_node_with_parent_mixin parent_node_;
-
-public:
- adapt_conveyor_node();
- ~adapt_conveyor_node();
-
- void set_feeder(adapt_conveyor_feeder<T> *feeder);
-
- void feed(T &&value);
- void fail(error &&error);
-
- // ConveyorNode
- void get_result(error_or_value &err_or_val) override;
-
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee) noexcept override;
-
- conveyor_storage *next_storage() noexcept override;
- void notify_parent_attached(conveyor_node &) noexcept override;
-
- // ConveyorStorage
- size_t space() const override;
- size_t queued() const override;
-
- void child_has_fired() override;
- void parent_has_fired() override;
-
- // Event
- void fire() override;
-};
-
-template <typename T> class one_time_conveyor_node;
-
-template <typename T>
-class one_time_conveyor_feeder final : public conveyor_feeder<unfix_void<T>> {
-private:
- one_time_conveyor_node<T> *feedee_ = nullptr;
-
-public:
- ~one_time_conveyor_feeder();
-
- void set_feedee(one_time_conveyor_node<T> *feedee);
-
- void feed(T &&value) override;
- void fail(error &&error) override;
-
- size_t space() const override;
- size_t queued() const override;
-};
-
-template <typename T>
-class one_time_conveyor_node final : public conveyor_node,
- public conveyor_storage,
- public event {
-private:
- one_time_conveyor_feeder<T> *feeder_ = nullptr;
-
- bool passed_ = false;
- maybe<error_or<T>> storage_ = std::nullopt;
-
-public:
- ~one_time_conveyor_node();
-
- void set_feeder(one_time_conveyor_feeder<T> *feeder);
-
- void feed(T &&value);
- void fail(error &&error);
-
- // ConveyorNode
- void get_result(error_or_value &err_or_val) override;
-
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee) override;
-
- // ConveyorStorage
- size_t space() const override;
- size_t queued() const override;
-
- void child_has_fired() override {}
- void parent_has_fired() override;
-
- // Event
- void fire() override;
-};
-
-/**
- * This class buffers and saves incoming elements and acts as an interrupt node
- * for processing calls
- */
-class queue_buffer_conveyor_node_base : public conveyor_node,
- public conveyor_event_storage {
-protected:
- conveyor_node_with_child_mixin child_mixin_;
-
-public:
- queue_buffer_conveyor_node_base(own<conveyor_node> child_)
- : conveyor_event_storage{}, child_mixin_{std::move(child_), *this} {}
- virtual ~queue_buffer_conveyor_node_base() = default;
-
- /**
- * Use mixin
- */
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee_) noexcept override;
-
- conveyor_storage *next_storage() noexcept override {
- return static_cast<conveyor_storage *>(this);
- }
-};
-
-template <typename T>
-class queue_buffer_conveyor_node final
- : public queue_buffer_conveyor_node_base {
-private:
- std::queue<error_or<T>> storage_;
- size_t max_store_;
-
-public:
- queue_buffer_conveyor_node(own<conveyor_node> dep, size_t max_size)
- : queue_buffer_conveyor_node_base{std::move(dep)}, max_store_{
- max_size} {}
- // Event
- void fire() override;
- // ConveyorNode
- void get_result(error_or_value &eov) noexcept override;
-
- // ConveyorStorage
- size_t space() const override;
- size_t queued() const override;
-
- void child_has_fired() override;
- void parent_has_fired() override;
-};
-
-class attach_conveyor_node_base : public conveyor_node {
-protected:
- conveyor_node_with_child_mixin child_mixin_;
-
-public:
- attach_conveyor_node_base(own<conveyor_node> &&child_)
- : child_mixin_{std::move(child_), *this} {}
-
- virtual ~attach_conveyor_node_base() = default;
-
- void get_result(error_or_value &err_or_val) noexcept override;
-
- /**
- * Use mixin
- */
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee_) noexcept override;
-
- conveyor_storage *next_storage() noexcept override;
-};
-
-template <typename... Args>
-class attach_conveyor_node final : public attach_conveyor_node_base {
-public:
- attach_conveyor_node(own<conveyor_node> &&dep, Args &&...args)
- : attach_conveyor_node_base(std::move(dep)), attached_data_{
- std::move(args...)} {}
-
-private:
- std::tuple<Args...> attached_data_;
-};
-
-class convert_conveyor_node_base : public conveyor_node {
-public:
- convert_conveyor_node_base(own<conveyor_node> &&dep);
- virtual ~convert_conveyor_node_base() = default;
-
- void get_result(error_or_value &err_or_val) override;
-
- virtual void get_impl(error_or_value &err_or_val) = 0;
-
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee) noexcept override;
-
- conveyor_storage *next_storage() noexcept override;
-
-protected:
- conveyor_node_with_child_mixin child_mixin_;
-};
-
-template <typename T, typename DepT, typename Func, typename ErrorFunc>
-class convert_conveyor_node final : public convert_conveyor_node_base {
-private:
- Func func_;
- ErrorFunc error_func_;
-
- static_assert(std::is_same<DepT, remove_error_or<DepT>>::value,
- "Should never be of type ErrorOr");
-
-public:
- convert_conveyor_node(own<conveyor_node> &&dep, Func &&func,
- ErrorFunc &&error_func)
- : convert_conveyor_node_base(std::move(dep)), func_{std::move(func)},
- error_func_{std::move(error_func)} {}
-
- void get_impl(error_or_value &err_or_val) noexcept override {
- error_or<unfix_void<DepT>> dep_eov;
- error_or<unfix_void<remove_error_or<T>>> &eov =
- err_or_val.as<unfix_void<remove_error_or<T>>>();
- if (child_mixin_.child) {
- child_mixin_.child->get_result(dep_eov);
- if (dep_eov.is_value()) {
- try {
-
- eov = fix_void_caller<T, DepT>::apply(
- func_, std::move(dep_eov.get_value()));
- } catch (const std::bad_alloc &) {
- eov = make_error<err::out_of_memory>("Out of memory");
- } catch (const std::exception &) {
- eov = make_error<err::invalid_state>(
- "Exception in chain occured. Return ErrorOr<T> if you "
- "want to handle errors which are recoverable");
- }
- } else if (dep_eov.is_error()) {
- eov = error_func_(std::move(dep_eov.get_error()));
- } else {
- eov = make_error<err::invalid_state>("No value set in dependency");
- }
- } else {
- eov = make_error<err::invalid_state>("Conveyor doesn't have child");
- }
- }
-};
-
-class sink_conveyor_node final : public conveyor_node,
- public conveyor_event_storage {
-private:
- conveyor_node_with_child_mixin child_mixin_;
- conveyor_sink_set *conveyor_sink_;
-
-public:
- sink_conveyor_node(own<conveyor_node> node, conveyor_sink_set &conv_sink)
- : conveyor_event_storage{}, child_mixin_{std::move(node), *this},
- conveyor_sink_{&conv_sink} {}
-
- sink_conveyor_node(own<conveyor_node> node)
- : conveyor_event_storage{}, child_mixin_{std::move(node), *this},
- conveyor_sink_{nullptr} {}
-
- // Event only queued if a critical error occured
- void fire() override {
- // Queued for destruction of children, because this acts as a sink and
- // no other event should be here
- child_mixin_.child = nullptr;
-
- if (conveyor_sink_) {
- conveyor_sink_->destroy_sink_conveyor_node(*this);
- conveyor_sink_ = nullptr;
- }
- }
-
- // ConveyorStorage
- size_t space() const override { return 1; }
- size_t queued() const override { return 0; }
-
- // ConveyorNode
- void get_result(error_or_value &err_or_val) noexcept override {
- err_or_val.as<void_t>() =
- make_error<err::invalid_state>("In a sink node no result can be returned");
- }
-
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee) noexcept override {
- return child_mixin_.swap_child(std::move(swapee));
- }
-
- // ConveyorStorage
- void child_has_fired() override {
- if (child_mixin_.child) {
- error_or<void> dep_eov;
- child_mixin_.child->get_result(dep_eov);
- if (dep_eov.is_error()) {
- if (dep_eov.get_error().is_critical()) {
- if (!is_armed()) {
- arm_last();
- }
- }
- if (conveyor_sink_) {
- conveyor_sink_->fail(std::move(dep_eov.get_error()));
- }
- }
- }
- }
-
- /*
- * No parent needs to be fired since we always have space
- */
- void parent_has_fired() override {}
-
- conveyor_storage *next_storage() override {
- // Should never happen though
- assert(false);
- return nullptr;
- // return static_cast<ConveyorStorage*>(this);
- }
-};
-
-class immediate_conveyor_node_base : public conveyor_node,
- public conveyor_event_storage {
-private:
-public:
- immediate_conveyor_node_base();
-
- virtual ~immediate_conveyor_node_base() = default;
-
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee) noexcept override {
- (void)swapee;
- return make_error<err::not_supported>("Node doesn't support swapping");
- }
-
- conveyor_storage *next_storage() noexcept override {
- return static_cast<conveyor_storage *>(this);
- }
-};
-
-template <typename T>
-class immediate_conveyor_node final : public immediate_conveyor_node_base {
-private:
- error_or<fix_void<T>> value_;
- uint8_t retrieved_;
-
-public:
- immediate_conveyor_node(fix_void<T> &&val);
- immediate_conveyor_node(error &&error);
-
- // ConveyorStorage
- size_t space() const override;
- size_t queued() const override;
-
- void child_has_fired() override;
- void parent_has_fired() override;
-
- // ConveyorNode
- void get_result(error_or_value &err_or_val) noexcept override {
- if (retrieved_ > 0) {
- err_or_val.as<fix_void<T>>() =
- make_error<err::buffer_exhausted>("Already taken value");
- } else {
- err_or_val.as<fix_void<T>>() = std::move(value_);
- }
- if (queued() > 0) {
- ++retrieved_;
- }
- }
-
- // Event
- void fire() override;
-};
-
-/*
- * Collects every incoming value and throws it in one lane
- */
-class merge_conveyor_node_base : public conveyor_node,
- public conveyor_event_storage {
-public:
- merge_conveyor_node_base();
-
- virtual ~merge_conveyor_node_base() = default;
-
- conveyor_storage *next_storage() noexcept override {
- return static_cast<conveyor_storage *>(this);
- }
-};
-
-template <typename T>
-class merge_conveyor_node : public merge_conveyor_node_base {
-private:
- class appendage final : public conveyor_node, public conveyor_storage {
- public:
- own<conveyor_node> child;
- merge_conveyor_node *merger;
-
- maybe<error_or<fix_void<T>>> error_or_value_;
-
- public:
- appendage(own<conveyor_node> n, merge_conveyor_node &m)
- : conveyor_storage{}, child{std::move(n)}, merger{&m},
- error_or_value_{std::nullopt} {}
-
- bool child_storage_has_element_queued() const {
- if (!child) {
- return false;
- }
- conveyor_storage *storage = child->next_storage();
- if (storage) {
- return storage->queued() > 0;
- }
- return false;
- }
-
- void get_appendage_result(error_or_value &eov);
-
- /**
- * ConveyorNode
- */
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&swapee_) override;
-
- conveyor_storage *next_storage() noexcept override {
- return static_cast<conveyor_storage *>(this);
- }
-
- void get_result(error_or_value &err_or_val) override;
-
- /**
- * ConveyorStorage
- */
- size_t space() const override;
-
- size_t queued() const override;
-
- void child_has_fired() override;
-
- void parent_has_fired() override;
-
- void set_parent(conveyor_storage *par) override;
- };
-
- friend class merge_conveyor_node_data<T>;
- friend class appendage;
-
- our<merge_conveyor_node_data<T>> data_;
- size_t next_appendage_ = 0;
-
-public:
- merge_conveyor_node(our<merge_conveyor_node_data<T>> data);
- ~merge_conveyor_node();
- // ConveyorNode
- error_or<own<conveyor_node>>
- swap_child(own<conveyor_node> &&c) noexcept override;
-
- // Event
- void get_result(error_or_value &err_or_val) noexcept override;
-
- void fire() override;
-
- // ConveyorStorage
- size_t space() const override;
- size_t queued() const override;
- void child_has_fired() override;
- void parent_has_fired() override;
-};
-
-template <typename T> class merge_conveyor_node_data {
-public:
- std::vector<own<typename merge_conveyor_node<T>::appendage>> appendages;
-
- merge_conveyor_node<T> *merger = nullptr;
-
-public:
- void attach(conveyor<T> conv);
-
- void governing_node_destroyed();
-};
-
-/*
-class JoinConveyorNodeBase : public ConveyorNode, public ConveyorEventStorage {
-private:
-
-public:
-};
-
-template <typename... Args>
-class JoinConveyorNode final : public JoinConveyorNodeBase {
-private:
- template<typename T>
- class Appendage : public ConveyorEventStorage {
- private:
- Maybe<T> data = std::nullopt;
-
- public:
- size_t space() const override;
- size_t queued() const override;
-
- void fire() override;
- void get_result(ErrorOrValue& eov) override;
- };
-
- std::tuple<Appendage<Args>...> appendages;
-
-public:
-};
-
-*/
-
-} // namespace saw
-
-#include "async.tmpl.h"
diff --git a/src/async/async.tmpl.h b/src/async/async.tmpl.h
deleted file mode 100644
index 9569f60..0000000
--- a/src/async/async.tmpl.h
+++ /dev/null
@@ -1,767 +0,0 @@
-#pragma once
-
-#include <forstio/core/common.h>
-#include <forstio/core/error.h>
-
-#include <cassert>
-// Template inlining
-
-namespace saw {
-
-template <typename Func> conveyor_result<Func, void> execLater(Func &&func) {
- conveyor<void> conveyor{fix_void<void>{}};
- return conveyor.then(std::move(func));
-}
-
-template <typename T>
-conveyor<T>::conveyor(fix_void<T> value) : conveyor_base(nullptr) {
- // Is there any way to do this?
- // @todo new conveyor_base constructor for Immediate values
-
- own<immediate_conveyor_node<fix_void<T>>> immediate =
- heap<immediate_conveyor_node<fix_void<T>>>(std::move(value));
-
- if (!immediate) {
- return;
- }
-
- node_ = std::move(immediate);
-}
-
-template <typename T>
-conveyor<T>::conveyor(error &&err) : conveyor_base(nullptr) {
- own<immediate_conveyor_node<fix_void<T>>> immediate =
- heap<immediate_conveyor_node<fix_void<T>>>(std::move(err));
-
- if (!immediate) {
- return;
- }
-
- node_ = std::move(immediate);
-}
-
-template <typename T>
-conveyor<T>::conveyor(own<conveyor_node> node_p)
- : conveyor_base{std::move(node_p)} {}
-
-template <typename T>
-template <typename Func, typename ErrorFunc>
-conveyor_result<Func, T> conveyor<T>::then(Func &&func,
- ErrorFunc &&error_func) {
- own<conveyor_node> conversion_node =
- heap<convert_conveyor_node<fix_void<return_type<Func, T>>, fix_void<T>,
- Func, ErrorFunc>>(
- std::move(node_), std::move(func), std::move(error_func));
-
- return conveyor<remove_error_or<return_type<Func, T>>>::to_conveyor(
- std::move(conversion_node));
-}
-
-template <typename T> conveyor<T> conveyor<T>::buffer(size_t size) {
- SAW_ASSERT(node_) { return conveyor<T>{own<conveyor_node>{nullptr}}; }
- conveyor_storage *storage = node_->next_storage();
- SAW_ASSERT(storage) { return conveyor<T>{own<conveyor_node>{nullptr}}; }
-
- own<queue_buffer_conveyor_node<fix_void<T>>> storage_node =
- heap<queue_buffer_conveyor_node<fix_void<T>>>(std::move(node_), size);
-
- conveyor_storage *storage_ptr =
- static_cast<conveyor_storage *>(storage_node.get());
-
- storage->set_parent(storage_ptr);
- return conveyor<T>{std::move(storage_node)};
-}
-
-template <typename T>
-template <typename... Args>
-conveyor<T> conveyor<T>::attach(Args &&...args) {
- own<attach_conveyor_node<Args...>> attach_node =
- heap<attach_conveyor_node<Args...>>(std::move(node_),
- std::move(args...));
- return conveyor<T>{std::move(attach_node)};
-}
-
-template <typename T>
-std::pair<conveyor<T>, merge_conveyor<T>> conveyor<T>::merge() {
- our<merge_conveyor_node_data<T>> data =
- share<merge_conveyor_node_data<T>>();
-
- own<merge_conveyor_node<T>> merge_node = heap<merge_conveyor_node<T>>(data);
-
- SAW_ASSERT(node_) {
- return std::make_pair(conveyor<T>{own<conveyor_node>{nullptr}},
- merge_conveyor<T>{});
- }
- conveyor_storage *storage = node_->next_storage();
- SAW_ASSERT(storage) {
- return std::make_pair(conveyor<T>{own<conveyor_node>{nullptr}},
- merge_conveyor<T>{});
- }
-
- data->attach(conveyor<T>::to_conveyor(std::move(node_)));
-
- merge_conveyor<T> node_ref{data};
-
- return std::make_pair(conveyor<T>{std::move(merge_node)},
- std::move(node_ref));
-}
-
-template <>
-template <typename ErrorFunc>
-conveyor_sink conveyor<void>::sink(ErrorFunc &&error_func) {
- conveyor_storage *storage = node_->next_storage();
- SAW_ASSERT(storage) { return conveyor_sink{}; }
-
- own<sink_conveyor_node> sink_node =
- heap<sink_conveyor_node>(std::move(node_));
- conveyor_storage *storage_ptr =
- static_cast<conveyor_storage *>(sink_node.get());
-
- storage->set_parent(storage_ptr);
-
- return conveyor_sink{std::move(sink_node)};
-}
-
-void detach_conveyor(conveyor<void> &&conveyor);
-
-template <typename T>
-template <typename ErrorFunc>
-void conveyor<T>::detach(ErrorFunc &&func) {
- detach_conveyor(std::move(then([](T &&) {}, std::move(func))));
-}
-
-template <>
-template <typename ErrorFunc>
-void conveyor<void>::detach(ErrorFunc &&func) {
- detach_conveyor(std::move(then([]() {}, std::move(func))));
-}
-
-template <typename T>
-conveyor<T> conveyor<T>::to_conveyor(own<conveyor_node> node) {
- return conveyor<T>{std::move(node)};
-}
-
-template <typename T>
-own<conveyor_node> conveyor<T>::from_conveyor(conveyor<T> conveyor) {
- return std::move(conveyor.node_);
-}
-
-template <typename T> error_or<fix_void<T>> conveyor<T>::take() {
- SAW_ASSERT(node_) {
- return error_or<fix_void<T>>{
- make_error<err::invalid_state>("conveyor in invalid state")};
- }
- conveyor_storage *storage = node_->next_storage();
- if (storage) {
- if (storage->queued() > 0) {
- error_or<fix_void<T>> result;
- node_->get_result(result);
- return result;
- } else {
- return error_or<fix_void<T>>{
- make_error<err::buffer_exhausted>("conveyor buffer has no elements")};
- }
- } else {
- return error_or<fix_void<T>>{
- make_error<err::invalid_state>("conveyor node has no child storage")};
- }
-}
-
-template <typename T> conveyor_and_feeder<T> new_conveyor_and_feeder() {
- own<adapt_conveyor_feeder<fix_void<T>>> feeder =
- heap<adapt_conveyor_feeder<fix_void<T>>>();
- own<adapt_conveyor_node<fix_void<T>>> node =
- heap<adapt_conveyor_node<fix_void<T>>>();
-
- feeder->set_feedee(node.get());
- node->set_feeder(feeder.get());
-
- return conveyor_and_feeder<T>{std::move(feeder),
- conveyor<T>::to_conveyor(std::move(node))};
-}
-
-// QueueBuffer
-template <typename T> void queue_buffer_conveyor_node<T>::fire() {
- if (child_mixin_.child) {
- if (!storage_.empty()) {
- if (storage_.front().is_error()) {
- if (storage_.front().get_error().is_critical()) {
- child_mixin_.child = nullptr;
- }
- }
- }
- }
-
- bool has_space_before_fire = space() > 0;
-
- if (parent_) {
- parent_->child_has_fired();
- if (!storage_.empty() && parent_->space() > 0) {
- arm_later();
- }
- }
-
- if (!child_mixin_.child) {
- while (!storage_.empty()) {
- storage_.pop();
- }
- return;
- }
-
- conveyor_storage *ch_storage = child_mixin_.child->next_storage();
- if (ch_storage && !has_space_before_fire) {
- ch_storage->parent_has_fired();
- }
-}
-
-template <typename T>
-void queue_buffer_conveyor_node<T>::get_result(error_or_value &eov) noexcept {
- error_or<T> &err_or_val = eov.as<T>();
- err_or_val = std::move(storage_.front());
- storage_.pop();
-}
-
-template <typename T> size_t queue_buffer_conveyor_node<T>::space() const {
- return max_store_ - storage_.size();
-}
-
-template <typename T> size_t queue_buffer_conveyor_node<T>::queued() const {
- return storage_.size();
-}
-
-template <typename T> void queue_buffer_conveyor_node<T>::child_has_fired() {
- if (child_mixin_.child && storage_.size() < max_store_) {
- error_or<T> eov;
- child_mixin_.child->get_result(eov);
-
- if (eov.is_error()) {
- if (eov.get_error().is_critical()) {
- }
- }
-
- storage_.push(std::move(eov));
- if (!is_armed()) {
- arm_later();
- }
- }
-}
-
-template <typename T> void queue_buffer_conveyor_node<T>::parent_has_fired() {
- SAW_ASSERT(parent_) { return; }
-
- if (parent_->space() == 0) {
- return;
- }
-
- if (queued() > 0) {
- arm_later();
- }
-}
-
-template <typename T>
-immediate_conveyor_node<T>::immediate_conveyor_node(fix_void<T> &&val)
- : value_{std::move(val)}, retrieved_{0} {}
-
-template <typename T>
-immediate_conveyor_node<T>::immediate_conveyor_node(error &&error)
- : value_{std::move(error)}, retrieved_{0} {}
-
-template <typename T> size_t immediate_conveyor_node<T>::space() const {
- return 0;
-}
-
-template <typename T> size_t immediate_conveyor_node<T>::queued() const {
- return retrieved_ > 1 ? 0 : 1;
-}
-
-template <typename T> void immediate_conveyor_node<T>::child_has_fired() {
- // Impossible case
- assert(false);
-}
-
-template <typename T> void immediate_conveyor_node<T>::parent_has_fired() {
- SAW_ASSERT(parent_) { return; }
- assert(parent_->space() > 0);
-
- if (queued() > 0) {
- arm_next();
- }
-}
-
-template <typename T> void immediate_conveyor_node<T>::fire() {
-
- if (parent_) {
- parent_->child_has_fired();
- if (queued() > 0 && parent_->space() > 0) {
- arm_last();
- }
- }
-}
-
-template <typename T>
-merge_conveyor<T>::merge_conveyor(lent<merge_conveyor_node_data<T>> d)
- : data_{std::move(d)} {}
-
-template <typename T> merge_conveyor<T>::~merge_conveyor() {}
-
-template <typename T> void merge_conveyor<T>::attach(conveyor<T> conveyor) {
- auto sp = data_.lock();
- SAW_ASSERT(sp) { return; }
-
- sp->attach(std::move(conveyor));
-}
-
-template <typename T>
-merge_conveyor_node<T>::merge_conveyor_node(our<merge_conveyor_node_data<T>> d)
- : data_{d} {
- SAW_ASSERT(data_) { return; }
-
- data_->merger = this;
-}
-
-template <typename T> merge_conveyor_node<T>::~merge_conveyor_node() {}
-
-template <typename T>
-error_or<own<conveyor_node>>
-merge_conveyor_node<T>::swap_child(own<conveyor_node> &&swapee_) noexcept {
- (void)swapee_;
- return make_error<err::invalid_state>(
- "merge_conveyor_node<T>::appendage should block calls to this class");
-}
-
-template <typename T>
-void merge_conveyor_node<T>::get_result(error_or_value &eov) noexcept {
- error_or<fix_void<T>> &err_or_val = eov.as<fix_void<T>>();
-
- SAW_ASSERT(data_) { return; }
-
- /// @todo search appendages for result
-
- auto &appendages = data_->appendages;
- next_appendage_ = std::min(appendages.size(), next_appendage_);
-
- for (size_t i = next_appendage_; i < appendages.size(); ++i) {
- if (appendages[i]->queued() > 0) {
- err_or_val = std::move(appendages[i]->error_or_value_.value());
- appendages[i]->error_or_value_ = std::nullopt;
- next_appendage_ = i + 1;
- return;
- }
- }
- for (size_t i = 0; i < next_appendage_; ++i) {
- if (appendages[i]->queued() > 0) {
- err_or_val = std::move(appendages[i]->error_or_value_.value());
- appendages[i]->error_or_value_ = std::nullopt;
- next_appendage_ = i + 1;
- return;
- }
- }
-
- err_or_val = make_error<err::invalid_state>("No value in Merge appendages");
-}
-
-template <typename T> void merge_conveyor_node<T>::fire() {
- SAW_ASSERT(queued() > 0) { return; }
-
- if (parent_) {
- parent_->child_has_fired();
-
- if (queued() > 0 && parent_->space() > 0) {
- arm_later();
- }
- }
-}
-
-template <typename T> size_t merge_conveyor_node<T>::space() const { return 0; }
-
-template <typename T> size_t merge_conveyor_node<T>::queued() const {
- SAW_ASSERT(data_) { return 0; }
-
- size_t queue_count = 0;
-
- for (auto &iter : data_->appendages) {
- queue_count += iter->queued();
- }
-
- return queue_count;
-}
-
-template <typename T> void merge_conveyor_node<T>::child_has_fired() {
- /// This can never happen
- assert(false);
-}
-
-template <typename T> void merge_conveyor_node<T>::parent_has_fired() {
- SAW_ASSERT(parent_) { return; }
- if (queued() > 0) {
- if (parent_->space() > 0) {
- arm_later();
- }
- }
-}
-
-/**
- * merge_conveyor_node<T>::Apendage
- */
-
-template <typename T>
-error_or<own<conveyor_node>>
-merge_conveyor_node<T>::appendage::swap_child(own<conveyor_node> &&swapee_) {
- own<conveyor_node> old_child = std::move(child);
-
- child = std::move(swapee_);
-
- // This case should never happen
- SAW_ASSERT(old_child) { return make_error<err::invalid_state>("No child exists"); }
-
- return old_child;
-}
-
-template <typename T>
-void merge_conveyor_node<T>::appendage::get_result(error_or_value &eov) {
- error_or<fix_void<T>> &err_or_val = eov.as<fix_void<T>>();
-
- SAW_ASSERT(queued() > 0) {
- err_or_val =
- make_error<err::invalid_state>("No element queued in Merge appendage Node");
- return;
- }
-
- err_or_val = std::move(error_or_value_.value());
- error_or_value_ = std::nullopt;
-}
-
-template <typename T> size_t merge_conveyor_node<T>::appendage::space() const {
- SAW_ASSERT(merger) { return 0; }
-
- if (error_or_value_.has_value()) {
- return 0;
- }
-
- return 1;
-}
-
-template <typename T> size_t merge_conveyor_node<T>::appendage::queued() const {
- SAW_ASSERT(merger) { return 0; }
-
- if (error_or_value_.has_value()) {
- return 1;
- }
-
- return 0;
-}
-
-/// @todo delete this function. Replaced by the regular get_result
-template <typename T>
-void merge_conveyor_node<T>::appendage::get_appendage_result(
- error_or_value &eov) {
- error_or<fix_void<T>> &err_or_val = eov.as<fix_void<T>>();
-
- SAW_ASSERT(queued() > 0) {
- err_or_val =
- make_error<err::invalid_state>("No element queued in Merge appendage Node");
- return;
- }
-
- err_or_val = std::move(error_or_value_.value());
- error_or_value_ = std::nullopt;
-}
-
-template <typename T>
-void merge_conveyor_node<T>::appendage::child_has_fired() {
- SAW_ASSERT(!error_or_value_.has_value()) { return; }
- error_or<fix_void<T>> eov;
- child->get_result(eov);
-
- error_or_value_ = std::move(eov);
-
- if (!merger->is_armed()) {
- merger->arm_later();
- }
-}
-
-template <typename T>
-void merge_conveyor_node<T>::appendage::parent_has_fired() {
- conveyor_storage *child_storage = child->next_storage();
- if (child_storage) {
- child_storage->parent_has_fired();
- }
-}
-
-template <typename T>
-void merge_conveyor_node<T>::appendage::set_parent(conveyor_storage *par) {
- SAW_ASSERT(merger) { return; }
-
- SAW_ASSERT(child) { return; }
-
- parent_ = par;
-}
-
-template <typename T>
-void merge_conveyor_node_data<T>::attach(conveyor<T> conv) {
- auto nas = conveyor<T>::from_conveyor(std::move(conv));
- SAW_ASSERT(nas) { return; }
- conveyor_storage *storage = nas->next_storage();
- SAW_ASSERT(storage) { return; }
-
- auto merge_node_appendage =
- heap<typename merge_conveyor_node<T>::appendage>(std::move(nas),
- *merger);
- auto merge_node_appendage_ptr = merge_node_appendage.get();
-
- storage->set_parent(merge_node_appendage.get());
-
- SAW_ASSERT(merger) { return; }
-
- conveyor_storage *mrg_storage = merger->next_storage();
- SAW_ASSERT(mrg_storage) { return; }
-
- merge_node_appendage->set_parent(mrg_storage);
-
- appendages.push_back(std::move(merge_node_appendage));
-
- /// @todo return this. necessary? maybe for the weird linking setup
- /// maybe not
- // return merge_node_appendage_ptr;
-}
-
-template <typename T>
-void merge_conveyor_node_data<T>::governing_node_destroyed() {
- appendages.clear();
- merger = nullptr;
-}
-
-template <typename T> adapt_conveyor_feeder<T>::~adapt_conveyor_feeder() {
- if (feedee_) {
- feedee_->set_feeder(nullptr);
- feedee_ = nullptr;
- }
-}
-
-template <typename T>
-void adapt_conveyor_feeder<T>::set_feedee(adapt_conveyor_node<T> *feedee_p) {
- feedee_ = feedee_p;
-}
-
-template <typename T> void adapt_conveyor_feeder<T>::feed(T &&value) {
- if (feedee_) {
- feedee_->feed(std::move(value));
- }
-}
-
-template <typename T> void adapt_conveyor_feeder<T>::fail(error &&error) {
- if (feedee_) {
- feedee_->fail(std::move(error));
- }
-}
-
-template <typename T> size_t adapt_conveyor_feeder<T>::queued() const {
- if (feedee_) {
- return feedee_->queued();
- }
- return 0;
-}
-
-template <typename T> size_t adapt_conveyor_feeder<T>::space() const {
- if (feedee_) {
- return feedee_->space();
- }
- return 0;
-}
-
-template <typename T>
-error adapt_conveyor_feeder<T>::swap(conveyor<T> &&conv) noexcept {
- SAW_ASSERT(feedee_) { return make_error<err::invalid_state>("No feedee connected"); }
-
- auto node = conveyor<T>::from_conveyor(std::move(conv));
-
- feedee_->swap_child(std::move(node));
-
- return no_error();
-}
-
-template <typename T>
-adapt_conveyor_node<T>::adapt_conveyor_node() : conveyor_event_storage{} {}
-
-template <typename T> adapt_conveyor_node<T>::~adapt_conveyor_node() {
- if (feeder_) {
- feeder_->set_feedee(nullptr);
- feeder_ = nullptr;
- }
-}
-
-template <typename T>
-error_or<own<conveyor_node>>
-adapt_conveyor_node<T>::swap_child(own<conveyor_node> &&swapee) noexcept {
- // This should return the owning pointer of this instance
- auto myself_err = parent_node_.swap_child_of_parent(std::move(swapee));
-
- if (myself_err.is_error()) {
- return myself_err;
- }
-
- auto &myself = myself_err.get_value();
-
- assert(myself.get() == this);
-
- return myself_err;
-}
-
-template <typename T>
-conveyor_storage *adapt_conveyor_node<T>::next_storage() noexcept {
- return static_cast<conveyor_storage *>(this);
-}
-
-template <typename T>
-void adapt_conveyor_node<T>::notify_parent_attached(
- conveyor_node &par) noexcept {
- parent_node_.change_parent(&par);
-}
-
-template <typename T>
-void adapt_conveyor_node<T>::set_feeder(adapt_conveyor_feeder<T> *feeder_p) {
- feeder_ = feeder_p;
-}
-
-template <typename T> void adapt_conveyor_node<T>::feed(T &&value) {
- storage_.push(std::move(value));
- arm_next();
-}
-
-template <typename T> void adapt_conveyor_node<T>::fail(error &&error) {
- storage_.push(std::move(error));
- arm_next();
-}
-
-template <typename T> size_t adapt_conveyor_node<T>::queued() const {
- return storage_.size();
-}
-
-template <typename T> size_t adapt_conveyor_node<T>::space() const {
- return std::numeric_limits<size_t>::max() - storage_.size();
-}
-
-template <typename T>
-void adapt_conveyor_node<T>::get_result(error_or_value &err_or_val) {
- if (!storage_.empty()) {
- err_or_val.as<T>() = std::move(storage_.front());
- storage_.pop();
- } else {
- err_or_val.as<T>() = make_error<err::invalid_state>(
- "Signal for retrieval of storage sent even though no "
- "data is present");
- }
-}
-
-template <typename T> void adapt_conveyor_node<T>::child_has_fired() {
- // Adapt node has no children
- assert(false);
-}
-
-template <typename T> void adapt_conveyor_node<T>::parent_has_fired() {
- SAW_ASSERT(parent_) { return; }
-
- if (parent_->space() == 0) {
- return;
- }
-}
-
-template <typename T> void adapt_conveyor_node<T>::fire() {
- if (parent_) {
- parent_->child_has_fired();
-
- if (storage_.size() > 0) {
- arm_later();
- }
- }
-}
-
-template <typename T> one_time_conveyor_feeder<T>::~one_time_conveyor_feeder() {
- if (feedee_) {
- feedee_->set_feeder(nullptr);
- feedee_ = nullptr;
- }
-}
-
-template <typename T>
-void one_time_conveyor_feeder<T>::set_feedee(
- one_time_conveyor_node<T> *feedee_p) {
- feedee_ = feedee_p;
-}
-
-template <typename T> void one_time_conveyor_feeder<T>::feed(T &&value) {
- if (feedee_) {
- feedee_->feed(std::move(value));
- }
-}
-
-template <typename T> void one_time_conveyor_feeder<T>::fail(error &&error) {
- if (feedee_) {
- feedee_->fail(std::move(error));
- }
-}
-
-template <typename T> size_t one_time_conveyor_feeder<T>::queued() const {
- if (feedee_) {
- return feedee_->queued();
- }
- return 0;
-}
-
-template <typename T> size_t one_time_conveyor_feeder<T>::space() const {
- if (feedee_) {
- return feedee_->space();
- }
- return 0;
-}
-
-template <typename T> one_time_conveyor_node<T>::~one_time_conveyor_node() {
- if (feeder_) {
- feeder_->set_feedee(nullptr);
- feeder_ = nullptr;
- }
-}
-
-template <typename T>
-void one_time_conveyor_node<T>::set_feeder(
- one_time_conveyor_feeder<T> *feeder_p) {
- feeder_ = feeder_p;
-}
-
-template <typename T> void one_time_conveyor_node<T>::feed(T &&value) {
- storage_ = std::move(value);
- arm_next();
-}
-
-template <typename T> void one_time_conveyor_node<T>::fail(error &&error) {
- storage_ = std::move(error);
- arm_next();
-}
-
-template <typename T> size_t one_time_conveyor_node<T>::queued() const {
- return storage_.has_value() ? 1 : 0;
-}
-
-template <typename T> size_t one_time_conveyor_node<T>::space() const {
- return passed_ ? 0 : 1;
-}
-
-template <typename T>
-void one_time_conveyor_node<T>::get_result(error_or_value &err_or_val) {
- if (storage_.has_value()) {
- err_or_val.as<T>() = std::move(storage_.value());
- storage_ = std::nullopt;
- } else {
- err_or_val.as<T>() = make_error<err::invalid_state>(
- "Signal for retrieval of storage sent even though no "
- "data is present");
- }
-}
-
-template <typename T> void one_time_conveyor_node<T>::fire() {
- if (parent_) {
- parent_->child_has_fired();
- }
-}
-
-} // namespace saw
diff --git a/src/codec-json/.nix/derivation.nix b/src/codec-json/.nix/derivation.nix
deleted file mode 100644
index 0f701c9..0000000
--- a/src/codec-json/.nix/derivation.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-codec-json";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- forstio.async
- forstio.codec
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/codec-json/SConscript b/src/codec-json/SConscript
deleted file mode 100644
index 772ac0b..0000000
--- a/src/codec-json/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-codec_json_env = env.Clone();
-
-codec_json_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-codec_json_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += codec_json_env.sources;
-env.headers += codec_json_env.headers;
-
-## Shared lib
-objects_shared = []
-codec_json_env.add_source_files(objects_shared, codec_json_env.sources, shared=True);
-codec_json_env.library_shared = codec_json_env.SharedLibrary('#build/forstio-codec-json', [objects_shared]);
-
-## Static lib
-objects_static = []
-codec_json_env.add_source_files(objects_static, codec_json_env.sources, shared=False);
-codec_json_env.library_static = codec_json_env.StaticLibrary('#build/forstio-codec-json', [objects_static]);
-
-# Set Alias
-env.Alias('library_codec_json', [codec_json_env.library_shared, codec_json_env.library_static]);
-
-env.targets += ['library_codec_json'];
-
-# Install
-env.Install('$prefix/lib/', [codec_json_env.library_shared, codec_json_env.library_static]);
-env.Install('$prefix/include/forstio/codec/json/', [codec_json_env.headers]);
diff --git a/src/codec-json/SConstruct b/src/codec-json/SConstruct
deleted file mode 100644
index edd5f57..0000000
--- a/src/codec-json/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-codec'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/codec-json/json.h b/src/codec-json/json.h
deleted file mode 100644
index 1fe6bb5..0000000
--- a/src/codec-json/json.h
+++ /dev/null
@@ -1,116 +0,0 @@
-#pragma once
-
-#include <forstio/core/buffer.h>
-#include <forstio/core/common.h>
-#include <forstio/codec/data.h>
-
-#include <algorithm>
-
-namespace saw {
-namespace encode {
-struct Json {};
-}
-
-template<typename Schema>
-class data<Schema, encode::Json> {
-private:
- ring_buffer buffer_;
-public:
- data():buffer_{}{}
-
- data(std::size_t ring_size_):buffer_{ring_size_}{}
-
- data(const std::string_view& view__):
- buffer_{view__.size()}
- {
- auto ptr = reinterpret_cast<const uint8_t*>(view__.data());
- if(!ptr){
- return;
- }
- buffer_.push(*ptr, view__.size());
- }
-
- buffer& get_buffer(){
- return buffer_;
- }
-
- const buffer& get_buffer() const {
- return buffer_;
- }
-
- error push(uint8_t val){
- return buffer_.push(val);
- }
-
- std::size_t get_size() const {
- return buffer_.read_composite_length();
- }
-
- uint8_t& at(std::size_t i){
- return buffer_.read(i);
- }
-
- const uint8_t& at(std::size_t i) const {
- return buffer_.read(i);
- }
-};
-}
-
-#include "json.tmpl.h"
-
-namespace saw {
-
-/**
- * Codec class for json
- */
-template<typename Schema>
-class codec<Schema, encode::Json> {
-public:
- struct config {
- size_t depth = 16;
- size_t length = 1024;
- };
-private:
- config cfg_;
-public:
- /**
- * Default constructor
- */
- codec(){}
-
- /**
- * Constructor
- */
- codec(config cfg__):cfg_{std::move(cfg__)}{}
-
- SAW_FORBID_COPY(codec);
- SAW_DEFAULT_MOVE(codec);
-
- template <typename FromEncoding>
- error_or<void> encode(const data<Schema, FromEncoding>& from_encode, data<Schema, encode::Json>& to_encode){
- // To Be encoded
- buffer_view buff_v{to_encode.get_buffer()};
- auto eov = impl::json_encode<Schema, Schema, FromEncoding>::encode(from_encode, buff_v);
- if(eov.is_error()){
- return std::move(eov.get_error());
- }
- to_encode.get_buffer().write_advance(buff_v.write_offset());
-
- return void_t{};
- }
-
- template <typename ToEncoding>
- error_or<void> decode(data<Schema, encode::Json>& from_decode, data<Schema, ToEncoding>& to_decode){
- buffer_view buff_v{from_decode.get_buffer()};
-
- auto eov = impl::json_decode<Schema, Schema, ToEncoding>::decode(buff_v, to_decode);
- if(eov.is_error()){
- return std::move(eov.get_error());
- }
- from_decode.get_buffer().read_advance(buff_v.read_offset());
-
- return void_t {};
- }
-};
-}
-
diff --git a/src/codec-json/json.tmpl.h b/src/codec-json/json.tmpl.h
deleted file mode 100644
index 4b3a1a2..0000000
--- a/src/codec-json/json.tmpl.h
+++ /dev/null
@@ -1,734 +0,0 @@
-#pragma once
-
-#include <charconv>
-#include <sstream>
-
-#include <iostream>
-
-namespace saw {
-namespace impl {
-template<typename Schema, typename RootSchema, typename FromEncode>
-class json_encode {
- static_assert(always_false<Schema, RootSchema, FromEncode>, "This schema type is not being handled by the json encoding.");
-};
-
-template<typename T, size_t N, typename RootSchema, typename FromEncode>
-struct json_encode<schema::Primitive<T,N>, RootSchema, FromEncode> {
- static error_or<void> encode(const data<schema::Primitive<T,N>, FromEncode>& from, buffer& to) {
- auto val = from.get();
- std::array<uint8_t, 256> data;
- auto tc_result = std::to_chars(reinterpret_cast<char*>(data.data()), reinterpret_cast<char*>(data.data())+data.size(), val);
-
- if(tc_result.ec != std::errc{}){
- return make_error<err::critical>();
- }
-
- size_t bytes_written = 0;
- for(char* ptr = reinterpret_cast<char*>(data.data()); ptr != tc_result.ptr; ++ptr){
- ++bytes_written;
- }
-
- auto& buff = to;
- error err = buff.write_require_length(bytes_written);
- if(!err.template is_type<err::no_error>()){
- return std::move(err);
- }
-
- for(char* ptr = reinterpret_cast<char*>(data.data()); ptr != tc_result.ptr; ++ptr){
- uint8_t* un_ptr = reinterpret_cast<uint8_t*>(ptr);
- buff.push(un_ptr[0]);
- }
-
- return void_t{};
- }
-};
-
-template<typename RootSchema, typename FromEncode>
-struct json_encode<schema::String, RootSchema, FromEncode> {
- static error_or<void> encode(const data<schema::String, FromEncode>& from, buffer& to) {
- {
- auto err = to.push('"');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- for(std::size_t i = 0; i < from.size(); ++i){
- auto err = to.push(from.get_at(i));
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- {
- auto err = to.push('"');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
-
- return void_t{};
- }
-};
-
-template<typename... T, typename RootSchema, typename FromEncode>
-struct json_encode<schema::Tuple<T...>, RootSchema, FromEncode> {
- template<size_t i>
- static error_or<void> encode_element(const data<schema::Tuple<T...>, FromEncode>& from, buffer& to){
- auto eov = json_encode<typename parameter_pack_type<i, T...>::type, RootSchema, FromEncode>::encode(from.template get<i>(), to);
-
- if(eov.is_error()){
- return eov;
- }
-
- if constexpr ( (i+1) < sizeof...(T)){
- {
- auto eov_ele = to.push(',');
- if(!eov_ele.template is_type<err::no_error>()){
- return eov_ele;
- }
- }
- {
- auto eov_ele = encode_element<i+1>(from, to);
- if(eov_ele.is_error()){
- return eov_ele;
- }
- }
-
-
- }
- return void_t{};
- }
-
- static error_or<void> encode(const data<schema::Tuple<T...>, FromEncode>& from, buffer& to) {
- {
- auto err = to.push('[');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- if constexpr ( sizeof...(T) > 0 ){
- auto eov = encode_element<0>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- auto err = to.push(']');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
-
- return void_t{};
- }
-};
-
-template<typename T, size_t D, typename RootSchema, typename FromEncode>
-struct json_encode<schema::Array<T,D>, RootSchema, FromEncode> {
- template<size_t Level>
- static error_or<void> encode_level(const data<schema::Array<T,D>, FromEncode>& from, buffer& to, std::array<std::size_t, D>& index){
- if constexpr (Level == D){
- auto eov = json_encode<T, RootSchema, FromEncode>::encode(from.at(index), to);
- if(eov.is_error()){
- return eov;
- }
- } else {
- {
- auto err = to.push('[');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- for(std::size_t i = 0; i < from.get_dim_size(Level); ++i){
- if( i > 0 ){
- auto err = to.push(',');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- {
- index[Level] = i;
- auto eov = encode_level<Level+1>(from, to, index);
- if(eov.is_error()){
- return eov;
- }
- }
- }
- {
- auto err = to.push(']');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- }
- return void_t{};
- }
-
- static error_or<void> encode(const data<schema::Array<T,D>, FromEncode>& from, buffer& to) {
- std::array<std::size_t, D> index;
- return encode_level<0>(from, to, index);
- }
-};
-
-template<typename... T, string_literal... Key, typename RootSchema, typename FromEncode>
-struct json_encode<schema::Struct<schema::Member<T,Key>...>, RootSchema, FromEncode> {
-
- template<size_t i>
- static error_or<void> encode_element(const data<schema::Struct<schema::Member<T,Key>...>, FromEncode>& from, buffer& to){
- // Encode the name
- {
- std::string_view view = parameter_key_pack_type<i, Key...>::literal.view();
- error err = to.push('"');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- err = to.push(*reinterpret_cast<const uint8_t *>(view.data()), view.size());
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- err = to.push('"');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- // Add the separator
- {
- auto eov_ele = to.push(':');
- if(!eov_ele.template is_type<err::no_error>()){
- return eov_ele;
- }
- }
-
- // Encode the value
- auto eov = json_encode<typename parameter_pack_type<i, T...>::type, RootSchema, FromEncode>::encode(from.template get<parameter_key_pack_type<i, Key...>::literal>(), to);
-
- // Go to the next element
- if constexpr ( (i+1) < sizeof...(T)){
- {
- auto eov_ele = to.push(',');
- if(!eov_ele.template is_type<err::no_error>()){
- return eov_ele;
- }
- }
- {
- auto eov_ele = encode_element<i+1>(from, to);
- if(eov_ele.is_error()){
- return eov_ele;
- }
- }
-
-
- }
-
- return void_t{};
- }
- static error_or<void> encode(const data<schema::Struct<schema::Member<T,Key>...>, FromEncode>& from, buffer& to) {
- {
- auto err = to.push('{');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- if constexpr ( sizeof...(T) > 0 ){
- auto eov = encode_element<0>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- auto err = to.push('}');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
-
- return void_t{};
- }
-};
-
-template<typename... T, string_literal... Key, typename RootSchema, typename FromEncode>
-struct json_encode<schema::Union<schema::Member<T,Key>...>, RootSchema, FromEncode> {
-
- template<size_t i>
- static error_or<void> encode_element(const data<schema::Union<schema::Member<T,Key>...>, FromEncode>& from, buffer& to){
- if(from.template holds_alternative<typename parameter_key_pack_type<i, Key...>::literal>()){
- // Encode the name
- {
- std::string_view view = parameter_key_pack_type<i, Key...>::literal.view();
- error err = to.push('"');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- err = to.push(*reinterpret_cast<const uint8_t *>(view.data()), view.size());
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- err = to.push('"');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- // Add the separator
- {
- auto eov_ele = to.push(':');
- if(!eov_ele.template is_type<err::no_error>()){
- return eov_ele;
- }
- }
-
- // Encode the value
- auto eov = json_encode<typename parameter_pack_type<i, T...>::type, RootSchema, FromEncode>::encode(from.template get<parameter_key_pack_type<i, Key...>::literal>(), to);
- }
- // Go to the next element
- if constexpr ( (i+1) < sizeof...(T)){
- {
- auto eov_ele = encode_element<i+1>(from, to);
- if(eov_ele.is_error()){
- return eov_ele;
- }
- }
-
-
- }
-
- return void_t{};
- }
- static error_or<void> encode(const data<schema::Union<schema::Member<T,Key>...>, FromEncode>& from, buffer& to) {
- {
- auto err = to.push('{');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
- if constexpr ( sizeof...(T) > 0 ){
- auto eov = encode_element<0>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- auto err = to.push('}');
- if(!err.template is_type<err::no_error>()){
- return err;
- }
- }
-
- return void_t{};
- }
-};
-
-struct json_helper {
- static bool is_whitespace(int8_t ch) {
- return ch == '\t' || ch == ' ' || ch == '\r' || ch == '\n';
- }
-
- static void skip_whitespace(buffer_view& buff) {
- while(buff.read_composite_length() > 0 && json_helper::is_whitespace(buff.read())) {
- buff.read_advance(1);
- }
- }
-};
-
-template<typename Schema, typename RootSchema, typename ToDecode>
-struct json_decode;
-
-template<typename T, size_t N, typename RootSchema, typename ToDecode>
-struct json_decode<schema::Primitive<T,N>, RootSchema, ToDecode> {
- static error_or<void> decode(buffer_view& buff, data<schema::Primitive<T,N>, ToDecode>& to) {
- assert(
- ( buff.read() >= '0' && buff.read() <= '9')
- || ( buff.read() == '+' || buff.read() == '-')
- );
-
- std::size_t offset = 0;
-
- if (buff.read() == '-'){
- ++offset;
- } else if (buff.read() == '+'){
- return make_error<err::not_supported>();
- }
- if (offset >= buff.read_composite_length()) {
- return make_error<err::buffer_exhausted>();
- }
- if (buff.read(offset) >= '1' && buff.read(offset) <= '9') {
- ++offset;
-
- if(offset >= buff.read_composite_length()) {
- return make_error<err::buffer_exhausted>();
- }
-
- while(1){
- if (buff.read(offset) >= '0' && buff.read(offset) <= '9') {
- ++offset;
-
- if(offset >= buff.read_composite_length()) {
- break;
- }
- continue;
- }
- break;
- }
- } else if (buff.read(offset) == '0' ) {
- ++offset;
- } else {
- return make_error<err::buffer_exhausted>();
- }
-
- {
- std::string_view num_view{reinterpret_cast<char*>(&buff.read()), offset};
- typename native_data_type<schema::Primitive<T,N>>::type result;
- auto fc_result = std::from_chars(num_view.data(), num_view.data() + num_view.size(), result);
- if(fc_result.ec != std::errc{}){
- return make_error<err::invalid_state>();
- }
-
- to.set(result);
- }
- buff.read_advance(offset);
-
- return void_t{};
- }
-};
-
-template<typename RootSchema, typename ToDecode>
-struct json_decode<schema::String, RootSchema, ToDecode> {
- static error_or<void> decode(buffer_view& buff, data<schema::String, ToDecode>& to){
- assert(buff.read() == '"');
- buff.read_advance(1);
-
- std::stringstream iss;
- bool string_done = false;
- while(!string_done){
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
-
- switch(buff.read()){
- case '\\':{
- buff.read_advance(1);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- switch(buff.read()){
- case '\\':
- case '/':
- case '"':
- iss<< buff.read();
- break;
- case 'b':
- iss<<'\b';
- break;
- case 'f':
- iss<<'\f';
- break;
- case 'n':
- iss<<'\n';
- break;
- case 'r':
- iss<<'\r';
- break;
- case 't':
- iss<<'\t';
- break;
- case 'u': {
- buff.read_advance(1);
- if(buff.read_composite_length() < 4){
- return make_error<err::buffer_exhausted>();
- }
- iss<<'?';
- iss<<'?';
- iss<<'?';
- iss<<'?';
-
- buff.read_advance(3);
- } break;
- }
- } break;
- case '"':
- string_done = true;
- break;
- default:{
- // Avoids Control sequences
- if(buff.read() >= ' ' && buff.read() <= '~'){
- iss<<buff.read();
- }
- // Avoid Unicode
- else if (buff.read() < 0) {
- do {
- buff.read_advance(1);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- } while( buff.read() < 0 );
- iss<<'?';
- }
- break;
- }
- }
- buff.read_advance(1);
- }
-
- std::string raw = iss.str();
- to.set(std::move(raw));
-
- return void_t{};
- }
-};
-
-template<typename... T, string_literal... Lits, typename RootSchema, typename ToDecode>
-struct json_decode<schema::Struct<schema::Member<T,Lits>...>, RootSchema, ToDecode> {
- template<std::size_t i>
- static error_or<void> decode_field_search(buffer_view& buff, data<schema::Struct<schema::Member<T,Lits>...>, ToDecode>& to, std::array<bool, sizeof...(T)>& fields, const data<schema::String,ToDecode>& search_name){
- if constexpr ( i < sizeof...(T)){
- using Type = typename parameter_pack_type<i, T...>::type;
- constexpr static string_literal Literal = parameter_key_pack_type<i, Lits...>::literal;
- if(search_name == Literal.view()){
- if(fields[i]){
- return make_error<err::invalid_state>();
- }
- fields[i] = true;
- auto eov = json_decode<Type, RootSchema, ToDecode>::decode(buff, to.template get<Literal>());
- if(eov.is_error()){
- return eov;
- }
- }else {
- decode_field_search<i+1>(buff, to, fields, search_name);
- }
- }else {
- return make_error<err::invalid_state>();
- }
- return void_t{};
- }
-
- static error_or<void> decode_fields(buffer_view& buff, data<schema::Struct<schema::Member<T,Lits>...>, ToDecode>& to, std::array<bool, sizeof...(T)>& fields){
- for(;;){
- data<schema::String, ToDecode> name;
- auto eov = json_decode<schema::String, RootSchema, ToDecode>::decode(buff, name);
- if(eov.is_error()){
- return eov;
- }
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- if(buff.read() != ':'){
- return make_error<err::invalid_state>();
- }
- buff.read_advance(1);
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- {
- auto eov = decode_field_search<0>(buff, to, fields, name);
- if(eov.is_error()){
- return eov;
- }
- }
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- if(buff.read() == ','){
- buff.read_advance(1);
- }else if(buff.read() == '}'){
- // If not all fields are set, the dataset is incomplete
- for(auto& iter : fields){
- if(!iter){
- return make_error<err::invalid_state>();
- }
- }
- buff.read_advance(1);
- return void_t{};
- }else{
- return make_error<err::invalid_state>();
- }
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- }
- return void_t{};
- }
-
- static error_or<void> decode(buffer_view& buff, data<schema::Struct<schema::Member<T,Lits>...>, ToDecode>& to){
- std::array<bool, sizeof...(T)> found_fields;
- std::fill(found_fields.begin(), found_fields.end(), false);
-
- assert(buff.read() == '{');
- buff.read_advance(1);
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
-
- // Check if there are no elements present in the JSON Struct
- if(buff.read() == '}'){
- if(sizeof...(T) > 0){
- return make_error<err::invalid_state>();
- }
- buff.read_advance(1);
- return void_t{};
- }
-
- auto eov = decode_fields(buff, to, found_fields);
- if(eov.is_error()){
- return eov;
- }
-
- return void_t{};
- }
-};
-
-template<typename... T, typename RootSchema, typename ToDecode>
-struct json_decode<schema::Tuple<T...>, RootSchema, ToDecode> {
- template<std::size_t i>
- static error_or<void> decode_element(buffer_view& buff, data<schema::Tuple<T...>, ToDecode>& to){
- if constexpr (i < sizeof...(T)){
- if constexpr ( i > 0 ){
- if(buff.read() != ','){
- return make_error<err::invalid_state>();
- }
- buff.read_advance(1);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
- }
- using Type = typename parameter_pack_type<i, T...>::type;
-
- auto eov = json_decode<Type, RootSchema, ToDecode>::decode(buff, to.template get<i>());
- if(eov.is_error()){
- return eov;
- }
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
-
- eov = decode_element<i+1>(buff, to);
- if(eov.is_error()){
- return eov;
- }
- }else{
- if(buff.read() != ']'){
- return make_error<err::invalid_state>();
- }
- buff.read_advance(1);
- }
- return void_t{};
- }
-
- static error_or<void> decode(buffer_view& buff, data<schema::Tuple<T...>, ToDecode>& to){
- assert(buff.read() == '[');
- buff.read_advance(1);
-
- json_helper::skip_whitespace(buff);
- if(buff.read_composite_length() == 0){
- return make_error<err::buffer_exhausted>();
- }
-
- auto eov = decode_element<0>(buff, to);
- if(eov.is_error()){
- return eov;
- }
-
- return void_t{};
- }
-};
-
-// The whole std::vector approach is hacky af. ToDo change it maybe?
-template<typename T, size_t D, typename RootSchema, typename ToDecode>
-struct json_decode<schema::Array<T,D>, RootSchema, ToDecode> {
- template<size_t Level>
- static error_or<void> decode_flat_level(buffer_view& buff, std::vector<data<T, encode::Native>>& to, std::array<std::size_t, D>& index, std::array<std::size_t, D>& dims, bool log_dim){
- if constexpr (Level == D) {
- json_helper::skip_whitespace(buff);
- try {
- to.push_back({});
- }catch(std::exception& e){
- return make_error<err::out_of_memory>();
- }
- auto eov = json_decode<T, RootSchema, ToDecode>::decode(buff, to.back());
- if(eov.is_error()){
- return eov;
- }
- } else {
- assert(buff.read() == '[');
- buff.read_advance(1);
-
- json_helper::skip_whitespace(buff);
- if ( buff.read_composite_length() == 0 ){
- return make_error<err::buffer_exhausted>();
- }
-
- index[Level] = 0;
- for(;;){
- // We should have an element right now
- auto eov = decode_flat_level<Level+1>(buff,to,index,dims, index[Level] == 0 && log_dim);
- if(eov.is_error()){
- return eov;
- }
- json_helper::skip_whitespace(buff);
- if ( buff.read_composite_length() == 0 ){
- return make_error<err::buffer_exhausted>();
- }
-
- ++index[Level];
- if(buff.read() == ','){
- buff.read_advance(1);
- } else if(buff.read() == ']'){
- buff.read_advance(1);
- break;
- } else {
- return make_error<err::invalid_state>();
- }
- json_helper::skip_whitespace(buff);
- if ( buff.read_composite_length() == 0 ){
- return make_error<err::buffer_exhausted>();
- }
- }
- if(log_dim){
- dims[Level] = index[Level];
- }else if (dims[Level] != index[Level]){
- return make_error<err::invalid_state>();
- }
- }
- return void_t{};
- }
-
- template<std::size_t Level>
- static error_or<void> decode_unflat_level(std::vector<data<T,encode::Native>>& flat, data<schema::Array<T,D>, ToDecode>& to, std::array<std::size_t, D>& index, std::size_t& flat_index) {
- if constexpr ( Level == D ){
- auto& flat_data = flat.at(flat_index);
- to.at(index) = std::move(flat_data);
- ++flat_index;
- }else {
- const std::size_t dim_size = to.get_dim_size(Level);
- for(index[Level] = 0; index[Level] < dim_size; ++index[Level]){
-
- auto eov = decode_unflat_level<Level+1>(flat, to, index, flat_index);
- if(eov.is_error()){
- return eov;
- }
- }
- }
- return void_t{};
- }
-
- static error_or<void> decode(buffer_view& buff, data<schema::Array<T,D>, ToDecode>& to){
- std::array<std::size_t, D> index;
- std::array<std::size_t, D> dims;
- std::fill(dims.begin(), dims.end(), 0);
- std::vector<data<T,encode::Native>> flat_array;
- auto eov = decode_flat_level<0>(buff, flat_array, index, dims, true);
- if(eov.is_error()){
- return eov;
- }
-
- to = {dims};
- std::size_t flat_index = 0;
-
- return decode_unflat_level<0>(flat_array, to, index, flat_index);
- }
-};
-}
-}
diff --git a/src/codec/.nix/derivation.nix b/src/codec/.nix/derivation.nix
deleted file mode 100644
index 768dc6e..0000000
--- a/src/codec/.nix/derivation.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-codec";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- buildInputs = [
- forstio.core
- ];
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/codec/SConscript b/src/codec/SConscript
deleted file mode 100644
index c038d42..0000000
--- a/src/codec/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-codec_env = env.Clone();
-
-codec_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-codec_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += codec_env.sources;
-env.headers += codec_env.headers;
-
-## Shared lib
-objects_shared = []
-codec_env.add_source_files(objects_shared, codec_env.sources, shared=True);
-codec_env.library_shared = codec_env.SharedLibrary('#build/forstio-codec', [objects_shared]);
-
-## Static lib
-objects_static = []
-codec_env.add_source_files(objects_static, codec_env.sources, shared=False);
-codec_env.library_static = codec_env.StaticLibrary('#build/forstio-codec', [objects_static]);
-
-# Set Alias
-env.Alias('library_codec', [codec_env.library_shared, codec_env.library_static]);
-
-env.targets += ['library_codec'];
-
-# Install
-env.Install('$prefix/lib/', [codec_env.library_shared, codec_env.library_static]);
-env.Install('$prefix/include/forstio/codec/', [codec_env.headers]);
diff --git a/src/codec/SConstruct b/src/codec/SConstruct
deleted file mode 100644
index 0d7b7c6..0000000
--- a/src/codec/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-core'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/codec/data.h b/src/codec/data.h
deleted file mode 100644
index 8ff06dc..0000000
--- a/src/codec/data.h
+++ /dev/null
@@ -1,317 +0,0 @@
-#pragma once
-
-#include <forstio/core/common.h>
-#include <forstio/core/templates.h>
-
-#include <cassert>
-
-#include <array>
-#include <concepts>
-#include <variant>
-#include <vector>
-
-#include "schema.h"
-
-namespace saw {
-namespace encode {
-struct Native {};
-}
-template<typename Schema, typename Encode>
-class codec;
-/*
- * Helper for the basic message container, so the class doesn't have to be
- * specialized 10 times.
- */
-template <class T> struct native_data_type;
-
-template <>
-struct native_data_type<schema::Primitive<schema::SignedInteger, 1>> {
- using type = int8_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::SignedInteger, 2>> {
- using type = int16_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::SignedInteger, 4>> {
- using type = int32_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::SignedInteger, 8>> {
- using type = int64_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::UnsignedInteger, 1>> {
- using type = uint8_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::UnsignedInteger, 2>> {
- using type = uint16_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::UnsignedInteger, 4>> {
- using type = uint32_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::UnsignedInteger, 8>> {
- using type = uint64_t;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::FloatingPoint, 4>> {
- using type = float;
-};
-
-template <>
-struct native_data_type<schema::Primitive<schema::FloatingPoint, 8>> {
- using type = double;
-};
-
-template<typename T, typename Encoding = encode::Native>
-class data {
-private:
- static_assert(always_false<T>, "Type not supported");
-};
-
-template<typename... T, string_literal... literals>
-class data<schema::Union<schema::Member<T, literals>...>, encode::Native> {
-private:
- std::variant<data<T,encode::Native>...> value_;
-public:
- data() = default;
-
- SAW_DEFAULT_COPY(data);
- SAW_DEFAULT_MOVE(data);
-
- template<string_literal lit>
- void set(data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native> val){
- value_ = std::move(val);
- }
-
- template<string_literal lit>
- data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& init(){
- value_ = data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>{};
- return get<lit>();
- }
-
- template<string_literal lit>
- bool holds_alternative() const {
- return (parameter_key_pack_index<lit, literals...>::value == value_.index());
- }
-
- template<string_literal lit>
- data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& get(){
- return std::get<parameter_key_pack_index<lit, literals...>::value>(value_);
- }
-
- template<string_literal lit>
- const data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& get() const{
- return std::get<parameter_key_pack_index<lit, literals...>::value>(value_);
- }
-};
-
-template<typename... T, string_literal... literals>
-class data<schema::Struct<schema::Member<T, literals>...>, encode::Native> {
-private:
- std::tuple<data<T,encode::Native>...> value_;
-public:
- data() = default;
- SAW_DEFAULT_COPY(data);
- SAW_DEFAULT_MOVE(data);
-
- template<string_literal literal>
- data<
- typename parameter_pack_type<
- parameter_key_pack_index<
- literal, literals...
- >::value
- , T...>::type
- , encode::Native>& get(){
- return std::get<parameter_key_pack_index<literal, literals...>::value>(value_);
- }
-
- template<string_literal literal>
- const data<
- typename parameter_pack_type<
- parameter_key_pack_index<
- literal, literals...
- >::value
- , T...>::type
- , encode::Native>& get() const {
- return std::get<parameter_key_pack_index<literal, literals...>::value>(value_);
- }
-
- constexpr size_t size() const {
- return sizeof...(T);
- }
-};
-
-template<typename... T>
-class data<schema::Tuple<T...>, encode::Native> {
-private:
- std::tuple<data<T,encode::Native>...> value_;
-public:
- data() = default;
- SAW_DEFAULT_COPY(data);
- SAW_DEFAULT_MOVE(data);
-
- template<size_t i>
- data<typename parameter_pack_type<i,T...>::type, encode::Native>& get(){
- return std::get<i>(value_);
- }
-
- template<size_t i>
- const data<typename parameter_pack_type<i,T...>::type, encode::Native>& get() const{
- return std::get<i>(value_);
- }
-
- constexpr size_t size() const {
- return sizeof...(T);
- }
-};
-
-template<typename T, size_t Dim>
-class data<schema::Array<T,Dim>, encode::Native> {
- private:
- std::array<std::size_t, Dim> dims_;
- std::vector<data<T, encode::Native>> value_;
-
- std::size_t get_full_size() const {
- std::size_t s = 1;
-
- for(std::size_t iter = 0; iter < Dim; ++iter){
- assert(dims_.at(iter) > 0);
- s *= dims_.at(iter);
- }
-
- return s;
- }
- public:
- data() = default;
- SAW_DEFAULT_COPY(data);
- SAW_DEFAULT_MOVE(data);
-
- data(const std::array<std::size_t, Dim>& i):
- dims_{i},
- value_{}
- {
- value_.resize(get_full_size());
- }
-
- template<std::integral... Dims>
- data(Dims... size_):
- data{{size_...}}
- {
- static_assert(sizeof...(Dims)==Dim, "Argument size must be equal to the Dimension");
- }
-
- data<T, encode::Native>& at(const std::array<std::size_t, Dim>& ind){
- return value_.at(this->get_flat_index(ind));
- }
-
- const data<T, encode::Native>& at(const std::array<std::size_t, Dim>& ind) const {
- return value_.at(this->get_flat_index(ind));
- }
-
- template<std::integral... Dims>
- data<T, encode::Native>& at(Dims... i){
- return value_.at(this->get_flat_index({i...}));
- }
-
- template<std::integral... Dims>
- const data<T, encode::Native>& at(Dims... i) const {
- return value_.at(this->get_flat_index({i...}));
- }
-
- std::size_t get_dim_size(std::size_t i) const {
- return dims_.at(i);
- }
-
- size_t size() const { return value_.size();}
-
-private:
- std::size_t get_flat_index(const std::array<std::size_t, Dim>& i) const {
- std::size_t s = 0;
-
- std::size_t stride = 1;
-
- for(std::size_t iter = 0; iter < Dim; ++iter){
- s += i.at(iter) * stride;
- stride *= dims_.at(iter);
- }
-
- return s;
- }
-};
-
-template<>
-class data<schema::String, encode::Native> {
-private:
- std::string value_;
-public:
- data() = default;
- SAW_DEFAULT_COPY(data);
- SAW_DEFAULT_MOVE(data);
-
- data(std::string value__):value_{std::move(value__)}{}
- data(std::size_t size_){
- value_.resize(size_);
- }
-
- std::size_t size() const {
- return value_.size();
- }
-
- void set(std::string str){
- value_ = std::move(str);
- }
-
- char& at(size_t i) {
- return value_.at(i);
- }
-
- const char& at(size_t i) const {
- return value_.at(i);
- }
-
- char get_at(size_t i) const{
- return value_.at(i);
- }
-
- void set_at(size_t i, char val){
- value_.at(i) = val;
- }
-
- bool operator==(const std::string_view& val)const{
- return value_ == val;
- }
-};
-
-template<typename T, size_t N>
-class data<schema::Primitive<T,N>, encode::Native> {
-private:
- typename native_data_type<schema::Primitive<T,N>>::type value_;
-public:
- data():value_{{}}{};
- SAW_DEFAULT_COPY(data);
- SAW_DEFAULT_MOVE(data);
-
- data(typename native_data_type<schema::Primitive<T,N>>::type value__):
- value_{std::move(value__)}{}
-
- void set(typename native_data_type<schema::Primitive<T,N>>::type val){
- value_ = val;
- }
-
- typename native_data_type<schema::Primitive<T,N>>::type get() const {return value_;}
-};
-
-
-}
diff --git a/src/codec/forst.h b/src/codec/forst.h
deleted file mode 100644
index cadf78e..0000000
--- a/src/codec/forst.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include "data.h"
-
-namespace saw {
-namespace encode {
-struct KelForst {};
-}
-
-class data<schema::String, encode::KelForst> {
-
-};
-}
diff --git a/src/codec/schema.h b/src/codec/schema.h
deleted file mode 100644
index 2f63fe9..0000000
--- a/src/codec/schema.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#pragma once
-
-#include <forstio/core/common.h>
-#include <forstio/core/string_literal.h>
-
-namespace saw {
-namespace schema {
-// NOLINTBEGIN
-template <typename T, string_literal Literal> struct Member {};
-
-template <typename... T> struct Struct {
- static_assert(
- always_false<T...>,
- "This schema template doesn't support this type of template argument");
-};
-
-template <typename... V, string_literal... K>
-struct Struct<Member<V, K>...> {};
-
-template <typename... T> struct Union {
- static_assert(
- always_false<T...>,
- "This schema template doesn't support this type of template argument");
-};
-
-template <typename... V, string_literal... K>
-struct Union<Member<V, K>...> {};
-
-template <typename T, size_t Dim = 1> struct Array {};
-
-template <class T> struct is_array {
- constexpr static bool value = false;
-};
-
-template <class T, size_t Dim> struct is_array<schema::Array<T,Dim>> {
- constexpr static bool value = true;
-};
-
-template<typename T, size_t... S> struct FixedArray {};
-
-template <typename... T> struct Tuple {};
-
-/**
- * This acts as a separator of different encodings being mashed together
- */
-template <typename T, typename Enc>
-class Wrapper {};
-
-struct String {};
-
-struct SignedInteger {};
-struct UnsignedInteger {};
-struct FloatingPoint {};
-
-template <class T, size_t N> struct Primitive {
- static_assert(((std::is_same_v<T, SignedInteger> ||
- std::is_same_v<T, UnsignedInteger>)&&(N == 1 || N == 2 ||
- N == 4 || N == 8)) ||
- (std::is_same_v<T, FloatingPoint> && (N == 4 || N == 8)),
- "Primitive Type is not supported");
-};
-
-using Int8 = Primitive<SignedInteger, 1>;
-using Int16 = Primitive<SignedInteger, 2>;
-using Int32 = Primitive<SignedInteger, 4>;
-using Int64 = Primitive<SignedInteger, 8>;
-
-using UInt8 = Primitive<UnsignedInteger, 1>;
-using UInt16 = Primitive<UnsignedInteger, 2>;
-using UInt32 = Primitive<UnsignedInteger, 4>;
-using UInt64 = Primitive<UnsignedInteger, 8>;
-
-using Float32 = Primitive<FloatingPoint, 4>;
-using Float64 = Primitive<FloatingPoint, 8>;
-
-/**
- * Classes enabling Rpc calls
- */
-template <class Request, class Response, string_literal Literal>
-struct Function {};
-
-template <class... T> struct Interface {
- static_assert(
- always_false<T...>,
- "This schema template doesn't support this type of template argument");
-};
-
-template <class... Request, class... Response, string_literal... Literal>
-struct Interface<Function<Request, Response, Literal>...> {};
-
-// NOLINTEND
-} // namespace schema
-} // namespace saw
diff --git a/src/codec/simple.h b/src/codec/simple.h
deleted file mode 100644
index 8760754..0000000
--- a/src/codec/simple.h
+++ /dev/null
@@ -1,389 +0,0 @@
-#pragma once
-
-#include "data.h"
-#include "stream_value.h"
-
-#include <forstio/core/buffer.h>
-#include <forstio/core/error.h>
-
-namespace saw {
-namespace encode {
-struct KelSimple {};
-}
-
-template<typename T>
-class data<T, encode::KelSimple> {
-private:
- ring_buffer buffer_;
-public:
- data() = default;
-
- buffer& get_buffer(){
- return buffer_;
- }
-};
-
-namespace impl {
-template<typename Schema, typename FromEnc>
-class kelsimple_encode {
- static_assert(always_false<Schema, FromEnc>, "This schema type is not being handled by the kelsimple encoding.");
-};
-
-template<typename T, size_t N, typename FromEnc>
-struct kelsimple_encode<schema::Primitive<T,N>, FromEnc> {
- static error_or<void> encode(const data<schema::Primitive<T,N>, FromEnc>& from, buffer& to){
- auto eov = stream_value<schema::Primitive<T,N>>::encode(from.get(), to);
- return eov;
- }
-};
-
-template<typename T, size_t Dim, typename FromEnc>
-struct kelsimple_encode<schema::Array<T,Dim>, FromEnc> {
- template<std::size_t Level>
- static error_or<void> encode_level(const data<schema::Array<T,Dim>, FromEnc>& from, buffer& to, std::array<std::size_t, Dim>& index){
- if constexpr (Dim == Level){
- return kelsimple_encode<T,FromEnc>::encode(from.at(index), to);
- } else {
- const std::size_t dim_size = from.get_dim_size(Level);
- for(index[Level] = 0; (index.at(Level) < dim_size); ++index[Level]){
- auto eov = encode_level<Level+1>(from, to, index);
- if(eov.is_error()){
- return eov;
- }
- }
- }
- return void_t{};
- }
-
- static error_or<void> encode(const data<schema::Array<T,Dim>, FromEnc>& from, buffer& to){
- {
- for(uint64_t i = 0; i < Dim; ++i){
- auto eov = stream_value<schema::UInt64>::encode(from.get_dim_size(i), to);
- if(eov.is_error()){
- return eov;
- }
- }
- }
- {
- std::array<std::size_t, Dim> index;
- std::fill(index.begin(), index.end(), 0);
-
- return encode_level<0>(from, to, index);
- }
- return void_t{};
- }
-};
-
-template<typename... T, string_literal... Lits, typename FromEnc>
-struct kelsimple_encode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> {
- template<std::size_t i>
- static error_or<void> encode_member(const data<schema::Struct<schema::Member<T,Lits>...>, FromEnc>& from, buffer& to){
- using Type = typename parameter_pack_type<i,T...>::type;
- constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal;
- {
- auto eov = kelsimple_encode<Type, FromEnc>::encode(from.template get<Literal>(), to);
- if(eov.is_error()){
- return eov;
- }
- }
- if constexpr ((i+1) < sizeof...(T)){
- auto eov = encode_member<i+1>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- return void_t{};
- }
-
- static error_or<void> encode(const data<schema::Struct<schema::Member<T,Lits>...>, FromEnc>& from, buffer& to){
- return encode_member<0>(from, to);
- }
-};
-
-template<typename... T, string_literal... Lits, typename FromEnc>
-struct kelsimple_encode<schema::Union<schema::Member<T,Lits>...>,FromEnc> {
- template<std::size_t i>
- static error_or<void> encode_member(const data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& from, buffer& to){
- using Type = typename parameter_pack_type<i,T...>::type;
- constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal;
- if (from.template holds_alternative<Literal>()) {
- {
- auto eov = stream_value<schema::UInt64>::encode(static_cast<uint64_t>(i), to);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- auto eov = kelsimple_encode<Type, FromEnc>::encode(from.template get<Literal>(), to);
- if(eov.is_error()){
- return eov;
- }
- }
- }
-
- if constexpr ( (i+1) < sizeof...(T) ){
- auto eov = encode_member<i+1>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- return void_t{};
- }
-
- static error_or<void> encode(const data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& from, buffer& to){
- return encode_member<0>(from, to);
- }
-};
-
-template<typename... T, typename FromEnc>
-struct kelsimple_encode<schema::Tuple<T...>, FromEnc> {
- template<std::size_t i>
- static error_or<void> encode_member(const data<schema::Tuple<T...>, FromEnc>& from, buffer& to){
- using Type = typename parameter_pack_type<i,T...>::type;
- {
- auto eov = kelsimple_encode<Type, FromEnc>::encode(from.template get<i>(), to);
- }
- if constexpr ((i+1) < sizeof...(T)){
- auto eov = encode_member<i+1>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- return void_t{};
- }
-
- static error_or<void> encode(const data<schema::Tuple<T...>, FromEnc>& from, buffer& to){
- return encode_member<0>(from, to);
- }
-};
-
-template<typename FromEnc>
-struct kelsimple_encode<schema::String, FromEnc> {
- static error_or<void> encode(const data<schema::String, FromEnc>& from, buffer& to){
- const auto str_size = from.size();
- typename native_data_type<schema::UInt64>::type str_len = static_cast<uint64_t>(str_size);
- {
- auto eov = stream_value<schema::UInt64>::encode(str_len, to);
- if(eov.is_error()){
- return eov;
- }
- }
-
- for(std::size_t i = 0; i < str_size; ++i){
- auto eov = stream_value<schema::Int8>::encode(from.at(i), to);
- if(eov.is_error()){
- return eov;
- }
- }
-
- return void_t{};
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-template<typename Schema, typename FromEnc>
-class kelsimple_decode {
- static_assert(always_false<Schema, FromEnc>, "This schema type is not being handled by the kelsimple encoding.");
-};
-
-template<typename T, size_t N, typename FromEnc>
-struct kelsimple_decode<schema::Primitive<T,N>, FromEnc> {
- static error_or<void> decode(buffer& from, data<schema::Primitive<T,N>, FromEnc>& to){
- typename native_data_type<schema::Primitive<T,N>>::type val{};
- auto eov = stream_value<schema::Primitive<T,N>>::decode(val, from);
- if (eov.is_value()) {
- to.set(val);
- }
- return eov;
- }
-
-};
-
-template<typename T, size_t Dim, typename FromEnc>
-struct kelsimple_decode<schema::Array<T,Dim>, FromEnc> {
- template<std::size_t Level>
- static error_or<void> decode_level(buffer& from, data<schema::Array<T,Dim>, FromEnc>& to, std::array<std::size_t, Dim>& index){
- if constexpr (Level == Dim){
- return kelsimple_decode<T, FromEnc>::decode(from, to.at(index));
- }else{
- const std::size_t dim_size = to.get_dim_size(Level);
- for(index[Level] = 0; index[Level] < dim_size; ++index[Level]){
- auto eov = decode_level<Level+1>(from, to, index);
- if(eov.is_error()){
- return eov;
- }
- }
- }
- return void_t{};
- }
-
- static error_or<void> decode(buffer& from, data<schema::Array<T,Dim>, FromEnc>& to){
- {
- std::array<std::size_t, Dim> dims{};
- for(std::size_t i = 0; i < Dim; ++i){
- uint64_t val{};
- auto eov = stream_value<schema::UInt64>::decode(val, from);
- if(eov.is_error()){
- return eov;
- }
- dims.at(i) = static_cast<std::size_t>(val);
- }
- to = data<schema::Array<T,Dim>,FromEnc>{dims};
- }
- {
- std::array<std::size_t, Dim> index{};
- return decode_level<0>(from, to, index);
- }
- return void_t{};
- }
-};
-template<typename... T, string_literal... Lits, typename FromEnc>
-struct kelsimple_decode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> {
- template<std::size_t i>
- static error_or<void> decode_member(buffer& from, data<schema::Struct<schema::Member<T,Lits>...>, FromEnc>& to){
- using Type = typename parameter_pack_type<i,T...>::type;
- constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal;
- {
- auto eov = kelsimple_decode<Type, FromEnc>::decode(from, to.template get<Literal>());
- if(eov.is_error()){
- return eov;
- }
- }
- if constexpr ((i+1) < sizeof...(T)){
- auto eov = decode_member<i+1>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- return void_t{};
-
- }
- static error_or<void> decode(buffer& from, data<schema::Struct<schema::Member<T,Lits>...>, FromEnc>& to){
- return decode_member<0>(from, to);
- }
-
-};
-
-template<typename... T, string_literal... Lits, typename FromEnc>
-struct kelsimple_decode<schema::Union<schema::Member<T,Lits>...>,FromEnc> {
- template<uint64_t i>
- static error_or<void> decode_member(buffer& from, data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& to, uint64_t val){
- using Type = typename parameter_pack_type<i,T...>::type;
- constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal;
-
- if( i == val ){
- to.template set<Literal>(data<Type, FromEnc>{});
- auto eov = kelsimple_decode<Type, FromEnc>::decode(from, to.template get<Literal>());
- if(eov.is_error()){
- return eov;
- }
- return void_t{};
- }
-
- if constexpr ((i+1) < sizeof...(T)){
- auto eov = decode_member<i+1>(from, to, val);
- if(eov.is_error()){
- return eov;
- }
- }
- return void_t{};
-
- }
- static error_or<void> decode(buffer& from, data<schema::Union<schema::Member<T,Lits>...>, FromEnc>& to){
- uint64_t val{};
- auto eov = stream_value<schema::UInt64>::decode(val, from);
- if(eov.is_error()){
- return eov;
- }
- if ( val >= sizeof...(T) ){
- return make_error<err::invalid_state>();
- }
- return decode_member<0>(from, to, val);
- }
-
-};
-
-template<typename... T, typename FromEnc>
-struct kelsimple_decode<schema::Tuple<T...>,FromEnc> {
- template<std::size_t i>
- static error_or<void> decode_member(buffer& from, data<schema::Tuple<T...>, FromEnc>& to){
- using Type = typename parameter_pack_type<i,T...>::type;
- {
- auto eov = kelsimple_decode<Type, FromEnc>::decode(from, to.template get<i>());
- }
- if constexpr ((i+1) < sizeof...(T)){
- auto eov = decode_member<i+1>(from, to);
- if(eov.is_error()){
- return eov;
- }
- }
- return void_t{};
-
- }
- static error_or<void> decode(buffer& from, data<schema::Tuple<T...>, FromEnc>& to){
- return decode_member<0>(from, to);
- }
-
-};
-template<typename FromEnc>
-struct kelsimple_decode<schema::String, FromEnc> {
- static error_or<void> decode(buffer& from, data<schema::String, FromEnc>& to){
- {
- uint64_t val{};
- auto eov = stream_value<schema::UInt64>::decode(val, from);
- if(eov.is_error()){
- return eov;
- }
- to = data<schema::String,FromEnc>{val};
- }
- const std::size_t str_size = to.size();
- for(std::size_t i = 0; i < str_size; ++i){
- int8_t val{};
- auto eov = stream_value<schema::Int8>::decode(val, from);
- if(eov.is_error()){
- return eov;
- }
- to.set_at(i, val);
- }
- return void_t{};
- }
-};
-
-}
-
-template<typename Schema>
-class codec<Schema, encode::KelSimple> {
-public:
- struct config {
- size_t depth = 16;
- size_t length = 1024;
- };
-private:
- config cfg_;
-public:
- codec() = default;
-
- SAW_FORBID_COPY(codec);
- SAW_DEFAULT_MOVE(codec);
-
- template<typename FromEnc>
- error_or<void> encode(const data<Schema, FromEnc>& from_enc, data<Schema, encode::KelSimple>& to_enc){
- buffer_view buff_v{to_enc.get_buffer()};
-
- auto eov = impl::kelsimple_encode<Schema, FromEnc>::encode(from_enc, buff_v);
-
- to_enc.get_buffer().write_advance(buff_v.write_offset());
-
- return eov;
- }
-
- template<typename ToDec>
- error_or<void> decode(data<Schema, encode::KelSimple>& from_dec, data<Schema, ToDec>& to){
- buffer_view buff_v{from_dec.get_buffer()};
-
- auto eov = impl::kelsimple_decode<Schema,ToDec>::decode(buff_v, to);
-
- return eov;
- }
-};
-}
diff --git a/src/codec/stream_value.h b/src/codec/stream_value.h
deleted file mode 100644
index 09203cb..0000000
--- a/src/codec/stream_value.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-#include "schema.h"
-
-#include <forstio/core/buffer.h>
-#include <forstio/core/error.h>
-
-#include <cstdint>
-#include <cstring>
-
-namespace saw {
-/**
- * Helper class to encode/decode any primtive type into/from litte endian.
- * The shift class does this by shifting bytes. This type of procedure is
- * platform independent. So it does not matter if the memory layout is
- * little endian or big endian
- */
-template<typename T> class shift_stream_value {
- static_assert(always_false<T>, "Shift Stream Value only supports Primitives");
-};
-
-template <typename T, size_t N> class shift_stream_value<schema::Primitive<T,N>> {
-public:
- inline static error_or<void> decode(typename native_data_type<schema::Primitive<T,N>>::type &val, buffer &buff) {
- if (buff.read_composite_length() < N) {
- return make_error<err::buffer_exhausted>();
- }
-
- typename native_data_type<schema::Primitive<schema::UnsignedInteger,N>>::type raw = 0;
-
- for (size_t i = 0; i < N; ++i) {
- raw |= (static_cast<typename native_data_type<schema::Primitive<T,N>>::type>(buff.read(i)) << (i * 8));
- }
-
- memcpy(&val, &raw, N);
- buff.read_advance(N);
-
- return void_t{};
- }
-
- inline static error_or<void> encode(const typename native_data_type<schema::Primitive<T,N>>::type &val, buffer &buff) {
- error err = buff.write_require_length(N);
- if (err.failed()) {
- return err;
- }
-
- typename native_data_type<schema::Primitive<schema::UnsignedInteger,N>>::type raw{};
- memcpy(&raw, &val, N);
-
- for (size_t i = 0; i < N; ++i) {
- buff.write(i) = raw >> (i * 8);
- }
-
- buff.write_advance(N);
-
- return void_t{};
- }
-
- inline static size_t size() { return N; }
-};
-
-template <typename T> using stream_value = shift_stream_value<T>;
-
-} // namespace saw
diff --git a/src/core/.nix/derivation.nix b/src/core/.nix/derivation.nix
deleted file mode 100644
index 26acd3d..0000000
--- a/src/core/.nix/derivation.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-}:
-
-stdenvNoCC.mkDerivation {
- pname = "forstio-core";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/core/SConscript b/src/core/SConscript
deleted file mode 100644
index 04eb4c3..0000000
--- a/src/core/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-core_env = env.Clone();
-
-core_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-core_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += core_env.sources;
-env.headers += core_env.headers;
-
-## Shared lib
-objects_shared = []
-core_env.add_source_files(objects_shared, core_env.sources, shared=True);
-core_env.library_shared = core_env.SharedLibrary('#build/forstio-core', [objects_shared]);
-
-## Static lib
-objects_static = []
-core_env.add_source_files(objects_static, core_env.sources, shared=False);
-core_env.library_static = core_env.StaticLibrary('#build/forstio-core', [objects_static]);
-
-# Set Alias
-env.Alias('library_core', [core_env.library_shared, core_env.library_static]);
-
-env.targets += ['library_core'];
-
-# Install
-env.Install('$prefix/lib/', [core_env.library_shared, core_env.library_static]);
-env.Install('$prefix/include/forstio/core/', [core_env.headers]);
diff --git a/src/core/SConstruct b/src/core/SConstruct
deleted file mode 100644
index 865d131..0000000
--- a/src/core/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=[])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/core/buffer.cpp b/src/core/buffer.cpp
deleted file mode 100644
index 15f4cae..0000000
--- a/src/core/buffer.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-#include "buffer.h"
-
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-#include <iomanip>
-#include <sstream>
-
-namespace saw {
-error buffer::push(const uint8_t &value) {
- size_t write_remain = write_composite_length();
- if (write_remain > 0) {
- write() = value;
- write_advance(1);
- } else {
- return make_error<err::buffer_exhausted>();
- }
- return no_error();
-}
-
-error buffer::push(const uint8_t &buffer, size_t size) {
- error error = write_require_length(size);
- if (error.failed()) {
- return error;
- }
- const uint8_t *buffer_ptr = &buffer;
- while (size > 0) {
- size_t segment = std::min(write_segment_length(), size);
- memcpy(&write(), buffer_ptr, segment);
- write_advance(segment);
- size -= segment;
- buffer_ptr += segment;
- }
- return no_error();
-}
-
-error buffer::pop(uint8_t &value) {
- if (read_composite_length() > 0) {
- value = read();
- read_advance(1);
- } else {
- return make_error<err::buffer_exhausted>();
- }
- return no_error();
-}
-
-error buffer::pop(uint8_t &buffer, size_t size) {
- if (read_composite_length() >= size) {
- uint8_t *buffer_ptr = &buffer;
- while (size > 0) {
- size_t segment = std::min(read_segment_length(), size);
- memcpy(buffer_ptr, &read(), segment);
- read_advance(segment);
- size -= segment;
- buffer_ptr += segment;
- }
- } else {
- return make_error<err::buffer_exhausted>();
- }
- return no_error();
-}
-
-/*
-std::string buffer::to_hex() const {
- std::ostringstream oss;
- oss << std::hex << std::setfill('0');
- for (size_t i = 0; i < read_composite_length(); ++i) {
- oss << std::setw(2) << (uint16_t)read(i);
- if ((i + 1) < read_composite_length()) {
- oss << ((i % 4 == 3) ? '\n' : ' ');
- }
- }
- return oss.str();
-}
-*/
-
-std::string convert_to_string(const buffer& buff){
- std::ostringstream oss;
- for (size_t i = 0; i < buff.read_composite_length(); ++i) {
- oss << buff.read(i);
- }
- return oss.str();
-}
-
-buffer_view::buffer_view(buffer &buffer)
- : buffer_{&buffer}, read_offset_{0}, write_offset_{0} {}
-
-size_t buffer_view::read_position() const {
- return read_offset_ + buffer_->read_position();
-}
-
-size_t buffer_view::read_composite_length() const {
- assert(read_offset_ <= buffer_->read_composite_length());
- if (read_offset_ > buffer_->read_composite_length()) {
- return 0;
- }
-
- return buffer_->read_composite_length() - read_offset_;
-}
-
-size_t buffer_view::read_segment_length(size_t offset) const {
- size_t off = offset + read_offset_;
- assert(off <= buffer_->read_composite_length());
- if (off > buffer_->read_composite_length()) {
- return 0;
- }
-
- return buffer_->read_segment_length(off);
-}
-
-void buffer_view::read_advance(size_t bytes) {
- size_t offset = bytes + read_offset_;
- assert(offset <= buffer_->read_composite_length());
- if (offset > buffer_->read_composite_length()) {
- read_offset_ += buffer_->read_composite_length();
- return;
- }
-
- read_offset_ += bytes;
-}
-
-uint8_t &buffer_view::read(size_t i) {
- size_t pos = i + read_offset_;
-
- assert(pos < buffer_->read_composite_length());
-
- return buffer_->read(pos);
-}
-
-const uint8_t &buffer_view::read(size_t i) const {
- size_t pos = i + read_offset_;
-
- assert(pos < buffer_->read_composite_length());
-
- return buffer_->read(pos);
-}
-
-size_t buffer_view::write_position() const {
- return write_offset_ + buffer_->write_position();
-}
-
-size_t buffer_view::write_composite_length() const {
- assert(write_offset_ <= buffer_->write_composite_length());
- if (write_offset_ > buffer_->write_composite_length()) {
- return 0;
- }
-
- return buffer_->write_composite_length() - write_offset_;
-}
-
-size_t buffer_view::write_segment_length(size_t offset) const {
- size_t off = offset + write_offset_;
- assert(off <= buffer_->write_composite_length());
- if (off > buffer_->write_composite_length()) {
- return 0;
- }
-
- return buffer_->write_segment_length(off);
-}
-
-void buffer_view::write_advance(size_t bytes) {
- size_t offset = bytes + write_offset_;
- assert(offset <= buffer_->write_composite_length());
- if (offset > buffer_->write_composite_length()) {
- write_offset_ += buffer_->write_composite_length();
- return;
- }
-
- write_offset_ += bytes;
-}
-
-uint8_t &buffer_view::write(size_t i) {
- size_t pos = i + write_offset_;
-
- assert(pos < buffer_->write_composite_length());
-
- return buffer_->write(pos);
-}
-
-const uint8_t &buffer_view::write(size_t i) const {
- size_t pos = i + write_offset_;
-
- assert(pos < buffer_->write_composite_length());
-
- return buffer_->write(pos);
-}
-
-error buffer_view::write_require_length(size_t bytes) {
- return buffer_->write_require_length(bytes + write_offset_);
-}
-
-size_t buffer_view::read_offset() const { return read_offset_; }
-
-size_t buffer_view::write_offset() const { return write_offset_; }
-
-ring_buffer::ring_buffer() : read_position_{0}, write_position_{0} {
- buffer_.resize(RING_BUFFER_MAX_SIZE);
-}
-
-ring_buffer::ring_buffer(size_t size) : read_position_{0}, write_position_{0} {
- buffer_.resize(size);
-}
-
-size_t ring_buffer::read_position() const { return read_position_; }
-
-/*
- * If write is ahead of read it is a simple distance, but if read ist ahead of
- * write then there are two segments
- *
- */
-size_t ring_buffer::read_composite_length() const {
- return write_position() < read_position()
- ? buffer_.size() - (read_position() - write_position())
- : (write_reached_read_ ? buffer_.size()
- : write_position() - read_position());
-}
-
-/*
- * If write is ahead then it's the simple distance again. If read is ahead it's
- * until the end of the buffer/segment
- */
-size_t ring_buffer::read_segment_length(size_t offset) const {
- size_t read_composite = read_composite_length();
- assert(offset <= read_composite);
- offset = std::min(offset, read_composite);
- size_t remaining = read_composite - offset;
-
- size_t read_offset = read_position() + offset;
- read_offset = read_offset >= buffer_.size() ? read_offset - buffer_.size()
- : read_offset;
-
- // case 1 write is located before read and reached read
- // then offset can be used normally
- // case 2 write is located at read, but read reached write
- // then it is set to zero by readCompositeLength()
- // case 3 write is located after read
- // since std::min you can use simple subtraction
- if (write_position() < read_offset) {
- return buffer_.size() - read_offset;
- }
-
- if (write_position() == read_offset) {
- if (remaining > 0) {
- return buffer_.size() - read_offset;
- } else {
- return 0;
- }
- }
-
- return write_position() - read_offset;
-}
-
-void ring_buffer::read_advance(size_t bytes) {
- size_t read_composite = read_composite_length();
-
- assert(bytes <= read_composite);
- bytes = std::min(bytes, read_composite);
- size_t advanced = read_position_ + bytes;
- read_position_ = advanced >= buffer_.size() ? advanced - buffer_.size()
- : advanced;
- write_reached_read_ = bytes > 0 ? false : write_reached_read_;
-}
-
-uint8_t &ring_buffer::read(size_t i) {
- assert(i < read_composite_length());
- size_t pos = read_position_ + i;
- pos = pos >= buffer_.size() ? pos - buffer_.size() : pos;
- return buffer_[pos];
-}
-
-const uint8_t &ring_buffer::read(size_t i) const {
- assert(i < read_composite_length());
- size_t pos = read_position_ + i;
- pos = pos >= buffer_.size() ? pos - buffer_.size() : pos;
- return buffer_[pos];
-}
-
-size_t ring_buffer::write_position() const { return write_position_; }
-
-size_t ring_buffer::write_composite_length() const {
- return read_position() > write_position()
- ? (read_position() - write_position())
- : (write_reached_read_
- ? 0
- : buffer_.size() - (write_position() - read_position()));
-}
-
-size_t ring_buffer::write_segment_length(size_t offset) const {
- size_t write_composite = write_composite_length();
- assert(offset <= write_composite);
- offset = std::min(offset, write_composite);
-
- size_t write_offset = write_position() + offset;
- write_offset = write_offset >= buffer_.size()
- ? write_offset - buffer_.size()
- : write_offset;
-
- if (read_position_ > write_offset) {
- return read_position_ - write_offset;
- }
-
- if (write_reached_read_) {
- return 0;
- }
-
- return buffer_.size() - write_offset;
-}
-
-void ring_buffer::write_advance(size_t bytes) {
- assert(bytes <= write_composite_length());
- size_t advanced = write_position_ + bytes;
- write_position_ = advanced >= buffer_.size() ? advanced - buffer_.size()
- : advanced;
-
- write_reached_read_ =
- (write_position_ == read_position_ && bytes > 0 ? true : false);
-}
-
-uint8_t &ring_buffer::write(size_t i) {
- assert(i < write_composite_length());
- size_t pos = write_position_ + i;
- pos = pos >= buffer_.size() ? pos - buffer_.size() : pos;
- return buffer_[pos];
-}
-
-const uint8_t &ring_buffer::write(size_t i) const {
- assert(i < write_composite_length());
- size_t pos = write_position_ + i;
- pos = pos >= buffer_.size() ? pos - buffer_.size() : pos;
- return buffer_[pos];
-}
-/*
- Error RingBuffer::increaseSize(size_t size){
- size_t old_size = buffer.size();
- size_t new_size = old_size + size;
- buffer.resize(new_size);
- if(readPosition() > writePosition() || (readPosition() ==
- writePosition() && write_reached_read)){ size_t remaining = old_size -
- writePosition(); size_t real_remaining = 0; while(remaining > 0){ size_t
- segment = std::min(remaining, size); memcpy(&buffer[new_size-segment],
- &buffer[old_size-segment], segment); remaining -= segment; size -= segment;
- old_size -= segment;
- new_size -= segment;
- }
- }
-
- return noError();
- }
-*/
-error ring_buffer::write_require_length(size_t bytes) {
- size_t write_remain = write_composite_length();
- if (bytes > write_remain) {
- return make_error<err::buffer_exhausted>();
- }
- return no_error();
-}
-
-array_buffer::array_buffer(size_t size)
- : read_position_{0}, write_position_{0} {
- buffer_.resize(size);
-}
-
-size_t array_buffer::read_position() const { return read_position_; }
-
-size_t array_buffer::read_composite_length() const {
- return write_position_ - read_position_;
-}
-
-size_t array_buffer::read_segment_length(size_t offset) const {
- size_t read_composite = read_composite_length();
- assert(offset <= read_composite);
-
- offset = std::min(read_composite, offset);
- size_t read_offset = read_position_ + offset;
-
- return write_position_ - read_offset;
-}
-
-void array_buffer::read_advance(size_t bytes) {
- assert(bytes <= read_composite_length());
- read_position_ += bytes;
-}
-
-uint8_t &array_buffer::read(size_t i) {
- assert(i < read_composite_length());
-
- return buffer_[i + read_position_];
-}
-
-const uint8_t &array_buffer::read(size_t i) const {
- assert(i + read_position_ < buffer_.size());
-
- return buffer_[i + read_position_];
-}
-
-size_t array_buffer::write_position() const { return write_position_; }
-
-size_t array_buffer::write_composite_length() const {
- assert(write_position_ <= buffer_.size());
- return buffer_.size() - write_position_;
-}
-
-size_t array_buffer::write_segment_length(size_t offset) const {
- assert(write_position_ <= buffer_.size());
- size_t write_composite = write_composite_length();
-
- assert(offset <= write_composite);
- offset = std::min(write_composite, offset);
- size_t write_offset = write_position_ + offset;
-
- return buffer_.size() - write_offset;
-}
-
-void array_buffer::write_advance(size_t bytes) {
- assert(bytes <= write_composite_length());
- write_position_ += bytes;
-}
-
-uint8_t &array_buffer::write(size_t i) {
- assert(i < write_composite_length());
- return buffer_[i + write_position_];
-}
-
-const uint8_t &array_buffer::write(size_t i) const {
- assert(i < write_composite_length());
- return buffer_[i + write_position_];
-}
-error array_buffer::write_require_length(size_t bytes) {
- size_t write_remain = write_composite_length();
- if (bytes > write_remain) {
- return make_error<err::buffer_exhausted>();
- }
- return no_error();
-}
-
-} // namespace saw
diff --git a/src/core/buffer.h b/src/core/buffer.h
deleted file mode 100644
index f0cf76e..0000000
--- a/src/core/buffer.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#pragma once
-
-#include "error.h"
-
-#include <array>
-#include <cstdint>
-#include <deque>
-#include <list>
-#include <string>
-#include <vector>
-
-namespace saw {
-/*
- * Access class to reduce templated BufferSegments bloat
- */
-class buffer {
-protected:
- ~buffer() = default;
-
-public:
- virtual size_t read_position() const = 0;
- virtual size_t read_composite_length() const = 0;
- virtual size_t read_segment_length(size_t offset = 0) const = 0;
- virtual void read_advance(size_t bytes) = 0;
-
- virtual uint8_t &read(size_t i = 0) = 0;
- virtual const uint8_t &read(size_t i = 0) const = 0;
-
- virtual size_t write_position() const = 0;
- virtual size_t write_composite_length() const = 0;
- virtual size_t write_segment_length(size_t offset = 0) const = 0;
- virtual void write_advance(size_t bytes) = 0;
-
- virtual uint8_t &write(size_t i = 0) = 0;
- virtual const uint8_t &write(size_t i = 0) const = 0;
-
- /*
- * Sometime buffers need to grow with a little more control
- * than with push and pop for more efficient calls.
- * There is nothing you can do if read hasn't been filled, but at
- * least write can be increased if it is demanded.
- */
- virtual error write_require_length(size_t bytes) = 0;
-
- error push(const uint8_t &value);
- error push(const uint8_t &buffer, size_t size);
- error pop(uint8_t &value);
- error pop(uint8_t &buffer, size_t size);
-
-};
-
-/**
- * Converts a buffer to a string for convenience cases
- */
-std::string convert_to_string(const buffer& buf);
-
-/**
- *
- */
-
-/*
- * A viewer class for buffers.
- * Working on the reference buffer invalidates the buffer view
- */
-class buffer_view : public buffer {
-private:
- buffer *buffer_;
- size_t read_offset_;
- size_t write_offset_;
-
-public:
- buffer_view(buffer &);
-
- size_t read_position() const override;
- size_t read_composite_length() const override;
- size_t read_segment_length(size_t offset = 0) const override;
- void read_advance(size_t bytes) override;
-
- uint8_t &read(size_t i = 0) override;
- const uint8_t &read(size_t i = 0) const override;
-
- size_t write_position() const override;
- size_t write_composite_length() const override;
- size_t write_segment_length(size_t offset = 0) const override;
- void write_advance(size_t bytes) override;
-
- uint8_t &write(size_t i = 0) override;
- const uint8_t &write(size_t i = 0) const override;
-
- error write_require_length(size_t bytes) override;
-
- size_t read_offset() const;
- size_t write_offset() const;
-};
-
-/*
- * Buffer size meant for default allocation size of the ringbuffer since
- * this class currently doesn't support proper resizing
- */
-constexpr size_t RING_BUFFER_MAX_SIZE = 4096;
-/*
- * Buffer wrapping around if read caught up
- */
-class ring_buffer final : public buffer {
-private:
- std::vector<uint8_t> buffer_;
- size_t read_position_;
- size_t write_position_;
- bool write_reached_read_ = false;
-
-public:
- ring_buffer();
- ring_buffer(size_t size);
-
- inline size_t size() const { return buffer_.size(); }
-
- inline uint8_t &operator[](size_t i) { return buffer_[i]; }
- inline const uint8_t &operator[](size_t i) const { return buffer_[i]; }
-
- size_t read_position() const override;
- size_t read_composite_length() const override;
- size_t read_segment_length(size_t offset = 0) const override;
- void read_advance(size_t bytes) override;
-
- uint8_t &read(size_t i = 0) override;
- const uint8_t &read(size_t i = 0) const override;
-
- size_t write_position() const override;
- size_t write_composite_length() const override;
- size_t write_segment_length(size_t offset = 0) const override;
- void write_advance(size_t bytes) override;
-
- uint8_t &write(size_t i = 0) override;
- const uint8_t &write(size_t i = 0) const override;
-
- error write_require_length(size_t bytes) override;
-};
-
-/*
- * One time buffer
- */
-class array_buffer : public buffer {
-private:
- std::vector<uint8_t> buffer_;
-
- size_t read_position_;
- size_t write_position_;
-
-public:
- array_buffer(size_t size);
-
- size_t read_position() const override;
- size_t read_composite_length() const override;
- size_t read_segment_length(size_t offset = 0) const override;
- void read_advance(size_t bytes) override;
-
- uint8_t &read(size_t i = 0) override;
- const uint8_t &read(size_t i = 0) const override;
-
- size_t write_position() const override;
- size_t write_composite_length() const override;
- size_t write_segment_length(size_t offset = 0) const override;
- void write_advance(size_t bytes) override;
-
- uint8_t &write(size_t i = 0) override;
- const uint8_t &write(size_t i = 0) const override;
-
- error write_require_length(size_t bytes) override;
-};
-
-class chain_array_buffer : public buffer {
-private:
- std::deque<array_buffer> buffer_;
-
- size_t read_position_;
- size_t write_position_;
-
-public:
- chain_array_buffer();
-
- size_t read_position() const override;
- size_t read_composite_length() const override;
- size_t read_segment_length(size_t offset = 0) const override;
- void read_advance(size_t bytes) override;
-
- uint8_t &read(size_t i = 0) override;
- const uint8_t &read(size_t i = 0) const override;
-
- size_t write_position() const override;
- size_t write_composite_length() const override;
- size_t write_segment_length(size_t offset = 0) const override;
- void write_advance(size_t bytes) override;
-
- uint8_t &write(size_t i = 0) override;
- const uint8_t &write(size_t i = 0) const override;
-
- error write_require_length(size_t bytes) override;
-};
-} // namespace saw
diff --git a/src/core/common.h b/src/core/common.h
deleted file mode 100644
index a06c238..0000000
--- a/src/core/common.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <optional>
-#include <utility>
-
-namespace saw {
-
-#define SAW_CONCAT_(x, y) x##y
-#define SAW_CONCAT(x, y) SAW_CONCAT_(x, y)
-#define SAW_UNIQUE_NAME(prefix) SAW_CONCAT(prefix, __LINE__)
-
-#define SAW_FORBID_COPY(classname) \
- classname(const classname &) = delete; \
- classname &operator=(const classname &) = delete
-
-#define SAW_FORBID_MOVE(classname) \
- classname(classname &&) = delete; \
- classname &operator=(classname &&) = delete
-
-#define SAW_DEFAULT_COPY(classname) \
- classname(const classname &) = default; \
- classname &operator=(const classname &) = default
-
-#define SAW_DEFAULT_MOVE(classname) \
- classname(classname &&) = default; \
- classname &operator=(classname &&) = default
-
-// In case of C++20
-#define SAW_ASSERT(expression) \
- assert(expression); \
- if (!(expression)) [[unlikely]]
-
-template <typename T> using maybe = std::optional<T>;
-
-template <typename T> using own = std::unique_ptr<T>;
-
-template <typename T> using our = std::shared_ptr<T>;
-
-template <typename T> using lent = std::weak_ptr<T>;
-
-template <typename T, class... Args> own<T> heap(Args &&...args) {
- return own<T>(new T(std::forward<Args>(args)...));
-}
-
-template <typename T, class... Args> our<T> share(Args &&...args) {
- return std::make_shared<T>(std::forward<Args>(args)...);
-}
-
-template <typename T> T instance() noexcept;
-
-template <typename Func, typename T> struct return_type_helper {
- typedef decltype(instance<Func>()(instance<T>())) Type;
-};
-template <typename Func> struct return_type_helper<Func, void> {
- typedef decltype(instance<Func>()()) Type;
-};
-
-template <typename Func, typename T>
-using return_type = typename return_type_helper<Func, T>::Type;
-
-struct void_t {};
-
-template <typename T> struct void_fix { typedef T Type; };
-template <> struct void_fix<void> { typedef void_t Type; };
-template <typename T> using fix_void = typename void_fix<T>::Type;
-
-template <typename T> struct void_unfix { typedef T Type; };
-template <> struct void_unfix<void_t> { typedef void Type; };
-template <typename T> using unfix_void = typename void_unfix<T>::Type;
-
-template <typename... T> constexpr bool always_false = false;
-
-} // namespace saw
diff --git a/src/core/error.cpp b/src/core/error.cpp
deleted file mode 100644
index 360e628..0000000
--- a/src/core/error.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "error.h"
-
-namespace saw {
-error::error(error::code code_, bool is_critical__)
- : error_code_{static_cast<error::code>(code_)}, is_critical_{is_critical__} {}
-
-error::error(error::code code_, bool is_critical__, const std::string_view &msg)
- :
- error_code_{static_cast<error::code>(code_)}
- , is_critical_{is_critical__}, error_message_{msg}{}
-
-error::error(error &&error)
- :
- error_code_{std::move(error.error_code_)}
- , is_critical_{std::move(error.is_critical_)}
- , error_message_{std::move(error.error_message_)}{}
-
-const std::string_view error::get_category() const {
- auto& reg = impl::get_error_registry();
-
- auto eov = reg.search_category(error_code_);
- SAW_ASSERT(eov.is_value()){
- return "Error category not found. Report this error to the forstio maintainer";
- }
-
- return eov.get_value();
-}
-
-const std::string_view error::get_message() const {
- return std::visit(
- [this](auto &&arg) -> const std::string_view {
- using T = std::decay_t<decltype(arg)>;
-
- if constexpr (std::is_same_v<T, std::string>) {
- return std::string_view{arg};
- } else if constexpr (std::is_same_v<T, std::string_view>) {
- return arg;
- } else {
- return "Error in class Error. Good luck :)";
- }
- },
- error_message_);
-}
-
-bool error::failed() const {
- return !this->is_type<err::no_error>();
-}
-
-bool error::is_critical() const {
- return is_critical_;
-}
-
-bool error::is_recoverable() const {
- return !is_critical_;
-}
-
-error error::copy_error() const {
- auto copy_error_code = error_code_;
- error error{copy_error_code, is_critical_};
-
- try {
- error.error_message_ = error_message_;
- } catch (const std::bad_alloc &) {
- error.error_message_ =
- std::string_view{"Error while copying Error string. Out of memory"};
- }
-
- return error;
-}
-
-error::code error::get_id() const { return error_code_; }
-
-namespace impl {
-error_registry& get_error_registry() {
- static own<error_registry> reg = nullptr;
- if(!reg){
- reg = heap<error_registry>();
- }
-
- assert(reg);
- return *reg;
-}
-}
-
-error no_error(){
- return make_error<err::no_error>();
-}
-
-namespace impl {
-error_registry::error_registry():
- infos_{
- {
- err::no_error::description,
- err::no_error::is_critical
- },
- {
- err::not_found::description,
- err::not_found::is_critical
- },
- {
- err::out_of_memory::description,
- err::out_of_memory::is_critical
- }
- }
-{}
-
-error_or<const std::string_view> error_registry::search_category(const error::code& id) const {
- if( id >= infos_.size()){
- return make_error<err::not_found>();
- }
-
- return infos_.at(id).description;
-}
-
-error_or<error::code> error_registry::search_id(const std::string_view& desc)const{
- /**
- * Search the index in the vector
- */
- size_t i{};
- size_t info_max_size = std::min<std::size_t>(infos_.size(), std::numeric_limits<error::code>::max());
- for(i = 0; i < info_max_size; ++i){
- if(infos_.at(i).description == desc){
- break;
- }
- }
-
- if(i == info_max_size){
- return make_error<err::not_found>();
- }
-
- return static_cast<error::code>(i);
-}
-
-error_or<error::code> error_registry::search_or_register_id(const std::string_view& desc, bool is_critical){
- auto err_or_id = search_id(desc);
-
- if(err_or_id.is_value()){
- return err_or_id.get_value();
- }
-
- auto& err = err_or_id.get_error();
-
- if(err.is_type<err::not_found>()){
- size_t new_index = infos_.size();
- if(new_index == std::numeric_limits<error::code>::max()){
- return make_error<err::out_of_memory>("Error registry ids are exhausted");
- }
- infos_.emplace_back(error_info{desc, is_critical});
- return static_cast<error::code>(new_index);
- }
-
- return std::move(err);
-}
-}
-
-} // namespace saw
diff --git a/src/core/error.h b/src/core/error.h
deleted file mode 100644
index e816734..0000000
--- a/src/core/error.h
+++ /dev/null
@@ -1,248 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <limits>
-#include <string>
-#include <string_view>
-#include <variant>
-#include <vector>
-
-#include <cassert>
-
-#include "common.h"
-
-namespace saw {
-/**
- * Utility class for generating errors. Has a base distinction between
- * critical and recoverable errors. Additional code ids can be provided to the
- * constructor if additional distinctions are necessary.
- */
-class error {
-public:
- using code = uint32_t;
-private:
- code error_code_;
- bool is_critical_;
- std::variant<std::string_view, std::string> error_message_;
-
-public:
- error(error::code id, bool is_critical);
- error(error::code id, bool is_critical, const std::string_view &msg);
- error(error &&error);
-
- SAW_FORBID_COPY(error);
-
- error &operator=(error &&) = default;
-
- const std::string_view get_message() const;
-
- const std::string_view get_category() const;
-
- bool failed() const;
-
- bool is_critical() const;
- bool is_recoverable() const;
-
- /**
- * Replaces the copy constructor. We need this since we want to explicitly copy and not implicitly
- */
- error copy_error() const;
-
- code get_id() const;
-
- template<typename T>
- bool is_type() const;
-};
-
-template<typename T>
-class error_or;
-
-namespace impl {
-
-class error_registry {
-private:
- struct error_info {
- error_info() = delete;
- error_info(const std::string_view& d_, bool critical_):description{d_}, is_critical{critical_}{}
-
- std::string_view description;
- bool is_critical;
- };
-
- std::vector<error_info> infos_;
-public:
- error_registry();
-
- SAW_FORBID_COPY(error_registry);
- SAW_FORBID_MOVE(error_registry);
-
- error_or<const std::string_view> search_category(const error::code& id) const;
-
- error_or<error::code> search_id(const std::string_view& desc) const;
-
- error_or<error::code> search_or_register_id(const std::string_view& desc, bool is_critical);
-};
-
-error_registry& get_error_registry();
-
-template<typename T>
-error::code get_template_id(){
- static error::code id = std::numeric_limits<error::code>::max();
-
- if(id == std::numeric_limits<error::code>::max()){
- auto& reg = get_error_registry();
-
- auto err_or_id = reg.search_or_register_id(T::description, T::is_critical);
- if(err_or_id.is_error()){
- return std::numeric_limits<error::code>::max();
- }
-
- id = err_or_id.get_value();
- }
-
- return id;
-}
-}
-
-template<typename T> error make_error(const std::string_view& generic){
- error::code id = impl::get_template_id<T>();
-
- return error{id, T::is_critical, generic};
-}
-
-template<typename T> error make_error(){
- error::code id = impl::get_template_id<T>();
-
- return error{id, T::is_critical};
-}
-
-error make_error(error::code code, const std::string_view &generic);
-
-
-namespace err {
-struct no_error {
- static constexpr std::string_view description = "No error has occured";
- static constexpr bool is_critical = false;
-};
-
-struct recoverable {
- static constexpr std::string_view description = "Generic recoverable error";
- static constexpr bool is_critical = false;
-};
-
-struct critical {
- static constexpr std::string_view description = "Generic critical error";
- static constexpr bool is_critical = true;
-};
-
-struct buffer_exhausted {
- static constexpr std::string_view description = "Buffer Exhausted";
- static constexpr bool is_critical = false;
-};
-
-struct not_found {
- static constexpr std::string_view description = "Not found";
- static constexpr bool is_critical = false;
-};
-
-struct out_of_memory {
- static constexpr std::string_view description = "Out of memory";
- static constexpr bool is_critical = true;
-};
-
-struct invalid_state {
- static constexpr std::string_view description = "Invalid state";
- static constexpr bool is_critical = true;
-};
-
-struct not_supported {
- static constexpr std::string_view description = "Not supported";
- static constexpr bool is_critical = false;
-};
-
-struct not_implemented {
- static constexpr std::string_view description = "Not implemented";
- static constexpr bool is_critical = true;
-};
-
-struct already_exists {
- static constexpr std::string_view description = "Already exists";
- static constexpr bool is_critical = false;
-};
-}
-
-/**
- * Shorthand for no error happened
- */
-error no_error();
-
-/**
- * Exception alternative. Since I code without exceptions this class is
- * essentially a kind of exception replacement.
- */
-template <typename T> class error_or;
-
-class error_or_value {
-public:
- virtual ~error_or_value() = default;
-
- template <typename T> error_or<unfix_void<T>> &as() {
- return static_cast<error_or<unfix_void<T>> &>(*this);
- }
-
- template <typename T> const error_or<unfix_void<T>> &as() const {
- return static_cast<const error_or<unfix_void<T>> &>(*this);
- }
-};
-
-template <typename T> class error_or final : public error_or_value {
-private:
- std::variant<error, fix_void<T>> value_or_error_;
-
- static_assert(!std::is_same_v<T, void_t>,
- "Don't use internal private types");
-
-public:
- error_or():value_or_error_{fix_void<T>{}}{}
- error_or(const fix_void<T> &value) : value_or_error_{value} {}
-
- error_or(fix_void<T> &&value) : value_or_error_{std::move(value)} {}
-
- error_or(const error &error) : value_or_error_{error} {}
- error_or(error &&error) : value_or_error_{std::move(error)} {}
-
- bool is_value() const {
- return std::holds_alternative<fix_void<T>>(value_or_error_);
- }
-
- bool is_error() const {
- return std::holds_alternative<class error>(value_or_error_);
- }
-
- class error &get_error() {
- return std::get<class error>(value_or_error_);
- }
-
- const class error &get_error() const {
- return std::get<class error>(value_or_error_);
- }
-
- fix_void<T> &get_value() { return std::get<fix_void<T>>(value_or_error_); }
-
- const fix_void<T> &get_value() const {
- return std::get<fix_void<T>>(value_or_error_);
- }
-};
-
-template <typename T> class error_or<error_or<T>> {
-private:
- error_or() = delete;
-};
-
-template<typename T>
-bool error::is_type() const {
-
- return error_code_ == impl::get_template_id<T>();
-}
-
-} // namespace saw
diff --git a/src/core/string_literal.h b/src/core/string_literal.h
deleted file mode 100644
index d530a54..0000000
--- a/src/core/string_literal.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <array>
-#include <string_view>
-
-namespace saw {
-/**
- * Helper object which creates a templated string from the provided string
- * literal. It guarantees compile time uniqueness and thus allows using strings
- * in template parameters.
- */
-template <class CharT, size_t N> class string_literal {
-public:
- constexpr string_literal(const CharT (&input)[N]) noexcept {
- for (size_t i = 0; i < N; ++i) {
- data[i] = input[i];
- }
- }
-
- std::array<CharT, N> data{};
-
- constexpr std::string_view view() const noexcept {
- return std::string_view{data.data()};
- }
-
- constexpr bool
- operator==(const string_literal<CharT, N> &) const noexcept = default;
-
- template <class CharTR, size_t NR>
- constexpr bool
- operator==(const string_literal<CharTR, NR> &) const noexcept {
- return false;
- }
-};
-
-template <typename T, T... Chars>
-constexpr string_literal<T, sizeof...(Chars)> operator""_key() {
- return string_literal<T, sizeof...(Chars) + 1u>{Chars..., '\0'};
-}
-} // namespace saw
diff --git a/src/core/templates.h b/src/core/templates.h
deleted file mode 100644
index 39befc1..0000000
--- a/src/core/templates.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#pragma once
-
-#include "string_literal.h"
-
-namespace saw {
-
-template <class T, class... TL> struct parameter_pack_index;
-
-template <class T, class... TL> struct parameter_pack_index<T, T, TL...> {
- static constexpr size_t value = 0u;
-};
-
-template <class T, class TL0, class... TL>
-struct parameter_pack_index<T, TL0, TL...> {
- static constexpr size_t value =
- 1u + parameter_pack_index<T, TL...>::value;
-};
-
-template <size_t N, class... T> struct parameter_pack_type {
- static_assert(always_false<T...>, "Should've been caught by the specializations");
-};
-
-template <class TN, class... T> struct parameter_pack_type<0, TN, T...> {
- using type = TN;
-};
-
-template <size_t N, class TN, class... T>
-struct parameter_pack_type<N, TN, T...> {
- static_assert(sizeof...(T) > 0, "Exhausted parameters");
- static_assert(N > 0, "Invalid number. Should've been caught");
- using type = typename parameter_pack_type<N - 1, T...>::type;
-};
-/*
- * Nightmare inducing compiler problems found here. Somehow non-type
- * string_literals cannot be resolved as non-type primitive template values can.
- * This is the workaround
- */
-template <string_literal V, string_literal Key0, string_literal... Keys>
-struct parameter_key_pack_index_helper {
- static constexpr size_t value =
- (V == Key0)
- ? (0u)
- : (1u + parameter_key_pack_index_helper<V, Keys...>::value);
-};
-
-template <string_literal V, string_literal Key0>
-struct parameter_key_pack_index_helper<V, Key0> {
- static constexpr size_t value = (V == Key0) ? (0u) : (1u);
-};
-
-template <string_literal V, string_literal... Keys>
-struct parameter_key_pack_index {
- static constexpr size_t value =
- parameter_key_pack_index_helper<V, Keys...>::value;
- static_assert(value < sizeof...(Keys),
- "Provided string_literal doesn't exist in searched list");
-};
-
-template <size_t i, size_t s, string_literal Key0, string_literal... Keys>
-struct parameter_key_pack_type_helper {
- static constexpr string_literal literal = parameter_key_pack_type_helper<i, s+1, Keys...>::literal;
-};
-
-template <size_t i, string_literal Key0, string_literal... Keys>
-struct parameter_key_pack_type_helper<i, i, Key0, Keys...> {
- static constexpr string_literal literal = Key0;
-};
-
-template <size_t i, string_literal... Keys>
-struct parameter_key_pack_type {
- static constexpr string_literal literal = parameter_key_pack_type_helper<i, 0, Keys...>::literal;
-
- static_assert(i < sizeof...(Keys), "Provided index is too large in list");
-};
-
-}
diff --git a/src/io-tls/.nix/derivation.nix b/src/io-tls/.nix/derivation.nix
deleted file mode 100644
index a08b195..0000000
--- a/src/io-tls/.nix/derivation.nix
+++ /dev/null
@@ -1,34 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-, gnutls
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-io-tls";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- forstio.async
- forstio.io
- gnutls
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/io-tls/SConscript b/src/io-tls/SConscript
deleted file mode 100644
index 4f88f37..0000000
--- a/src/io-tls/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-io_tls_env = env.Clone();
-
-io_tls_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-io_tls_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += io_tls_env.sources;
-env.headers += io_tls_env.headers;
-
-## Shared lib
-objects_shared = []
-io_tls_env.add_source_files(objects_shared, io_tls_env.sources, shared=True);
-io_tls_env.library_shared = io_tls_env.SharedLibrary('#build/forstio-io-tls', [objects_shared]);
-
-## Static lib
-objects_static = []
-io_tls_env.add_source_files(objects_static, io_tls_env.sources, shared=False);
-io_tls_env.library_static = io_tls_env.StaticLibrary('#build/forstio-io-tls', [objects_static]);
-
-# Set Alias
-env.Alias('library_io_tls', [io_tls_env.library_shared, io_tls_env.library_static]);
-
-env.targets += ['library_io_tls'];
-
-# Install
-env.Install('$prefix/lib/', [io_tls_env.library_shared, io_tls_env.library_static]);
-env.Install('$prefix/include/forstio/io/tls/', [io_tls_env.headers]);
diff --git a/src/io-tls/SConstruct b/src/io-tls/SConstruct
deleted file mode 100644
index fbd8657..0000000
--- a/src/io-tls/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['gnutls','forstio-io'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/io-tls/tls.cpp b/src/io-tls/tls.cpp
deleted file mode 100644
index 9fa143c..0000000
--- a/src/io-tls/tls.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-#include "tls.h"
-
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-
-#include <forstio/io/io_helpers.h>
-
-#include <cassert>
-
-#include <iostream>
-
-namespace saw {
-
-class tls::impl {
-public:
- gnutls_certificate_credentials_t xcred;
-
-public:
- impl() {
- gnutls_global_init();
- gnutls_certificate_allocate_credentials(&xcred);
- gnutls_certificate_set_x509_system_trust(xcred);
- }
-
- ~impl() {
- gnutls_certificate_free_credentials(xcred);
- gnutls_global_deinit();
- }
-};
-
-static ssize_t forst_tls_push_func(gnutls_transport_ptr_t p, const void *data,
- size_t size);
-static ssize_t forst_tls_pull_func(gnutls_transport_ptr_t p, void *data, size_t size);
-
-tls::tls() : impl_{heap<tls::impl>()} {}
-
-tls::~tls() {}
-
-tls::impl &tls::get_impl() { return *impl_; }
-
-class tls_io_stream final : public io_stream {
-private:
- own<io_stream> internal;
- gnutls_session_t session_handle;
-
-public:
- tls_io_stream(own<io_stream> internal_) : internal{std::move(internal_)} {}
-
- ~tls_io_stream() { gnutls_bye(session_handle, GNUTLS_SHUT_RDWR); }
-
- error_or<size_t> read(void *buffer, size_t length) override {
- ssize_t size = gnutls_record_recv(session_handle, buffer, length);
- if (size < 0) {
- if(gnutls_error_is_fatal(size) == 0){
- return make_error<err::recoverable>("Recoverable error on read in gnutls. TODO better error msg handling");
- // Leaving proper message handling done in previous error framework
- //return recoverable_error([size](){return std::string{"Read recoverable Error "}+std::string{gnutls_strerror(size)};}, "Error read r");
- }else{
- return make_error<err::critical>("Fatal error on read in gnutls. TODO better error msg handling");
- }
- }else if(size == 0){
- return make_error<err::disconnected>();
- }
-
- return static_cast<size_t>(length);
- }
-
- conveyor<void> read_ready() override { return internal->read_ready(); }
-
- conveyor<void> on_read_disconnected() override {
- return internal->on_read_disconnected();
- }
-
- error_or<size_t> write(const void *buffer, size_t length) override {
- ssize_t size = gnutls_record_send(session_handle, buffer, length);
- if(size < 0){
- if(gnutls_error_is_fatal(size) == 0){
- return make_error<err::recoverable>("Recoverable error on write in gnutls. TODO better error msg handling");
- }else{
- return make_error<err::critical>("Fatal error on write in gnutls. TODO better error msg handling");
- }
- }
-
- return static_cast<size_t>(size);
- }
-
- conveyor<void> write_ready() override { return internal->write_ready(); }
-
- gnutls_session_t &session() { return session_handle; }
-};
-
-tls_server::tls_server(own<server> srv) : internal{std::move(srv)} {}
-
-conveyor<own<io_stream>> tls_server::accept() {
- SAW_ASSERT(internal) { return conveyor<own<io_stream>>{fix_void<own<io_stream>>{nullptr}}; }
- return internal->accept().then([](own<io_stream> stream) -> own<io_stream> {
- /// @todo handshake
-
-
- return heap<tls_io_stream>(std::move(stream));
- });
-}
-
-namespace {
-/*
-* Small helper for setting up the nonblocking connection handshake
-*/
-struct tls_client_stream_helper {
-public:
- own<conveyor_feeder<own<io_stream>>> feeder;
- conveyor_sink connection_sink;
- conveyor_sink stream_reader;
- conveyor_sink stream_writer;
-
- own<tls_io_stream> stream = nullptr;
-public:
- tls_client_stream_helper(own<conveyor_feeder<own<io_stream>>> f):
- feeder{std::move(f)}
- {}
-
- void setupTurn(){
- SAW_ASSERT(stream){
- return;
- }
-
- stream_reader = stream->read_ready().then([this](){
- turn();
- }).sink();
-
- stream_writer = stream->write_ready().then([this](){
- turn();
- }).sink();
- }
-
- void turn(){
- if(stream){
- // Guarantee that the receiving end is already setup
- SAW_ASSERT(feeder){
- return;
- }
-
- auto &session = stream->session();
-
- int ret;
- do {
- ret = gnutls_handshake(session);
- } while ( (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) && gnutls_error_is_fatal(ret) == 0);
-
- if(gnutls_error_is_fatal(ret)){
- feeder->fail(make_error<err::critical>("Couldn't create Tls connection"));
- stream = nullptr;
- }else if(ret == GNUTLS_E_SUCCESS){
- feeder->feed(std::move(stream));
- }
- }
- }
-};
-}
-
-own<server> tls_network::listen(network_address& address) {
- return heap<tls_server>(internal.listen(address));
-}
-
-conveyor<own<io_stream>> tls_network::connect(network_address& address) {
- // Helper setups
- auto caf = new_conveyor_and_feeder<own<io_stream>>();
- own<tls_client_stream_helper> helper = heap<tls_client_stream_helper>(std::move(caf.feeder));
- tls_client_stream_helper* hlp_ptr = helper.get();
-
- // Conveyor entangled structure
- auto prim_conv = internal.connect(address).then([this, hlp_ptr, addr = address.address()](
- own<io_stream> stream) -> error_or<void> {
- io_stream* inner_stream = stream.get();
- auto tls_stream = heap<tls_io_stream>(std::move(stream));
-
- auto &session = tls_stream->session();
-
- gnutls_init(&session, GNUTLS_CLIENT);
-
- gnutls_server_name_set(session, GNUTLS_NAME_DNS, addr.c_str(),
- addr.size());
-
- gnutls_set_default_priority(session);
- gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
- tls_.get_impl().xcred);
- gnutls_session_set_verify_cert(session, addr.c_str(), 0);
-
- gnutls_transport_set_ptr(session, reinterpret_cast<gnutls_transport_ptr_t>(inner_stream));
- gnutls_transport_set_push_function(session, forst_tls_push_func);
- gnutls_transport_set_pull_function(session, forst_tls_pull_func);
-
- // gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
-
- hlp_ptr->stream = std::move(tls_stream);
- hlp_ptr->setupTurn();
- hlp_ptr->turn();
-
- return void_t{};
- });
-
- helper->connection_sink = prim_conv.sink();
-
- return caf.conveyor.attach(std::move(helper));
-}
-
-own<datagram> tls_network::datagram(network_address& address){
- ///@unimplemented
- return nullptr;
-}
-
-static ssize_t forst_tls_push_func(gnutls_transport_ptr_t p, const void *data,
- size_t size) {
- io_stream *stream = reinterpret_cast<io_stream *>(p);
- if (!stream) {
- return -1;
- }
-
- error_or<size_t> length = stream->write(data, size);
- if (length.is_error() || !length.is_value()) {
- return -1;
- }
-
- return static_cast<ssize_t>(length.get_value());
-}
-
-static ssize_t forst_tls_pull_func(gnutls_transport_ptr_t p, void *data, size_t size) {
- io_stream *stream = reinterpret_cast<io_stream *>(p);
- if (!stream) {
- return -1;
- }
-
- error_or<size_t> length = stream->read(data, size);
- if (length.is_error() || !length.is_value()) {
- return -1;
- }
-
- return static_cast<ssize_t>(length.get_value());
-}
-
-tls_network::tls_network(tls& tls_, network &network) : tls_{tls_},internal{network} {}
-
-conveyor<own<network_address>> tls_network::resolve_address(const std::string &addr,
- uint16_t port) {
- /// @todo tls server name needed. Check validity. Won't matter later on, because gnutls should fail anyway. But
- /// it's better to find the error source sooner rather than later
- return internal.resolve_address(addr, port);
-}
-
-std::optional<own<tls_network>> setup_tls_network(network &network) {
- return std::nullopt;
-}
-} // namespace saw
diff --git a/src/io-tls/tls.h b/src/io-tls/tls.h
deleted file mode 100644
index 74b39ff..0000000
--- a/src/io-tls/tls.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#pragma once
-
-#include <forstio/core/common.h>
-#include <forstio/io/io.h>
-
-#include <optional>
-#include <variant>
-
-namespace saw {
-class tls;
-
-class tls_server final : public server {
-private:
- own<server> internal;
-
-public:
- tls_server(own<server> srv);
-
- conveyor<own<io_stream>> accept() override;
-};
-
-class tls_network final : public network {
-private:
- tls& tls_;
- network &internal;
-public:
- tls_network(tls& tls_, network &network_);
-
- conveyor<own<network_address>> resolve_address(const std::string &addr, uint16_t port = 0) override;
-
- own<server> listen(network_address& address) override;
-
- conveyor<own<io_stream>> connect(network_address& address) override;
-
- own<class datagram> datagram(network_address& address) override;
-};
-
-/**
-* tls context class.
-* Provides tls network class which ensures the usage of tls encrypted connections
-*/
-class tls {
-private:
- class impl;
- own<impl> impl_;
-public:
- tls();
- ~tls();
-
- struct version {
- struct tls_1_0{};
- struct tls_1_1{};
- struct tls_1_2{};
- };
-
- struct options {
- public:
- version version;
- };
-
- impl &get_impl();
-private:
- options options_;
-};
-
-std::optional<own<tls_network>> setup_tls_network(network &network);
-
-} // namespace saw
diff --git a/src/io/.nix/derivation.nix b/src/io/.nix/derivation.nix
deleted file mode 100644
index 39d7568..0000000
--- a/src/io/.nix/derivation.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-io";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- forstio.async
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/io/SConscript b/src/io/SConscript
deleted file mode 100644
index 62ad58a..0000000
--- a/src/io/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-io_env = env.Clone();
-
-io_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-io_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += io_env.sources;
-env.headers += io_env.headers;
-
-## Shared lib
-objects_shared = []
-io_env.add_source_files(objects_shared, io_env.sources, shared=True);
-io_env.library_shared = io_env.SharedLibrary('#build/forstio-io', [objects_shared]);
-
-## Static lib
-objects_static = []
-io_env.add_source_files(objects_static, io_env.sources, shared=False);
-io_env.library_static = io_env.StaticLibrary('#build/forstio-io', [objects_static]);
-
-# Set Alias
-env.Alias('library_io', [io_env.library_shared, io_env.library_static]);
-
-env.targets += ['library_io'];
-
-# Install
-env.Install('$prefix/lib/', [io_env.library_shared, io_env.library_static]);
-env.Install('$prefix/include/forstio/io/', [io_env.headers]);
diff --git a/src/io/SConstruct b/src/io/SConstruct
deleted file mode 100644
index 4cccf82..0000000
--- a/src/io/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-async'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/io/io.cpp b/src/io/io.cpp
deleted file mode 100644
index f0705d2..0000000
--- a/src/io/io.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "io.h"
-
-#include <cassert>
-
-namespace saw {
-
-async_io_stream::async_io_stream(own<io_stream> str)
- : stream_{std::move(str)},
- read_ready_{stream_->read_ready()
- .then([this]() { read_stepper_.read_step(*stream_); })
- .sink()},
- write_ready_{stream_->write_ready()
- .then([this]() { write_stepper_.write_step(*stream_); })
- .sink()},
- read_disconnected_{stream_->on_read_disconnected()
- .then([this]() {
- if (read_stepper_.on_read_disconnect) {
- read_stepper_.on_read_disconnect->feed();
- }
- })
- .sink()} {}
-
-void async_io_stream::read(void *buffer, size_t min_length, size_t max_length) {
- SAW_ASSERT(buffer && max_length >= min_length && min_length > 0) { return; }
-
- SAW_ASSERT(!read_stepper_.read_task.has_value()) { return; }
-
- read_stepper_.read_task = read_task_and_step_helper::read_io_task{
- buffer, min_length, max_length, 0};
- read_stepper_.read_step(*stream_);
-}
-
-conveyor<size_t> async_io_stream::read_done() {
- auto caf = new_conveyor_and_feeder<size_t>();
- read_stepper_.read_done = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-conveyor<void> async_io_stream::on_read_disconnected() {
- auto caf = new_conveyor_and_feeder<void>();
- read_stepper_.on_read_disconnect = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-void async_io_stream::write(const void *buffer, size_t length) {
- SAW_ASSERT(buffer && length > 0) { return; }
-
- SAW_ASSERT(!write_stepper_.write_task.has_value()) { return; }
-
- write_stepper_.write_task =
- write_task_and_step_helper::write_io_task{buffer, length, 0};
- write_stepper_.write_step(*stream_);
-}
-
-conveyor<size_t> async_io_stream::write_done() {
- auto caf = new_conveyor_and_feeder<size_t>();
- write_stepper_.write_done = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-string_network_address::string_network_address(const std::string &address,
- uint16_t port)
- : address_value_{address}, port_value_{port} {}
-
-const std::string &string_network_address::address() const {
- return address_value_;
-}
-
-uint16_t string_network_address::port() const { return port_value_; }
-} // namespace saw
diff --git a/src/io/io.h b/src/io/io.h
deleted file mode 100644
index 7653ace..0000000
--- a/src/io/io.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#pragma once
-
-#include <forstio/async/async.h>
-#include <forstio/core/common.h>
-#include "io_helpers.h"
-
-#include <string>
-#include <variant>
-
-namespace saw {
-/**
- * Set of error common in io
- */
-namespace err {
-struct disconnected {
- static constexpr std::string_view description = "Disconnected";
- static constexpr bool is_critical = true;
-};
-
-struct resource_busy {
- static constexpr std::string_view description = "Resource busy";
- static constexpr bool is_critical = false;
-};
-}
-/*
- * Input stream
- */
-class input_stream {
-public:
- virtual ~input_stream() = default;
-
- virtual error_or<size_t> read(void *buffer, size_t length) = 0;
-
- virtual conveyor<void> read_ready() = 0;
-
- virtual conveyor<void> on_read_disconnected() = 0;
-};
-
-/*
- * Output stream
- */
-class output_stream {
-public:
- virtual ~output_stream() = default;
-
- virtual error_or<size_t> write(const void *buffer, size_t length) = 0;
-
- virtual conveyor<void> write_ready() = 0;
-};
-
-/*
- * Io stream
- */
-class io_stream : public input_stream, public output_stream {
-public:
- virtual ~io_stream() = default;
-};
-
-class async_input_stream {
-public:
- virtual ~async_input_stream() = default;
-
- virtual void read(void *buffer, size_t min_length, size_t max_length) = 0;
-
- virtual conveyor<size_t> read_done() = 0;
- virtual conveyor<void> on_read_disconnected() = 0;
-};
-
-class async_output_stream {
-public:
- virtual ~async_output_stream() = default;
-
- virtual void write(const void *buffer, size_t length) = 0;
-
- virtual conveyor<size_t> write_done() = 0;
-};
-
-class async_io_stream final : public async_input_stream,
- public async_output_stream {
-private:
- own<io_stream> stream_;
-
- conveyor_sink read_ready_;
- conveyor_sink write_ready_;
- conveyor_sink read_disconnected_;
-
- read_task_and_step_helper read_stepper_;
- write_task_and_step_helper write_stepper_;
-
-public:
- async_io_stream(own<io_stream> str);
-
- SAW_FORBID_COPY(async_io_stream);
- SAW_FORBID_MOVE(async_io_stream);
-
- void read(void *buffer, size_t length, size_t max_length) override;
-
- conveyor<size_t> read_done() override;
-
- conveyor<void> on_read_disconnected() override;
-
- void write(const void *buffer, size_t length) override;
-
- conveyor<size_t> write_done() override;
-};
-
-class server {
-public:
- virtual ~server() = default;
-
- virtual conveyor<own<io_stream>> accept() = 0;
-};
-
-class network_address;
-/**
- * Datagram class. Bound to a local address it is able to receive inbound
- * datagram messages and send them as well as long as an address is provided as
- * well
- */
-class datagram {
-public:
- virtual ~datagram() = default;
-
- virtual error_or<size_t> read(void *buffer, size_t length) = 0;
- virtual conveyor<void> read_ready() = 0;
-
- virtual error_or<size_t> write(const void *buffer, size_t length,
- network_address &dest) = 0;
- virtual conveyor<void> write_ready() = 0;
-};
-
-class os_network_address;
-class string_network_address;
-
-class network_address {
-public:
- using child_variant =
- std::variant<os_network_address *, string_network_address *>;
-
- virtual ~network_address() = default;
-
- virtual network_address::child_variant representation() = 0;
-
- virtual const std::string &address() const = 0;
- virtual uint16_t port() const = 0;
-};
-
-class os_network_address : public network_address {
-public:
- virtual ~os_network_address() = default;
-
- network_address::child_variant representation() override { return this; }
-};
-
-class string_network_address final : public network_address {
-private:
- std::string address_value_;
- uint16_t port_value_;
-
-public:
- string_network_address(const std::string &address, uint16_t port);
-
- const std::string &address() const override;
- uint16_t port() const override;
-
- network_address::child_variant representation() override { return this; }
-};
-
-class network {
-public:
- virtual ~network() = default;
-
- /**
- * Resolve the provided string and uint16 to the preferred storage method
- */
- virtual conveyor<own<network_address>>
- resolve_address(const std::string &addr, uint16_t port_hint = 0) = 0;
-
- /**
- * Parse the provided string and uint16 to the preferred storage method
- * Since no dns request is made here, no async conveyors have to be used.
- */
- /// @todo implement
- // virtual Own<NetworkAddress> parseAddress(const std::string& addr,
- // uint16_t port_hint = 0) = 0;
-
- /**
- * Set up a listener on this address
- */
- virtual own<server> listen(network_address &bind_addr) = 0;
-
- /**
- * Connect to a remote address
- */
- virtual conveyor<own<io_stream>> connect(network_address &address) = 0;
-
- /**
- * Bind a datagram socket at this address.
- */
- virtual own<datagram> datagram(network_address &address) = 0;
-};
-
-class io_provider {
-public:
- virtual ~io_provider() = default;
-
- virtual own<input_stream> wrap_input_fd(int fd) = 0;
-
- virtual network &get_network() = 0;
-};
-
-struct async_io_context {
- own<io_provider> io;
- event_loop &event_loop;
- event_port &event_port;
-};
-
-error_or<async_io_context> setup_async_io();
-} // namespace saw
diff --git a/src/io/io_helpers.cpp b/src/io/io_helpers.cpp
deleted file mode 100644
index c2cf2be..0000000
--- a/src/io/io_helpers.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "io_helpers.h"
-
-#include "io.h"
-
-#include <cassert>
-
-namespace saw {
-void read_task_and_step_helper::read_step(input_stream &reader) {
- while (read_task.has_value()) {
- read_io_task &task = *read_task;
-
- error_or<size_t> n_err = reader.read(task.buffer, task.max_length);
- if (n_err.is_error()) {
- const error &error = n_err.get_error();
- if (error.is_critical()) {
- if (read_done) {
- read_done->fail(error.copy_error());
- }
- read_task = std::nullopt;
- }
-
- break;
- } else if (n_err.is_value()) {
- size_t n = n_err.get_value();
- if (static_cast<size_t>(n) >= task.min_length &&
- static_cast<size_t>(n) <= task.max_length) {
- if (read_done) {
- read_done->feed(n + task.already_read);
- }
- read_task = std::nullopt;
- } else {
- task.buffer = static_cast<uint8_t *>(task.buffer) + n;
- task.min_length -= static_cast<size_t>(n);
- task.max_length -= static_cast<size_t>(n);
- task.already_read += n;
- }
-
- } else {
- if (read_done) {
- read_done->fail(make_error<err::invalid_state>("Read failed"));
- }
- read_task = std::nullopt;
- }
- }
-}
-
-void write_task_and_step_helper::write_step(output_stream &writer) {
- while (write_task.has_value()) {
- write_io_task &task = *write_task;
-
- error_or<size_t> n_err = writer.write(task.buffer, task.length);
-
- if (n_err.is_value()) {
-
- size_t n = n_err.get_value();
- assert(n <= task.length);
- if (n == task.length) {
- if (write_done) {
- write_done->feed(n + task.already_written);
- }
- write_task = std::nullopt;
- } else {
- task.buffer = static_cast<const uint8_t *>(task.buffer) + n;
- task.length -= n;
- task.already_written += n;
- }
- } else if (n_err.is_error()) {
- const error &error = n_err.get_error();
- if (error.is_critical()) {
- if (write_done) {
- write_done->fail(error.copy_error());
- }
- write_task = std::nullopt;
- }
- break;
- } else {
- if (write_done) {
- write_done->fail(make_error<err::invalid_state>("Write failed"));
- }
- write_task = std::nullopt;
- }
- }
-}
-
-} // namespace saw
diff --git a/src/io/io_helpers.h b/src/io/io_helpers.h
deleted file mode 100644
index 94e37f4..0000000
--- a/src/io/io_helpers.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include <forstio/async/async.h>
-#include <forstio/core/common.h>
-
-#include <cstdint>
-#include <optional>
-
-namespace saw {
-/*
- * Helper classes for the specific driver implementations
- */
-
-/*
- * Since I don't want to repeat these implementations for tls on unix systems
- * and gnutls doesn't let me write or read into buffers I have to have this kind
- * of strange abstraction. This may also be reusable for windows/macOS though.
- */
-class input_stream;
-
-class read_task_and_step_helper {
-public:
- struct read_io_task {
- void *buffer;
- size_t min_length;
- size_t max_length;
- size_t already_read = 0;
- };
- std::optional<read_io_task> read_task;
- own<conveyor_feeder<size_t>> read_done = nullptr;
-
- own<conveyor_feeder<void>> on_read_disconnect = nullptr;
-
-public:
- void read_step(input_stream &reader);
-};
-
-class output_stream;
-
-class write_task_and_step_helper {
-public:
- struct write_io_task {
- const void *buffer;
- size_t length;
- size_t already_written = 0;
- };
- std::optional<write_io_task> write_task;
- own<conveyor_feeder<size_t>> write_done = nullptr;
-
-public:
- void write_step(output_stream &writer);
-};
-} // namespace saw
diff --git a/src/io/io_unix.cpp b/src/io/io_unix.cpp
deleted file mode 100644
index c3b4f17..0000000
--- a/src/io/io_unix.cpp
+++ /dev/null
@@ -1,894 +0,0 @@
-#ifdef SAW_UNIX
-
-#include <csignal>
-#include <sys/signalfd.h>
-
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-#include <cassert>
-#include <cstring>
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <queue>
-#include <sstream>
-#include <unordered_map>
-#include <vector>
-
-#include "io.h"
-
-namespace saw {
-namespace unix {
-constexpr int MAX_EPOLL_EVENTS = 256;
-
-class unix_event_port;
-class i_fd_owner {
-protected:
- unix_event_port &event_port_;
-
-private:
- int file_descriptor_;
- int fd_flags_;
- uint32_t event_mask_;
-
-public:
- i_fd_owner(unix_event_port &event_port, int file_descriptor, int fd_flags,
- uint32_t event_mask);
-
- virtual ~i_fd_owner();
-
- virtual void notify(uint32_t mask) = 0;
-
- int fd() const { return file_descriptor_; }
-};
-
-class unix_event_port final : public event_port {
-private:
- int epoll_fd_;
- int signal_fd_;
-
- sigset_t signal_fd_set_;
-
- std::unordered_multimap<Signal, own<conveyor_feeder<void>>>
- signal_conveyors_;
-
- int pipefds_[2];
-
- std::vector<int> to_unix_signal(Signal signal) const {
- switch (signal) {
- case Signal::User1:
- return {SIGUSR1};
- case Signal::Terminate:
- default:
- return {SIGTERM, SIGQUIT, SIGINT};
- }
- }
-
- Signal from_unix_signal(int signal) const {
- switch (signal) {
- case SIGUSR1:
- return Signal::User1;
- case SIGTERM:
- case SIGINT:
- case SIGQUIT:
- default:
- return Signal::Terminate;
- }
- }
-
- void notify_signal_listener(int sig) {
- Signal signal = from_unix_signal(sig);
-
- auto equal_range = signal_conveyors_.equal_range(signal);
- for (auto iter = equal_range.first; iter != equal_range.second;
- ++iter) {
-
- if (iter->second) {
- if (iter->second->space() > 0) {
- iter->second->feed();
- }
- }
- }
- }
-
- bool poll_impl(int time) {
- epoll_event events[MAX_EPOLL_EVENTS];
- int nfds = 0;
- do {
- nfds = epoll_wait(epoll_fd_, events, MAX_EPOLL_EVENTS, time);
-
- if (nfds < 0) {
- /// @todo error_handling
- return false;
- }
-
- for (int i = 0; i < nfds; ++i) {
- if (events[i].data.u64 == 0) {
- while (1) {
- struct ::signalfd_siginfo siginfo;
- ssize_t n =
- ::read(signal_fd_, &siginfo, sizeof(siginfo));
- if (n < 0) {
- break;
- }
- assert(n == sizeof(siginfo));
-
- notify_signal_listener(siginfo.ssi_signo);
- }
- } else if (events[i].data.u64 == 1) {
- uint8_t i;
- if (pipefds_[0] < 0) {
- continue;
- }
- while (1) {
- ssize_t n = ::recv(pipefds_[0], &i, sizeof(i), 0);
- if (n < 0) {
- break;
- }
- }
- } else {
- i_fd_owner *owner =
- reinterpret_cast<i_fd_owner *>(events[i].data.ptr);
- if (owner) {
- owner->notify(events[i].events);
- }
- }
- }
- } while (nfds == MAX_EPOLL_EVENTS);
-
- return true;
- }
-
-public:
- unix_event_port() : epoll_fd_{-1}, signal_fd_{-1} {
- ::signal(SIGPIPE, SIG_IGN);
-
- epoll_fd_ = ::epoll_create1(EPOLL_CLOEXEC);
- if (epoll_fd_ < 0) {
- return;
- }
-
- ::sigemptyset(&signal_fd_set_);
- signal_fd_ =
- ::signalfd(-1, &signal_fd_set_, SFD_NONBLOCK | SFD_CLOEXEC);
- if (signal_fd_ < 0) {
- return;
- }
-
- struct epoll_event event;
- memset(&event, 0, sizeof(event));
- event.events = EPOLLIN;
- event.data.u64 = 0;
- ::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, signal_fd_, &event);
-
- int rc = ::pipe2(pipefds_, O_NONBLOCK | O_CLOEXEC);
- if (rc < 0) {
- return;
- }
- memset(&event, 0, sizeof(event));
- event.events = EPOLLIN;
- event.data.u64 = 1;
- ::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, pipefds_[0], &event);
- }
-
- ~unix_event_port() {
- ::close(epoll_fd_);
- ::close(signal_fd_);
- ::close(pipefds_[0]);
- ::close(pipefds_[1]);
- }
-
- conveyor<void> on_signal(Signal signal) override {
- auto caf = new_conveyor_and_feeder<void>();
-
- signal_conveyors_.insert(std::make_pair(signal, std::move(caf.feeder)));
-
- std::vector<int> sig = to_unix_signal(signal);
-
- for (auto iter = sig.begin(); iter != sig.end(); ++iter) {
- ::sigaddset(&signal_fd_set_, *iter);
- }
- ::sigprocmask(SIG_BLOCK, &signal_fd_set_, nullptr);
- ::signalfd(signal_fd_, &signal_fd_set_, SFD_NONBLOCK | SFD_CLOEXEC);
-
- auto node = conveyor<void>::from_conveyor(std::move(caf.conveyor));
- return conveyor<void>::to_conveyor(std::move(node));
- }
-
- void poll() override { poll_impl(0); }
-
- void wait() override { poll_impl(-1); }
-
- void wait(const std::chrono::steady_clock::duration &duration) override {
- poll_impl(
- std::chrono::duration_cast<std::chrono::milliseconds>(duration)
- .count());
- }
- void
- wait(const std::chrono::steady_clock::time_point &time_point) override {
- auto now = std::chrono::steady_clock::now();
- if (time_point <= now) {
- poll();
- } else {
- poll_impl(std::chrono::duration_cast<std::chrono::milliseconds>(
- time_point - now)
- .count());
- }
- }
-
- void wake() override {
- /// @todo pipe() in the beginning and write something minor into it like
- /// uint8_t or sth the value itself doesn't matter
- if (pipefds_[1] < 0) {
- return;
- }
- uint8_t i = 0;
- ::send(pipefds_[1], &i, sizeof(i), MSG_DONTWAIT);
- }
-
- void subscribe(i_fd_owner &owner, int fd, uint32_t event_mask) {
- if (epoll_fd_ < 0 || fd < 0) {
- return;
- }
- ::epoll_event event;
- memset(&event, 0, sizeof(event));
- event.events = event_mask | EPOLLET;
- event.data.ptr = &owner;
-
- if (::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &event) < 0) {
- /// @todo error_handling
- return;
- }
- }
-
- void unsubscribe(int fd) {
- if (epoll_fd_ < 0 || fd < 0) {
- return;
- }
- if (::epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, nullptr) < 0) {
- /// @todo error_handling
- return;
- }
- }
-};
-
-ssize_t unix_read(int fd, void *buffer, size_t length);
-ssize_t unix_write(int fd, const void *buffer, size_t length);
-
-class unix_io_stream final : public io_stream, public i_fd_owner {
-private:
- own<conveyor_feeder<void>> read_ready_ = nullptr;
- own<conveyor_feeder<void>> on_read_disconnect_ = nullptr;
- own<conveyor_feeder<void>> write_ready_ = nullptr;
-
-public:
- unix_io_stream(unix_event_port &event_port, int file_descriptor,
- int fd_flags, uint32_t event_mask);
-
- error_or<size_t> read(void *buffer, size_t length) override;
-
- conveyor<void> read_ready() override;
-
- conveyor<void> on_read_disconnected() override;
-
- error_or<size_t> write(const void *buffer, size_t length) override;
-
- conveyor<void> write_ready() override;
-
- /*
- void read(void *buffer, size_t min_length, size_t max_length) override;
- Conveyor<size_t> readDone() override;
- Conveyor<void> readReady() override;
-
- Conveyor<void> onReadDisconnected() override;
-
- void write(const void *buffer, size_t length) override;
- Conveyor<size_t> writeDone() override;
- Conveyor<void> writeReady() override;
- */
-
- void notify(uint32_t mask) override;
-};
-
-class unix_server final : public server, public i_fd_owner {
-private:
- own<conveyor_feeder<own<io_stream>>> accept_feeder_ = nullptr;
-
-public:
- unix_server(unix_event_port &event_port, int file_descriptor, int fd_flags);
-
- conveyor<own<io_stream>> accept() override;
-
- void notify(uint32_t mask) override;
-};
-
-class unix_datagram final : public datagram, public i_fd_owner {
-private:
- own<conveyor_feeder<void>> read_ready_ = nullptr;
- own<conveyor_feeder<void>> write_ready_ = nullptr;
-
-public:
- unix_datagram(unix_event_port &event_port, int file_descriptor,
- int fd_flags);
-
- error_or<size_t> read(void *buffer, size_t length) override;
- conveyor<void> read_ready() override;
-
- error_or<size_t> write(const void *buffer, size_t length,
- network_address &dest) override;
- conveyor<void> write_ready() override;
-
- void notify(uint32_t mask) override;
-};
-
-/**
- * Helper class which provides potential addresses to NetworkAddress
- */
-class socket_address {
-private:
- union {
- struct sockaddr generic;
- struct sockaddr_un unix;
- struct sockaddr_in inet;
- struct sockaddr_in6 inet6;
- struct sockaddr_storage storage;
- } address_;
-
- socklen_t address_length_;
- bool wildcard_;
-
- socket_address() : wildcard_{false} {}
-
-public:
- socket_address(const void *sockaddr, socklen_t len, bool wildcard)
- : address_length_{len}, wildcard_{wildcard} {
- assert(len <= sizeof(address_));
- memcpy(&address_.generic, sockaddr, len);
- }
-
- int socket(int type) const {
- type |= SOCK_NONBLOCK | SOCK_CLOEXEC;
-
- int result = ::socket(address_.generic.sa_family, type, 0);
- return result;
- }
-
- bool bind(int fd) const {
- if (wildcard_) {
- int value = 0;
- ::setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value));
- }
- int error = ::bind(fd, &address_.generic, address_length_);
- return error < 0;
- }
-
- struct ::sockaddr *get_raw() {
- return &address_.generic;
- }
-
- const struct ::sockaddr *get_raw() const { return &address_.generic; }
-
- socklen_t get_raw_length() const { return address_length_; }
-
- static std::vector<socket_address> resolve(std::string_view str,
- uint16_t port_hint) {
- std::vector<socket_address> results;
-
- struct ::addrinfo *head;
- struct ::addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
-
- std::string port_string = std::to_string(port_hint);
- bool wildcard = str == "*" || str == "::";
- std::string address_string{str};
-
- int error = ::getaddrinfo(address_string.c_str(), port_string.c_str(),
- &hints, &head);
-
- if (error) {
- return {};
- }
-
- for (struct ::addrinfo *it = head; it != nullptr; it = it->ai_next) {
- if (it->ai_addrlen > sizeof(socket_address::address_)) {
- continue;
- }
- results.push_back({it->ai_addr, it->ai_addrlen, wildcard});
- }
- ::freeaddrinfo(head);
- return results;
- }
-};
-
-class unix_network_address final : public os_network_address {
-private:
- const std::string path_;
- uint16_t port_hint_;
- std::vector<socket_address> addresses_;
-
-public:
- unix_network_address(const std::string &path, uint16_t port_hint,
- std::vector<socket_address> &&addr)
- : path_{path}, port_hint_{port_hint}, addresses_{std::move(addr)} {}
-
- const std::string &address() const override;
-
- uint16_t port() const override;
-
- // Custom address info
- socket_address &unix_address(size_t i = 0);
- size_t unix_address_size() const;
-};
-
-class unix_network final : public network {
-private:
- unix_event_port &event_port_;
-
-public:
- unix_network(unix_event_port &event_port);
-
- conveyor<own<network_address>>
- resolve_address(const std::string &address,
- uint16_t port_hint = 0) override;
-
- own<server> listen(network_address &addr) override;
-
- conveyor<own<io_stream>> connect(network_address &addr) override;
-
- own<class datagram> datagram(network_address &addr) override;
-};
-
-class unix_io_provider final : public io_provider {
-private:
- unix_event_port &event_port_;
- class event_loop event_loop_;
-
- unix_network unix_network_;
-
-public:
- unix_io_provider(unix_event_port &port_ref, own<event_port> port);
-
- class network &get_network() override;
-
- own<input_stream> wrap_input_fd(int fd) override;
-
- class event_loop &event_loop();
-};
-
-i_fd_owner::i_fd_owner(unix_event_port &event_port, int file_descriptor,
- int fd_flags, uint32_t event_mask)
- : event_port_{event_port}, file_descriptor_{file_descriptor},
- fd_flags_{fd_flags}, event_mask_{event_mask} {
- event_port_.subscribe(*this, file_descriptor, event_mask);
-}
-
-i_fd_owner::~i_fd_owner() {
- if (file_descriptor_ >= 0) {
- event_port_.unsubscribe(file_descriptor_);
- ::close(file_descriptor_);
- }
-}
-
-ssize_t unix_read(int fd, void *buffer, size_t length) {
- return ::recv(fd, buffer, length, 0);
-}
-
-ssize_t unix_write(int fd, const void *buffer, size_t length) {
- return ::send(fd, buffer, length, 0);
-}
-
-unix_io_stream::unix_io_stream(unix_event_port &event_port, int file_descriptor,
- int fd_flags, uint32_t event_mask)
- : i_fd_owner{event_port, file_descriptor, fd_flags,
- event_mask | EPOLLRDHUP} {}
-
-error_or<size_t> unix_io_stream::read(void *buffer, size_t length) {
- ssize_t read_bytes = unix_read(fd(), buffer, length);
- if (read_bytes > 0) {
- return static_cast<size_t>(read_bytes);
- } else if (read_bytes == 0) {
- return make_error<err::disconnected>();
- }
-
- return make_error<err::resource_busy>();
-}
-
-conveyor<void> unix_io_stream::read_ready() {
- auto caf = new_conveyor_and_feeder<void>();
- read_ready_ = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-conveyor<void> unix_io_stream::on_read_disconnected() {
- auto caf = new_conveyor_and_feeder<void>();
- on_read_disconnect_ = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-error_or<size_t> unix_io_stream::write(const void *buffer, size_t length) {
- ssize_t write_bytes = unix_write(fd(), buffer, length);
- if (write_bytes > 0) {
- return static_cast<size_t>(write_bytes);
- }
-
- int error = errno;
-
- if (error == EAGAIN || error == EWOULDBLOCK) {
- return make_error<err::resource_busy>();
- }
-
- return make_error<err::disconnected>();
-}
-
-conveyor<void> unix_io_stream::write_ready() {
- auto caf = new_conveyor_and_feeder<void>();
- write_ready_ = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-void unix_io_stream::notify(uint32_t mask) {
- if (mask & EPOLLOUT) {
- if (write_ready_) {
- write_ready_->feed();
- }
- }
-
- if (mask & EPOLLIN) {
- if (read_ready_) {
- read_ready_->feed();
- }
- }
-
- if (mask & EPOLLRDHUP) {
- if (on_read_disconnect_) {
- on_read_disconnect_->feed();
- }
- }
-}
-
-unix_server::unix_server(unix_event_port &event_port, int file_descriptor,
- int fd_flags)
- : i_fd_owner{event_port, file_descriptor, fd_flags, EPOLLIN} {}
-
-conveyor<own<io_stream>> unix_server::accept() {
- auto caf = new_conveyor_and_feeder<own<io_stream>>();
- accept_feeder_ = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-void unix_server::notify(uint32_t mask) {
- if (mask & EPOLLIN) {
- if (accept_feeder_) {
- struct ::sockaddr_storage address;
- socklen_t address_length = sizeof(address);
-
- int accept_fd =
- ::accept4(fd(), reinterpret_cast<struct ::sockaddr *>(&address),
- &address_length, SOCK_NONBLOCK | SOCK_CLOEXEC);
- if (accept_fd < 0) {
- return;
- }
- auto fd_stream = heap<unix_io_stream>(event_port_, accept_fd, 0,
- EPOLLIN | EPOLLOUT);
- accept_feeder_->feed(std::move(fd_stream));
- }
- }
-}
-
-unix_datagram::unix_datagram(unix_event_port &event_port, int file_descriptor,
- int fd_flags)
- : i_fd_owner{event_port, file_descriptor, fd_flags, EPOLLIN | EPOLLOUT} {}
-
-namespace {
-ssize_t unix_read_msg(int fd, void *buffer, size_t length) {
- struct ::sockaddr_storage their_addr;
- socklen_t addr_len = sizeof(sockaddr_storage);
- return ::recvfrom(fd, buffer, length, 0,
- reinterpret_cast<struct ::sockaddr *>(&their_addr),
- &addr_len);
-}
-
-ssize_t unix_write_msg(int fd, const void *buffer, size_t length,
- ::sockaddr *dest_addr, socklen_t dest_addr_len) {
-
- return ::sendto(fd, buffer, length, 0, dest_addr, dest_addr_len);
-}
-} // namespace
-
-error_or<size_t> unix_datagram::read(void *buffer, size_t length) {
- ssize_t read_bytes = unix_read_msg(fd(), buffer, length);
- if (read_bytes > 0) {
- return static_cast<size_t>(read_bytes);
- }
- return make_error<err::resource_busy>();
-}
-
-conveyor<void> unix_datagram::read_ready() {
- auto caf = new_conveyor_and_feeder<void>();
- read_ready_ = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-error_or<size_t> unix_datagram::write(const void *buffer, size_t length,
- network_address &dest) {
- unix_network_address &unix_dest = static_cast<unix_network_address &>(dest);
- socket_address &sock_addr = unix_dest.unix_address();
- socklen_t sock_addr_length = sock_addr.get_raw_length();
- ssize_t write_bytes = unix_write_msg(fd(), buffer, length,
- sock_addr.get_raw(), sock_addr_length);
- if (write_bytes > 0) {
- return static_cast<size_t>(write_bytes);
- }
- return make_error<err::resource_busy>();
-}
-
-conveyor<void> unix_datagram::write_ready() {
- auto caf = new_conveyor_and_feeder<void>();
- write_ready_ = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-void unix_datagram::notify(uint32_t mask) {
- if (mask & EPOLLOUT) {
- if (write_ready_) {
- write_ready_->feed();
- }
- }
-
- if (mask & EPOLLIN) {
- if (read_ready_) {
- read_ready_->feed();
- }
- }
-}
-
-namespace {
-bool begins_with(const std::string_view &viewed,
- const std::string_view &begins) {
- return viewed.size() >= begins.size() &&
- viewed.compare(0, begins.size(), begins) == 0;
-}
-
-std::variant<unix_network_address, unix_network_address *>
-translate_network_address_to_unix_network_address(network_address &addr) {
- auto addr_variant = addr.representation();
- std::variant<unix_network_address, unix_network_address *> os_addr =
- std::visit(
- [](auto &arg)
- -> std::variant<unix_network_address, unix_network_address *> {
- using T = std::decay_t<decltype(arg)>;
-
- if constexpr (std::is_same_v<T, os_network_address *>) {
- return static_cast<unix_network_address *>(arg);
- }
-
- auto sock_addrs = socket_address::resolve(
- std::string_view{arg->address()}, arg->port());
-
- return unix_network_address{arg->address(), arg->port(),
- std::move(sock_addrs)};
- },
- addr_variant);
- return os_addr;
-}
-
-unix_network_address &translate_to_unix_address_ref(
- std::variant<unix_network_address, unix_network_address *> &addr_variant) {
- return std::visit(
- [](auto &arg) -> unix_network_address & {
- using T = std::decay_t<decltype(arg)>;
-
- if constexpr (std::is_same_v<T, unix_network_address>) {
- return arg;
- } else if constexpr (std::is_same_v<T, unix_network_address *>) {
- return *arg;
- } else {
- static_assert(true, "Cases exhausted");
- }
- },
- addr_variant);
-}
-
-} // namespace
-
-own<server> unix_network::listen(network_address &addr) {
- auto unix_addr_storage =
- translate_network_address_to_unix_network_address(addr);
- unix_network_address &address =
- translate_to_unix_address_ref(unix_addr_storage);
-
- assert(address.unix_address_size() > 0);
- if (address.unix_address_size() == 0) {
- return nullptr;
- }
-
- int fd = address.unix_address(0).socket(SOCK_STREAM);
- if (fd < 0) {
- return nullptr;
- }
-
- int val = 1;
- int rc = ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
- if (rc < 0) {
- ::close(fd);
- return nullptr;
- }
-
- bool failed = address.unix_address(0).bind(fd);
- if (failed) {
- ::close(fd);
- return nullptr;
- }
-
- ::listen(fd, SOMAXCONN);
-
- return heap<unix_server>(event_port_, fd, 0);
-}
-
-conveyor<own<io_stream>> unix_network::connect(network_address &addr) {
- auto unix_addr_storage =
- translate_network_address_to_unix_network_address(addr);
- unix_network_address &address =
- translate_to_unix_address_ref(unix_addr_storage);
-
- assert(address.unix_address_size() > 0);
- if (address.unix_address_size() == 0) {
- return conveyor<own<io_stream>>{make_error<err::critical>()};
- }
-
- int fd = address.unix_address(0).socket(SOCK_STREAM);
- if (fd < 0) {
- return conveyor<own<io_stream>>{make_error<err::disconnected>()};
- }
-
- own<unix_io_stream> io_str =
- heap<unix_io_stream>(event_port_, fd, 0, EPOLLIN | EPOLLOUT);
-
- bool success = false;
- for (size_t i = 0; i < address.unix_address_size(); ++i) {
- socket_address &addr_iter = address.unix_address(i);
- int status =
- ::connect(fd, addr_iter.get_raw(), addr_iter.get_raw_length());
- if (status < 0) {
- int error = errno;
- /*
- * It's not connected yet...
- * But edge triggered epolling means that it'll
- * be ready when the signal is triggered
- */
-
- /// @todo Add limit node when implemented
- if (error == EINPROGRESS) {
- /*
- Conveyor<void> write_ready = io_stream->writeReady();
- return write_ready.then(
- [ios{std::move(io_stream)}]() mutable {
- ios->write_ready = nullptr;
- return std::move(ios);
- });
- */
- success = true;
- break;
- } else if (error != EINTR) {
- /// @todo Push error message from
- return conveyor<own<io_stream>>{make_error<err::disconnected>()};
- }
- } else {
- success = true;
- break;
- }
- }
-
- if (!success) {
- return conveyor<own<io_stream>>{make_error<err::disconnected>()};
- }
-
- return conveyor<own<io_stream>>{std::move(io_str)};
-}
-
-own<datagram> unix_network::datagram(network_address &addr) {
- auto unix_addr_storage =
- translate_network_address_to_unix_network_address(addr);
- unix_network_address &address =
- translate_to_unix_address_ref(unix_addr_storage);
-
- SAW_ASSERT(address.unix_address_size() > 0) { return nullptr; }
-
- int fd = address.unix_address(0).socket(SOCK_DGRAM);
-
- int optval = 1;
- int rc =
- ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
- if (rc < 0) {
- ::close(fd);
- return nullptr;
- }
-
- bool failed = address.unix_address(0).bind(fd);
- if (failed) {
- ::close(fd);
- return nullptr;
- }
- /// @todo
- return heap<unix_datagram>(event_port_, fd, 0);
-}
-
-const std::string &unix_network_address::address() const { return path_; }
-
-uint16_t unix_network_address::port() const { return port_hint_; }
-
-socket_address &unix_network_address::unix_address(size_t i) {
- assert(i < addresses_.size());
- /// @todo change from list to vector?
- return addresses_.at(i);
-}
-
-size_t unix_network_address::unix_address_size() const {
- return addresses_.size();
-}
-
-unix_network::unix_network(unix_event_port &event) : event_port_{event} {}
-
-conveyor<own<network_address>>
-unix_network::resolve_address(const std::string &path, uint16_t port_hint) {
- std::string_view addr_view{path};
- {
- std::string_view str_begins_with = "unix:";
- if (begins_with(addr_view, str_begins_with)) {
- addr_view.remove_prefix(str_begins_with.size());
- }
- }
-
- std::vector<socket_address> addresses =
- socket_address::resolve(addr_view, port_hint);
-
- return conveyor<own<network_address>>{
- heap<unix_network_address>(path, port_hint, std::move(addresses))};
-}
-
-unix_io_provider::unix_io_provider(unix_event_port &port_ref,
- own<event_port> port)
- : event_port_{port_ref}, event_loop_{std::move(port)}, unix_network_{
- port_ref} {}
-
-own<input_stream> unix_io_provider::wrap_input_fd(int fd) {
- return heap<unix_io_stream>(event_port_, fd, 0, EPOLLIN);
-}
-
-class network &unix_io_provider::get_network() {
- return static_cast<class network &>(unix_network_);
-}
-
-class event_loop &unix_io_provider::event_loop() {
- return event_loop_;
-}
-
-} // namespace unix
-
-error_or<async_io_context> setup_async_io() {
- using namespace unix;
- try {
- own<unix_event_port> prt = heap<unix_event_port>();
- unix_event_port &prt_ref = *prt;
-
- own<unix_io_provider> io_provider =
- heap<unix_io_provider>(prt_ref, std::move(prt));
-
- event_loop &loop_ref = io_provider->event_loop();
-
- return {{std::move(io_provider), loop_ref, prt_ref}};
- } catch (std::bad_alloc &) {
- return make_error<err::out_of_memory>();
- }
-}
-} // namespace saw
-#endif
diff --git a/src/io_codec/.nix/derivation.nix b/src/io_codec/.nix/derivation.nix
deleted file mode 100644
index 2ea0913..0000000
--- a/src/io_codec/.nix/derivation.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-io_codec";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- forstio.async
- forstio.io
- forstio.codec
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/io_codec/SConscript b/src/io_codec/SConscript
deleted file mode 100644
index 0afd6d6..0000000
--- a/src/io_codec/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-io_env = env.Clone();
-
-io_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-io_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += io_env.sources;
-env.headers += io_env.headers;
-
-## Shared lib
-objects_shared = []
-io_env.add_source_files(objects_shared, io_env.sources, shared=True);
-io_env.library_shared = io_env.SharedLibrary('#build/forstio-io_codec', [objects_shared]);
-
-## Static lib
-objects_static = []
-io_env.add_source_files(objects_static, io_env.sources, shared=False);
-io_env.library_static = io_env.StaticLibrary('#build/forstio-io_codec', [objects_static]);
-
-# Set Alias
-env.Alias('library_io_codec', [io_env.library_shared, io_env.library_static]);
-
-env.targets += ['library_io_codec'];
-
-# Install
-env.Install('$prefix/lib/', [io_env.library_shared, io_env.library_static]);
-env.Install('$prefix/include/forstio/io_codec/', [io_env.headers]);
diff --git a/src/io_codec/SConstruct b/src/io_codec/SConstruct
deleted file mode 100644
index 4e6e150..0000000
--- a/src/io_codec/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-io'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/io_codec/io_peer.h b/src/io_codec/io_peer.h
deleted file mode 100644
index b9a4b34..0000000
--- a/src/io_codec/io_peer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-
-#include <forstio/async/async.h>
-#include <forstio/buffer.h>
-#include <forsto/io/io.h>
-#include <forstio/schema/message.h>
-
-namespace saw {
-
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer = message_container<Incoming>,
- typename OutContainer = message_container<Outgoing>,
- typename BufferT = ring_buffer>
-class streaming_io_peer {
-public:
- /**
- *
- */
- streaming_io_peer(
- own<conveyor_feeder<heap_message_root<Incoming, InContainer>>> feed,
- own<async_io_stream> stream, Codec codec, BufferT in, BufferT out);
- /**
- *
- */
- streaming_io_peer(
- own<conveyor_feeder<heap_message_root<Incoming, InContainer>>> feed,
- own<async_io_stream> stream);
-
- /**
- * Deleted copy and move constructors
- */
- SAW_FORBID_COPY(streaming_io_peer);
- SAW_FORBID_MOVE(streaming_io_peer);
-
- /**
- * Send a message to the remote peer
- */
- error send(heap_message_root<Outgoing, OutContainer> builder);
-
- /**
- * A phantom conveyor feeder. Meant for interfacing with other components
- */
- conveyor_feeder<heap_message_root<Outgoing, OutContainer>> &feeder();
-
- conveyor<void> on_read_disconnected();
-
-private:
- /// @unimplemented
- class peer_conveyor_feeder final
- : public conveyor_feeder<heap_message_root<Outgoing, OutContainer>> {
- public:
- peer_conveyor_feeder(
- streaming_io_peer<Codec, Incoming, Outgoing, InContainer,
- OutContainer, BufferT> &peer_)
- : peer_{peer_} {}
-
- void feed(heap_message_root<Outgoing, OutContainer> &&data) override {
- (void)data;
- }
-
- void fail(error &&error) override { (void)error; }
-
- size_t space() const override { return 0; }
-
- size_t queued() const override { return 0; }
-
- private:
- streaming_io_peer<Codec, Incoming, Outgoing, InContainer, OutContainer,
- BufferT> &peer_;
- };
-
-private:
- own<conveyor_feeder<heap_message_root<Incoming, InContainer>>>
- incoming_feeder_ = nullptr;
-
- own<async_io_stream> io_stream_;
-
- Codec codec_;
-
- BufferT in_buffer_;
- BufferT out_buffer_;
-
- conveyor_sink sink_read_;
- conveyor_sink sink_write_;
-
- peer_conveyor_feeder conveyor_feeder_;
-};
-
-/**
- * Setup new streaming io peer with the provided network protocols.
- * This is a convenience wrapper intended for a faster setup of this class
- */
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer = message_container<Incoming>,
- typename OutContainer = message_container<Outgoing>,
- typename BufferT = ring_buffer>
-std::pair<own<streaming_io_peer<Codec, Incoming, Outgoing, InContainer,
- OutContainer, BufferT>>,
- conveyor<heap_message_root<Incoming, InContainer>>>
-new_streaming_io_peer(own<async_io_stream> stream);
-
-} // namespace saw
-
-#include "io_peer.tmpl.h"
diff --git a/src/io_codec/io_peer.tmpl.h b/src/io_codec/io_peer.tmpl.h
deleted file mode 100644
index 880a58a..0000000
--- a/src/io_codec/io_peer.tmpl.h
+++ /dev/null
@@ -1,117 +0,0 @@
-namespace saw {
-
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer, typename OutContainer, typename BufferT>
-streaming_io_peer<Codec, Incoming, Outgoing, InContainer, OutContainer,
- BufferT>::
- streaming_io_peer(
- own<conveyor_feeder<heap_message_root<Incoming, InContainer>>> feed,
- own<async_io_stream> str)
- : streaming_io_peer{std::move(feed), std::move(str), {}, {}, {}} {}
-
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer, typename OutContainer, typename BufferT>
-streaming_io_peer<Codec, Incoming, Outgoing, InContainer, OutContainer,
- BufferT>::
- streaming_io_peer(
- own<conveyor_feeder<heap_message_root<Incoming, InContainer>>> feed,
- own<async_io_stream> stream, Codec codec, BufferT in, BufferT out)
- : incoming_feeder_{std::move(feed)},
- io_stream_{std::move(stream)}, codec_{std::move(codec)},
- in_buffer_{std::move(in)}, out_buffer_{std::move(out)},
- sink_read_{
- io_stream_->read_done()
- .then([this](size_t bytes) -> error_or<void> {
- in_buffer_.write_advance(bytes);
-
- if (in_buffer_.write_segment_length() == 0) {
- return critical_error("Message too long");
- }
-
- io_stream_->read(&in_buffer_.write(), 1,
- in_buffer_.write_segment_length());
-
- while (true) {
- auto root = heap_message_root<Incoming, InContainer>();
- auto builder = root.build();
-
- error err = codec_.template decode<Incoming, InContainer>(
- builder, in_buffer_);
- if (err.is_critical()) {
- return err;
- }
-
- if (!err.failed()) {
- incoming_feeder_->feed(std::move(root));
- } else {
- break;
- }
- }
-
- return void_t{};
- })
- .sink([this](error err) {
- incoming_feeder_->fail(err.copy_error());
-
- return err;
- })},
- sink_write_{io_stream_->write_done()
- .then([this](size_t bytes) -> error_or<void> {
- out_buffer_.read_advance(bytes);
- if (out_buffer_.readCompositeLength() > 0) {
- io_stream_->write(
- &out_buffer_.read(),
- out_buffer_.read_segment_length());
- }
-
- return void_t{};
- })
- .sink()} {
- io_stream_->read(&in_buffer_.write(), 1, in_buffer_.write_segment_length());
-}
-
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer, typename OutContainer, typename BufferT>
-error streaming_io_peer<Codec, Incoming, Outgoing, InContainer, OutContainer,
- BufferT>::send(heap_message_root<Outgoing, OutContainer>
- msg) {
- bool restart_write = out_buffer_.read_segment_length() == 0;
-
- error err =
- codec_.template encode<Outgoing, OutContainer>(msg.read(), out_buffer_);
- if (err.failed()) {
- return err;
- }
-
- if (restart_write) {
- io_stream_->write(&out_buffer_.read(),
- out_buffer_.read_segment_length());
- }
-
- return no_error();
-}
-
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer, typename OutContainer, typename BufferT>
-conveyor<void>
-streaming_io_peer<Codec, Incoming, Outgoing, InContainer, OutContainer,
- BufferT>::on_read_disconnected() {
- return io_stream_->on_read_disconnected();
-}
-
-template <typename Codec, typename Incoming, typename Outgoing,
- typename InContainer, typename OutContainer, typename BufferT>
-std::pair<own<streaming_io_peer<Codec, Incoming, Outgoing, InContainer,
- OutContainer, BufferT>>,
- conveyor<heap_message_root<Incoming, InContainer>>>
-newstreaming_io_peer(own<async_io_stream> stream) {
- auto caf =
- new_conveyor_and_feeder<heap_message_root<Incoming, InContainer>>();
-
- return {heap<streaming_io_peer<Codec, Incoming, Outgoing, InContainer,
- OutContainer, BufferT>>(
- std::move(caf.feeder), std::move(stream)),
- std::move(caf.conveyor)};
-}
-
-} // namespace saw
diff --git a/src/test/.nix/derivation.nix b/src/test/.nix/derivation.nix
deleted file mode 100644
index 750d8ed..0000000
--- a/src/test/.nix/derivation.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-test";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/test/SConscript b/src/test/SConscript
deleted file mode 100644
index 6379b24..0000000
--- a/src/test/SConscript
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-test_env = env.Clone();
-
-test_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-test_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += test_env.sources;
-env.headers += test_env.headers;
-
-## Shared lib
-objects = []
-test_env.add_source_files(objects, test_env.sources, shared=False);
-test_env.library = test_env.StaticLibrary('#build/forstio-test', [objects]);
-
-# Set Alias
-env.Alias('library_test', [test_env.library]);
-
-env.targets += ['library_test'];
-
-# Install
-env.Install('$prefix/lib/', [test_env.library]);
-env.Install('$prefix/include/forstio/test/', [test_env.headers]);
diff --git a/src/test/SConstruct b/src/test/SConstruct
deleted file mode 100644
index 0d7b7c6..0000000
--- a/src/test/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-core'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/test/suite.cpp b/src/test/suite.cpp
deleted file mode 100644
index 0fca8f9..0000000
--- a/src/test/suite.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-#include "suite.h"
-
-#include <map>
-#include <string>
-#include <chrono>
-#include <iostream>
-
-namespace saw {
-namespace test {
- test_case* testCaseHead = nullptr;
- test_case** testCaseTail = &testCaseHead;
-
- test_case::test_case(const std::string& file_, uint line_, const std::string& description_):
- file{file_},
- line{line_},
- description{description_},
- matched_filter{false},
- next{nullptr},
- prev{testCaseTail}
- {
- *prev = this;
- testCaseTail = &next;
- }
-
- test_case::~test_case(){
- *prev = next;
- if( next == nullptr ){
- testCaseTail = prev;
- }else{
- next->prev = prev;
- }
- }
-
- class test_runner {
- private:
- enum Colour {
- RED,
- GREEN,
- BLUE,
- WHITE
- };
-
- void write(Colour colour, const std::string& front, const std::string& message){
- std::string start_col, end_col;
- switch(colour){
- case RED: start_col = "\033[0;1;31m"; break;
- case GREEN: start_col = "\033[0;1;32m"; break;
- case BLUE: start_col = "\033[0;1;34m"; break;
- case WHITE: start_col = "\033[0m"; break;
- }
- end_col = "\033[0m";
- std::cout<<start_col<<front<<end_col<<message<<'\n';
- }
- public:
- void allowAll(){
- for(test_case* testCase = testCaseHead; testCase != nullptr; testCase = testCase->next){
- testCase->matched_filter = true;
- }
- }
-
- int run() {
- size_t passed_count = 0;
- size_t failed_count = 0;
-
- for(test_case* testCase = testCaseHead; testCase != nullptr; testCase =testCase->next){
- if(testCase->matched_filter){
- std::string name = testCase->file + std::string(":") + std::to_string(testCase->line) + std::string(": ") + testCase->description;
- write(BLUE, "[ TEST ] ", name);
- bool failed = true;
- std::string fail_message;
- auto start_clock = std::chrono::steady_clock::now();
- try {
- testCase->run();
- failed = false;
- }catch(std::exception& e){
- fail_message = e.what();
- failed = true;
- }
- auto stop_clock = std::chrono::steady_clock::now();
-
- auto runtime_duration_intern = stop_clock - start_clock;
- auto runtime_duration = std::chrono::duration_cast<std::chrono::microseconds>(runtime_duration_intern);
- std::string message = name + std::string(" (") + std::to_string(runtime_duration.count()) + std::string(" µs)");
- if(failed){
- write(RED, "[ FAIL ] ", message + " " + fail_message);
- ++failed_count;
- }else{
- write(GREEN, "[ PASS ] ", message);
- ++passed_count;
- }
- }
- }
-
- if(passed_count>0) write(GREEN, std::to_string(passed_count) + std::string(" test(s) passed"), "");
- if(failed_count>0) write(RED, std::to_string(failed_count) + std::string(" test(s) failed"), "");
- return -failed_count;
- }
- };
-}
-}
-
-int main() {
- saw::test::test_runner runner;
- runner.allowAll();
- int rv = runner.run();
- return rv<0?-1:0;
-}
diff --git a/src/test/suite.h b/src/test/suite.h
deleted file mode 100644
index 34f29bf..0000000
--- a/src/test/suite.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-
-#include <string>
-#include <memory>
-#include <stdexcept>
-#include <type_traits>
-
-#include <forstio/core/common.h>
-
-namespace saw {
-namespace test {
-class test_runner;
-class test_case {
-private:
- std::string file;
- uint line;
- std::string description;
- bool matched_filter;
- test_case* next;
- test_case** prev;
-
- friend class test_runner;
-public:
- test_case(const std::string& file_, uint line_, const std::string& description_);
- ~test_case();
-
- virtual void run() = 0;
-};
-}
-}
-#define SAW_TEST(description) \
- class SAW_UNIQUE_NAME(test_case) : public ::saw::test::test_case { \
- public: \
- SAW_UNIQUE_NAME(test_case)(): ::saw::test::test_case(__FILE__,__LINE__,description) {} \
- void run() override; \
- }SAW_UNIQUE_NAME(test_case_); \
- void SAW_UNIQUE_NAME(test_case)::run()
-
-#define SAW_EXPECT(expr, msg_split) \
- if( ! (expr) ){ \
- auto msg = msg_split; \
- throw std::runtime_error{std::string{msg}};\
- }
diff --git a/src/window-opengl/.nix/derivation.nix b/src/window-opengl/.nix/derivation.nix
deleted file mode 100644
index 95cd318..0000000
--- a/src/window-opengl/.nix/derivation.nix
+++ /dev/null
@@ -1,37 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-, xorg
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-window-opengl";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- forstio.async
- forstio.io
- forstio.codec
- forstio.window
- xorg.libX11
- xorg.libxcb
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/window-opengl/SConscript b/src/window-opengl/SConscript
deleted file mode 100644
index bd830b9..0000000
--- a/src/window-opengl/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-window_env = env.Clone();
-
-window_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-window_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += window_env.sources;
-env.headers += window_env.headers;
-
-## Shared lib
-objects_shared = []
-window_env.add_source_files(objects_shared, window_env.sources, shared=True);
-window_env.library_shared = window_env.SharedLibrary('#build/forstio-window', [objects_shared]);
-
-## Static lib
-objects_static = []
-window_env.add_source_files(objects_static, window_env.sources, shared=False);
-window_env.library_static = window_env.StaticLibrary('#build/forstio-window', [objects_static]);
-
-# Set Alias
-env.Alias('library_window', [window_env.library_shared, window_env.library_static]);
-
-env.targets += ['library_window'];
-
-# Install
-env.Install('$prefix/lib/', [window_env.library_shared, window_env.library_static]);
-env.Install('$prefix/include/forstio/window/', [window_env.headers]);
diff --git a/src/window-opengl/SConstruct b/src/window-opengl/SConstruct
deleted file mode 100644
index 05fc016..0000000
--- a/src/window-opengl/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX', 'SAW_UNIX_XCB'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-core', 'forstio-io', 'forstio-async', 'forstio-codec'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/window/.nix/derivation.nix b/src/window/.nix/derivation.nix
deleted file mode 100644
index 9974564..0000000
--- a/src/window/.nix/derivation.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-{ lib
-, stdenvNoCC
-, scons
-, clang
-, clang-tools
-, version
-, forstio
-, xorg
-}:
-
-let
-
-in stdenvNoCC.mkDerivation {
- pname = "forstio-window";
- inherit version;
- src = ./..;
-
- enableParallelBuilding = true;
-
- nativeBuildInputs = [
- scons
- clang
- clang-tools
- ];
-
- buildInputs = [
- forstio.core
- forstio.async
- forstio.io
- forstio.codec
- xorg.libX11
- xorg.libxcb
- ];
-
- outputs = ["out" "dev"];
-}
diff --git a/src/window/SConscript b/src/window/SConscript
deleted file mode 100644
index bd830b9..0000000
--- a/src/window/SConscript
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/false
-
-import os
-import os.path
-import glob
-
-
-Import('env')
-
-dir_path = Dir('.').abspath
-
-# Environment for base library
-window_env = env.Clone();
-
-window_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
-window_env.headers = sorted(glob.glob(dir_path + "/*.h"))
-
-env.sources += window_env.sources;
-env.headers += window_env.headers;
-
-## Shared lib
-objects_shared = []
-window_env.add_source_files(objects_shared, window_env.sources, shared=True);
-window_env.library_shared = window_env.SharedLibrary('#build/forstio-window', [objects_shared]);
-
-## Static lib
-objects_static = []
-window_env.add_source_files(objects_static, window_env.sources, shared=False);
-window_env.library_static = window_env.StaticLibrary('#build/forstio-window', [objects_static]);
-
-# Set Alias
-env.Alias('library_window', [window_env.library_shared, window_env.library_static]);
-
-env.targets += ['library_window'];
-
-# Install
-env.Install('$prefix/lib/', [window_env.library_shared, window_env.library_static]);
-env.Install('$prefix/include/forstio/window/', [window_env.headers]);
diff --git a/src/window/SConstruct b/src/window/SConstruct
deleted file mode 100644
index 05fc016..0000000
--- a/src/window/SConstruct
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import os.path
-import glob
-import re
-
-
-if sys.version_info < (3,):
- def isbasestring(s):
- return isinstance(s,basestring)
-else:
- def isbasestring(s):
- return isinstance(s, (str,bytes))
-
-def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
-
- if isbasestring(filetype):
- dir_path = self.Dir('.').abspath
- filetype = sorted(glob.glob(dir_path+"/"+filetype))
-
- for path in filetype:
- target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
- if shared:
- target_name+='.os'
- sources.append( self.SharedObject( target=target_name, source=path ) )
- else:
- target_name+='.o'
- sources.append( self.StaticObject( target=target_name, source=path ) )
- pass
-
-def isAbsolutePath(key, dirname, env):
- assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
-
-env_vars = Variables(
- args=ARGUMENTS
-)
-
-env_vars.Add('prefix',
- help='Installation target location of build results and headers',
- default='/usr/local/',
- validator=isAbsolutePath
-)
-
-env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
- CPPDEFINES=['SAW_UNIX', 'SAW_UNIX_XCB'],
- CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
- LIBS=['forstio-core', 'forstio-io', 'forstio-async', 'forstio-codec'])
-env.__class__.add_source_files = add_kel_source_files
-env.Tool('compilation_db');
-env.cdb = env.CompilationDatabase('compile_commands.json');
-
-env.objects = [];
-env.sources = [];
-env.headers = [];
-env.targets = [];
-
-Export('env')
-SConscript('SConscript')
-
-env.Alias('cdb', env.cdb);
-env.Alias('all', [env.targets]);
-env.Default('all');
-
-env.Alias('install', '$prefix')
diff --git a/src/window/backends.h b/src/window/backends.h
deleted file mode 100644
index e129037..0000000
--- a/src/window/backends.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace saw {
-namespace gfx {
-namespace backend {
-struct linux_xcb {};
-struct wasm {};
-}
-}
-}
diff --git a/src/window/device.h b/src/window/device.h
deleted file mode 100644
index 7d3cdb1..0000000
--- a/src/window/device.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include "window.h"
-
-#include <forstio/async/async.h>
-#include <forstio/core/common.h>
-#include <forstio/codec/data.h>
-#include <forstio/io/io.h>
-
-#include <string_view>
-#include <variant>
-
-namespace saw {
-namespace gfx {
-template<typename T>
-class device;
-}
-}
diff --git a/src/window/linux_xcb.h b/src/window/linux_xcb.h
deleted file mode 100644
index 65ff94d..0000000
--- a/src/window/linux_xcb.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-#ifdef SAW_UNIX_XCB
-#include "xcb.h"
-#endif
diff --git a/src/window/old.dummy b/src/window/old.dummy
deleted file mode 100644
index c762945..0000000
--- a/src/window/old.dummy
+++ /dev/null
@@ -1,399 +0,0 @@
-#include <X11/Xlib-xcb.h>
-#include <X11/Xlib.h>
-#include <xcb/xcb.h>
-#include <forstio/io/io.h>
-
-#include <map>
-#include <vector>
-
-#include "device.h"
-
-namespace saw {
-class xcb_window;
-class xcb_device final : public device {
-public:
- ::Display *display;
- int screen;
-
- xcb_connection_t *xcb_connection;
- xcb_screen_t *xcb_screen;
-
- own<input_stream> async_notifier;
- conveyor_sink async_conveyor;
-
- std::map<xcb_window_t, xcb_window *> windows;
-
- std::vector<xcb_generic_event_t *> pending_events;
-
-public:
- xcb_device(::Display *display, int screen, xcb_connection_t *xcb_connection,
- xcb_screen_t *xcb_screen, own<input_stream> &&an);
- ~xcb_device();
-
- void window_destroyed(xcb_window_t window_id);
- void handle_events();
-
- own<xcb_window> create_xcb_window(const video_mode &mode,
- std::string_view title_view,
- int visual_id);
- own<window> create_window(const video_mode &video_mode,
- std::string_view title_view) override;
-
- void flush() override;
-};
-
-own<xcb_device> create_xcb_device(io_provider &provider);
-
-class xcb_window final : public window {
-public:
- xcb_device &device_;
-
- xcb_window_t xcb_window_;
- xcb_colormap_t xcb_colormap_;
-
- video_mode video_mode_;
- std::string window_title_;
-
- own<conveyor_feeder<window::variant_event>> event_feeder = nullptr;
-
-public:
- xcb_window(xcb_device &dev, xcb_window_t xcb_win,
- xcb_colormap_t xcb_colormap_, const video_mode &video_mode_,
- std::string_view title_view_);
- ~xcb_window();
-
- void show() override;
- void hide() override;
-
- const video_mode &get_video_mode() const override;
- const std::string_view title() const override;
-
- void resize(size_t width, size_t height) override;
-
- conveyor<window::variant_event> on_event() override;
-
- void resize_event(size_t x, size_t y, size_t width, size_t height);
- void mouse_event(int16_t x, int16_t y, uint16_t state, bool pressed);
- void mouse_move_event(int16_t x, int16_t y);
- void keyboard_event(int16_t x, int16_t y, uint32_t keycode, bool pressed,
- bool repeat);
-};
-
-xcb_device::xcb_device(::Display *display, int screen,
- xcb_connection_t *xcb_connection,
- xcb_screen_t *xcb_screen, own<input_stream> &&an)
- : display{display}, screen{screen}, xcb_connection{xcb_connection},
- xcb_screen{xcb_screen}, async_notifier{std::move(an)},
- async_conveyor{async_notifier->read_ready()
- .then([this]() { handle_events(); })
- .sink()} {}
-
-xcb_device::~xcb_device() {
- if (display) {
- xcb_flush(xcb_connection);
- ::XCloseDisplay(display);
- }
-}
-
-void xcb_device::window_destroyed(xcb_window_t window_id) {
- windows.erase(window_id);
-}
-
-void xcb_device::handle_events() {
- while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection)) {
- pending_events.push_back(event);
- }
- for (size_t i = 0; i < pending_events.size(); ++i) {
- xcb_generic_event_t *event = pending_events.at(i);
- switch (event->response_type & ~0x80) {
- case XCB_MOTION_NOTIFY: {
- xcb_motion_notify_event_t *motion =
- reinterpret_cast<xcb_motion_notify_event_t *>(event);
- auto find = windows.find(motion->event);
- if (find != windows.end()) {
- assert(find->second);
- find->second->mouse_move_event(motion->event_x,
- motion->event_y);
- }
- } break;
- case XCB_EXPOSE: {
- xcb_expose_event_t *expose =
- reinterpret_cast<xcb_expose_event_t *>(event);
- auto find = windows.find(expose->window);
- if (find != windows.end()) {
- assert(find->second);
- find->second->resize_event(static_cast<size_t>(expose->x),
- static_cast<size_t>(expose->y),
- static_cast<size_t>(expose->width),
- static_cast<size_t>(expose->height));
- }
- } break;
- case XCB_BUTTON_RELEASE: {
- xcb_button_release_event_t *button =
- reinterpret_cast<xcb_button_release_event_t *>(event);
- auto find = windows.find(button->event);
- if (find != windows.end()) {
- assert(find->second);
- find->second->mouse_event(button->event_x, button->event_y,
- button->detail, false);
- }
- } break;
- case XCB_BUTTON_PRESS: {
- xcb_button_press_event_t *button =
- reinterpret_cast<xcb_button_press_event_t *>(event);
- auto find = windows.find(button->event);
- if (find != windows.end()) {
- assert(find->second);
- find->second->mouse_event(button->event_x, button->event_y,
- button->detail, true);
- }
- } break;
- case XCB_KEY_RELEASE: {
- xcb_key_release_event_t *key =
- reinterpret_cast<xcb_key_release_event_t *>(event);
-
- bool repeat = false;
- /*
- * Peek into future events
- */
- for (size_t j = i + 1; j < pending_events.size(); ++j) {
- xcb_generic_event_t *f_ev = pending_events.at(j);
-
- if ((f_ev->response_type & ~0x80) == XCB_KEY_PRESS) {
- xcb_key_press_event_t *f_key =
- reinterpret_cast<xcb_key_press_event_t *>(f_ev);
-
- if (key->detail == f_key->detail &&
- key->event == f_key->event) {
- auto iterator = pending_events.begin() + j;
- assert(iterator != pending_events.end());
- free(*iterator);
- pending_events.erase(iterator);
- repeat = true;
- break;
- }
- }
- }
-
- auto find = windows.find(key->event);
- if (find != windows.end()) {
- assert(find->second);
- find->second->keyboard_event(key->event_x, key->event_y,
- key->detail, repeat, repeat);
- }
- } break;
- case XCB_KEY_PRESS: {
- xcb_key_press_event_t *key =
- reinterpret_cast<xcb_key_press_event_t *>(event);
- auto find = windows.find(key->event);
- if (find != windows.end()) {
- assert(find->second);
- find->second->keyboard_event(key->event_x, key->event_y,
- key->detail, true, false);
- }
- } break;
- default:
- break;
- }
- }
-
- for (xcb_generic_event_t *event : pending_events) {
- free(event);
- }
- pending_events.clear();
-}
-
-own<xcb_window> xcb_device::create_xcb_window(const video_mode &video_mode,
- std::string_view title_view,
- int visual_id) {
- assert(xcb_screen);
- assert(xcb_connection);
-
- xcb_colormap_t xcb_colormap = xcb_generate_id(xcb_connection);
- xcb_window_t xcb_window = xcb_generate_id(xcb_connection);
-
- xcb_create_colormap(xcb_connection, XCB_COLORMAP_ALLOC_NONE, xcb_colormap,
- xcb_screen->root, visual_id);
-
- uint32_t eventmask =
- XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS |
- XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS |
- XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION |
- XCB_EVENT_MASK_BUTTON_MOTION;
- uint32_t valuelist[] = {eventmask, xcb_colormap, 0};
- uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
-
- xcb_create_window(xcb_connection, XCB_COPY_FROM_PARENT, xcb_window,
- xcb_screen->root, 0, 0, video_mode.width,
- video_mode.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
- visual_id, valuemask, valuelist);
-
- xcb_change_property(xcb_connection, XCB_PROP_MODE_REPLACE, xcb_window,
- XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title_view.size(),
- title_view.data());
-
- xcb_flush(xcb_connection);
- auto window = heap<class xcb_window>(*this, xcb_window, xcb_colormap,
- video_mode, title_view);
- windows[xcb_window] = window.get();
-
- return window;
-}
-
-own<window> xcb_device::create_window(const video_mode &video_mode,
- std::string_view title_view) {
- assert(xcb_screen);
- return create_xcb_window(video_mode, title_view, xcb_screen->root_visual);
-}
-
-void xcb_device::flush() {
- assert(xcb_connection);
- xcb_flush(xcb_connection);
-}
-
-own<xcb_device> create_xcb_device(io_provider &provider) {
- ::Display *display = ::XOpenDisplay(nullptr);
- if (!display) {
- /// @todo log errors
- return nullptr;
- }
-
- int screen = ::XDefaultScreen(display);
-
- xcb_connection_t *xcb_connection = ::XGetXCBConnection(display);
- if (!xcb_connection) {
- /// @todo log errors
- ::XCloseDisplay(display);
- return nullptr;
- }
-
- int fd = xcb_get_file_descriptor(xcb_connection);
-
- own<input_stream> fd_wrapped = provider.wrap_input_fd(fd);
- if (!fd_wrapped) {
- ::XCloseDisplay(display);
- return nullptr;
- }
-
- ::XSetEventQueueOwner(display, XCBOwnsEventQueue);
-
- xcb_screen_iterator_t screen_iter =
- xcb_setup_roots_iterator(xcb_get_setup(xcb_connection));
- for (int screen_i = screen; screen_iter.rem && screen_i > 0;
- --screen_i, xcb_screen_next(&screen_iter))
- ;
-
- xcb_screen_t *xcb_screen = screen_iter.data;
-
- return heap<xcb_device>(display, screen, xcb_connection, xcb_screen,
- std::move(fd_wrapped));
-}
-
-own<device> createdevice(io_provider &provider) {
- return create_xcb_device(provider);
-}
-
-xcb_window::xcb_window(xcb_device &dev, xcb_window_t xcb_win,
- xcb_colormap_t xcb_colmap, const video_mode &vid_mode,
- std::string_view title_view_)
- : device_{dev}, xcb_window_{xcb_win}, xcb_colormap_{xcb_colmap},
- video_mode_{vid_mode}, window_title_{title_view_} {}
-
-xcb_window::~xcb_window() {
- device_.window_destroyed(xcb_window_);
- xcb_destroy_window(device_.xcb_connection, xcb_window_);
- device_.flush();
-}
-
-void xcb_window::show() {
- assert(device_.xcb_connection);
- xcb_map_window(device_.xcb_connection, xcb_window_);
-}
-
-void xcb_window::hide() {
- assert(device_.xcb_connection);
- xcb_unmap_window(device_.xcb_connection, xcb_window_);
-}
-
-const video_mode &xcb_window::get_video_mode() const { return video_mode_; }
-
-const std::string_view xcb_window::title() const { return window_title_; }
-
-void xcb_window::resize(size_t width, size_t height) {
- const uint32_t values[2] = {static_cast<uint32_t>(width),
- static_cast<uint32_t>(height)};
-
- xcb_configure_window(device_.xcb_connection, xcb_window_,
- XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
- values);
- video_mode_.width = width;
- video_mode_.height = height;
-}
-
-conveyor<window::variant_event> xcb_window::on_event() {
- auto caf = new_conveyor_and_feeder<window::variant_event>();
- event_feeder = std::move(caf.feeder);
- return std::move(caf.conveyor);
-}
-
-void xcb_window::resize_event(size_t x, size_t y, size_t width, size_t height) {
- (void)x;
- (void)y;
- /// @todo maybe include x and y?
- video_mode_.width = width;
- video_mode_.height = height;
-
- if (event_feeder) {
- event_feeder->feed(
- window::variant_event{window::event::resize{width, height}});
- }
-}
-
-void xcb_window::mouse_event(int16_t x, int16_t y, uint16_t state,
- bool pressed) {
- if (x < 0 || y < 0) {
- return;
- }
- uint32_t ux = static_cast<uint32_t>(x);
- uint32_t uy = static_cast<uint32_t>(y);
- if (ux >= video_mode_.width || uy >= video_mode_.height) {
- return;
- }
- if (event_feeder) {
- event_feeder->feed(window::variant_event{
- window::event::mouse{state, pressed, ux, uy}});
- }
-}
-
-void xcb_window::mouse_move_event(int16_t x, int16_t y) {
- if (x < 0 || y < 0) {
- return;
- }
- uint32_t ux = static_cast<uint32_t>(x);
- uint32_t uy = static_cast<uint32_t>(y);
- if (ux >= video_mode_.width || uy >= video_mode_.height) {
- return;
- }
- if (event_feeder) {
- event_feeder->feed(
- window::variant_event{window::event::mouse_move{ux, uy}});
- }
-}
-
-void xcb_window::keyboard_event(int16_t x, int16_t y, uint32_t keycode,
- bool pressed, bool repeat) {
- if (x < 0 || y < 0) {
- return;
- }
- uint32_t ux = static_cast<uint32_t>(x);
- uint32_t uy = static_cast<uint32_t>(y);
- if (ux >= video_mode_.width || uy >= video_mode_.height) {
- return;
- }
- if (event_feeder) {
- event_feeder->feed(window::variant_event{
- window::event::keyboard{keycode, keycode, pressed, repeat}});
- }
-}
-
-} // namespace saw
diff --git a/src/window/video_mode.h b/src/window/video_mode.h
deleted file mode 100644
index a8f1695..0000000
--- a/src/window/video_mode.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-#include <cstddef>
-
-namespace saw {
-class video_mode {
-public:
- size_t width = 64;
- size_t height = 64;
-};
-} // namespace saw
diff --git a/src/window/window.h b/src/window/window.h
deleted file mode 100644
index 36786de..0000000
--- a/src/window/window.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include "video_mode.h"
-
-#include <forstio/async/async.h>
-#include <forstio/core/common.h>
-#include <forstio/codec/schema.h>
-
-#include <string_view>
-#include <variant>
-
-namespace saw {
-namespace gfx {
-namespace schema {
-using namespace saw::schema;
-using WindowResize = Struct<
- Member<UInt32, "width">,
- Member<UInt32, "height">
->;
-using WindowEvents = Union<
- Member<WindowResize, "resize">
->;
-}
-
-template<typename T>
-class window;
-}
-}
-
-#include "linux_xcb.h"
-
-/**
-namespace saw {
-class window {
-public:
- class event {
- public:
- struct resize {
- size_t width;
- size_t height;
- };
-
- struct keyboard {
- uint32_t key;
- uint32_t scan;
- bool pressed;
- bool repeat;
- };
-
- struct mouse {
- uint16_t button_mask;
- bool pressed;
- uint32_t x;
- uint32_t y;
- };
-
- struct mouse_move {
- uint32_t x;
- uint32_t y;
- };
- };
-
- using variant_event = std::variant<event::resize, event::keyboard,
- event::mouse, event::mouse_move>;
-
- virtual ~window() = default;
-
- virtual void show() = 0;
- virtual void hide() = 0;
-
- virtual const video_mode &get_video_mode() const = 0;
- virtual const std::string_view title() const = 0;
-
- virtual void resize(size_t width, size_t height) = 0;
-
- virtual conveyor<variant_event> on_event() = 0;
-};
-} // namespace saw
-*/
diff --git a/src/window/xcb.cpp b/src/window/xcb.cpp
deleted file mode 100644
index 0a27643..0000000
--- a/src/window/xcb.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-#ifndef SAW_UNIX_XCB
-#error "XCB is not supported"
-#endif
-
-#include "xcb.h"
-
-namespace saw {
-namespace gfx {
-device<backend::linux_xcb>::device(::Display* disp, int screen, xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, own<input_stream>&& an):
- display_{disp}, screen_{screen}, xcb_connection_{xcb_connection}, xcb_screen_{xcb_screen}, async_notifier_{std::move(an)},
- async_conveyor_{async_notifier_->read_ready()
- .then([this]() { handle_events(); })
- .sink()} {}
-
-device<backend::linux_xcb>::~device(){
- if (display_) {
- xcb_flush(xcb_connection_);
- ::XCloseDisplay(display_);
- }
-}
-
-void device<backend::linux_xcb>::xcb_window_was_destroyed(xcb_window_t window_id){
- windows_.erase(window_id);
-}
-
-void device<backend::linux_xcb>::handle_events(){
- while (xcb_generic_event_t *event = xcb_poll_for_event(xcb_connection_)) {
- pending_events_.push_back(event);
- }
- for (size_t i = 0; i < pending_events_.size(); ++i) {
- xcb_generic_event_t *event = pending_events_.at(i);
- switch (event->response_type & ~0x80) {
- case XCB_MOTION_NOTIFY: {
- xcb_motion_notify_event_t *motion =
- reinterpret_cast<xcb_motion_notify_event_t *>(event);
- auto find = windows_.find(motion->event);
- if (find != windows_.end()) {
- assert(find->second);
- find->second->mouse_move_event(motion->event_x,
- motion->event_y);
- }
- } break;
- case XCB_EXPOSE: {
- xcb_expose_event_t *expose =
- reinterpret_cast<xcb_expose_event_t *>(event);
- auto find = windows_.find(expose->window);
- if (find != windows_.end()) {
- assert(find->second);
- find->second->resize_event(static_cast<size_t>(expose->x),
- static_cast<size_t>(expose->y),
- static_cast<size_t>(expose->width),
- static_cast<size_t>(expose->height));
- }
- } break;
- case XCB_BUTTON_RELEASE: {
- xcb_button_release_event_t *button =
- reinterpret_cast<xcb_button_release_event_t *>(event);
- auto find = windows_.find(button->event);
- if (find != windows_.end()) {
- assert(find->second);
- find->second->mouse_event(button->event_x, button->event_y,
- button->detail, false);
- }
- } break;
- case XCB_BUTTON_PRESS: {
- xcb_button_press_event_t *button =
- reinterpret_cast<xcb_button_press_event_t *>(event);
- auto find = windows_.find(button->event);
- if (find != windows_.end()) {
- assert(find->second);
- find->second->mouse_event(button->event_x, button->event_y,
- button->detail, true);
- }
- } break;
- case XCB_KEY_RELEASE: {
- xcb_key_release_event_t *key =
- reinterpret_cast<xcb_key_release_event_t *>(event);
-
- bool repeat = false;
- /*
- * Peek into future events
- */
- for (size_t j = i + 1; j < pending_events_.size(); ++j) {
- xcb_generic_event_t *f_ev = pending_events_.at(j);
-
- if ((f_ev->response_type & ~0x80) == XCB_KEY_PRESS) {
- xcb_key_press_event_t *f_key =
- reinterpret_cast<xcb_key_press_event_t *>(f_ev);
-
- if (key->detail == f_key->detail &&
- key->event == f_key->event) {
- auto iterator = pending_events_.begin() + j;
- assert(iterator != pending_events_.end());
- free(*iterator);
- pending_events_.erase(iterator);
- repeat = true;
- break;
- }
- }
- }
-
- auto find = windows_.find(key->event);
- if (find != windows_.end()) {
- assert(find->second);
- find->second->keyboard_event(key->event_x, key->event_y,
- key->detail, repeat, repeat);
- }
- } break;
- case XCB_KEY_PRESS: {
- xcb_key_press_event_t *key =
- reinterpret_cast<xcb_key_press_event_t *>(event);
- auto find = windows_.find(key->event);
- if (find != windows_.end()) {
- assert(find->second);
- find->second->keyboard_event(key->event_x, key->event_y,
- key->detail, true, false);
- }
- } break;
- default:
- break;
- }
- }
-
- for (xcb_generic_event_t *event : pending_events_) {
- free(event);
- }
- pending_events_.clear();
-}
-
-own<window<backend::linux_xcb>> device<backend::linux_xcb>::create_xcb_window(const video_mode &vid_mode,
- std::string_view title_view,
- int visual_id) {
- assert(xcb_screen_);
- assert(xcb_connection_);
-
- xcb_colormap_t xcb_colormap = xcb_generate_id(xcb_connection_);
- xcb_window_t xcb_window = xcb_generate_id(xcb_connection_);
-
- xcb_create_colormap(xcb_connection_, XCB_COLORMAP_ALLOC_NONE, xcb_colormap,
- xcb_screen_->root, visual_id);
-
- uint32_t eventmask =
- XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS |
- XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS |
- XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION |
- XCB_EVENT_MASK_BUTTON_MOTION;
- uint32_t valuelist[] = {eventmask, xcb_colormap, 0};
- uint32_t valuemask = XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
-
- xcb_create_window(xcb_connection_, XCB_COPY_FROM_PARENT, xcb_window,
- xcb_screen_->root, 0, 0, vid_mode.width,
- vid_mode.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
- visual_id, valuemask, valuelist);
-
- xcb_change_property(xcb_connection_, XCB_PROP_MODE_REPLACE, xcb_window,
- XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, title_view.size(),
- title_view.data());
-
- xcb_flush(xcb_connection_);
- auto win = heap<window<backend::linux_xcb>>(*this, xcb_window, xcb_colormap,
- vid_mode, title_view);
- // Insert into map
- windows_[xcb_window] = win.get();
-
- return win;
-}
-
-own<window<backend::linux_xcb>> device<backend::linux_xcb>::create_window(const video_mode& vid_mode, std::string_view title_view){
- assert(xcb_screen_);
- return create_xcb_window(vid_mode, title_view, xcb_screen_->root_visual);
-}
-
-void device<backend::linux_xcb>::flush(){
- assert(xcb_connection_);
- xcb_flush(xcb_connection_);
-}
-
-error_or<own<device<backend::linux_xcb>>> create_xcb_device(io_provider& provider){
- ::Display *display = ::XOpenDisplay(nullptr);
- if (!display) {
- /// @todo log errors
- return make_error<err::critical>();
- }
-
- int screen = ::XDefaultScreen(display);
-
- xcb_connection_t *xcb_connection = ::XGetXCBConnection(display);
- if (!xcb_connection) {
- /// @todo log errors
- ::XCloseDisplay(display);
- return make_error<err::critical>();
- }
-
- int fd = xcb_get_file_descriptor(xcb_connection);
-
- own<input_stream> fd_wrapped = provider.wrap_input_fd(fd);
- if (!fd_wrapped) {
- ::XCloseDisplay(display);
- return make_error<err::critical>();
- }
-
- ::XSetEventQueueOwner(display, XCBOwnsEventQueue);
-
- xcb_screen_iterator_t screen_iter =
- xcb_setup_roots_iterator(xcb_get_setup(xcb_connection));
- for (int screen_i = screen; screen_iter.rem && screen_i > 0;
- --screen_i, xcb_screen_next(&screen_iter))
- ;
-
- xcb_screen_t *xcb_screen = screen_iter.data;
-
- return heap<device<backend::linux_xcb>>(display, screen, xcb_connection, xcb_screen, std::move(fd_wrapped));
-}
-
-window<backend::linux_xcb>::window(device<backend::linux_xcb>& dev_, xcb_window_t xcb_win, xcb_colormap_t xcb_colormap_, const video_mode& vid_mode_, const std::string_view& title_view_):
- device_{&dev_},
- xcb_window_{xcb_win},
- xcb_colormap_{xcb_colormap_},
- video_mode_{vid_mode_},
- window_title_{title_view_}
-{
- // TODO
-}
-
-window<backend::linux_xcb>::~window(){
- // TODO
-}
-
-void window<backend::linux_xcb>::show(){
- // TODO
-}
-
-void window<backend::linux_xcb>::hide(){
- // TODO
-}
-
-}
-}
diff --git a/src/window/xcb.h b/src/window/xcb.h
deleted file mode 100644
index f4e9b9a..0000000
--- a/src/window/xcb.h
+++ /dev/null
@@ -1,91 +0,0 @@
-#pragma once
-
-#ifndef SAW_UNIX_XCB
-#error "XCB is not supported"
-#endif
-
-#include "backends.h"
-#include "device.h"
-#include "window.h"
-
-#include <map>
-
-#include <X11/Xlib-xcb.h>
-#include <X11/Xlib.h>
-
-namespace saw {
-namespace gfx {
-template<typename T>
-class window;
-
-template<typename T>
-class device;
-
-template<>
-class device<backend::linux_xcb> final {
-private:
- ::Display *display_;
- int screen_;
-
- xcb_connection_t *xcb_connection_;
- xcb_screen_t *xcb_screen_;
-
- own<input_stream> async_notifier_;
- conveyor_sink async_conveyor_;
-
- std::map<xcb_window_t, window<backend::linux_xcb> *> windows_;
-
- std::vector<xcb_generic_event_t *> pending_events_;
-private:
- own<window<backend::linux_xcb>> create_xcb_window(const video_mode& vid_mod, std::string_view title_view, int visual_id);
-public:
- device(::Display *display, int screen, xcb_connection_t *xcb_connection,
- xcb_screen_t *xcb_screen, own<input_stream> && an);
-
- ~device();
-
- void xcb_window_was_destroyed(xcb_window_t window_id);
- void handle_events();
-
- own<window<backend::linux_xcb>> create_window(const video_mode& vid_mod, std::string_view title_view);
-
- void flush();
-};
-
-error_or<own<device<backend::linux_xcb>>> create_xcb_device(io_provider& provider);
-
-template<>
-class window<backend::linux_xcb> final {
-private:
- device<backend::linux_xcb> *device_;
-
- xcb_window_t xcb_window_;
- xcb_colormap_t xcb_colormap_;
-
- video_mode video_mode_;
- std::string window_title_;
-
- own<conveyor_feeder<data<schema::WindowEvents>>> event_feeder = nullptr;
-public:
- window(device<backend::linux_xcb>& dev_, xcb_window_t xcb_win, xcb_colormap_t xcb_colormap_, const video_mode& vid_mode_, const std::string_view& title_view_);
-
- ~window();
-
- void show();
- void hide();
-
- const video_mode& get_video_mode() const;
-
- const std::string_view get_title() const;
-
- void resize(uint64_t width, uint64_t height);
-
- conveyor<data<schema::WindowEvents>> on_event();
-
- void resize_event(uint64_t x, uint64_t y, uint64_t width, uint64_t height);
- void mouse_event(int16_t x, int16_t y, uint16_t state, bool pressed);
- void mouse_move_event(int16_t x, int16_t y);
- void keyboard_event(int16_t x, int16_t y, uint32_t keycode, bool pressed, bool repeat);
-};
-}
-}