Merge branch 'dev'
commit
9f593db907
45
README.md
45
README.md
|
@ -1,10 +1,14 @@
|
|||
# kelgin
|
||||
# forst-io
|
||||
|
||||
Asynchronous framework mostly inspired by [Capn'Proto](https://github.com/capnproto/capnproto) with the key difference of not
|
||||
using Promises, but more reusable Pipelines/Conveyors. This introduces some challenges since I can't assume that only one
|
||||
element gets passed along the chain, but it is managable. The advantage is that you have zero heap overhead by not recreating the chain after every use.
|
||||
The asynchronous interfaces are very similar to [Capn'Proto](https://github.com/capnproto/capnproto). At least similar to the 0.7.0 version.
|
||||
The other elements like schema, serialization, network interfaces are designed in another manner.
|
||||
|
||||
Very early stage. I am currently rewriting my software to find a good interface solution by checking if I am comfortable with the current design.
|
||||
Early stage of development. I am currently rewriting my software to find a good interface solution by checking if I am comfortable with the current design.
|
||||
Schema description has been rewritten once already and the current version is probably here to stay. The default container will be changed in the future, so
|
||||
no parsing will be necessary with my binary format.
|
||||
|
||||
# Dependencies
|
||||
|
||||
|
@ -14,7 +18,7 @@ You will need
|
|||
* scons
|
||||
* gnutls
|
||||
|
||||
Currently the build script explicitly calls clang++ due to some occasional compiler error on archlinux with g++.
|
||||
Currently the build script explicitly calls clang++ due to some occasional internal compiler error on archlinux with g++.
|
||||
Optional dependencies are
|
||||
|
||||
* clang-format
|
||||
|
@ -27,10 +31,33 @@ It's that simple.
|
|||
`scons test` build the test cases.
|
||||
`scons format` formats the sources.
|
||||
`scons install` installs the library + headers locally.
|
||||
`scons all` to format the sources and build the library and the tests.
|
||||
|
||||
# Async
|
||||
|
||||
The main interface for async events is the ```Conveyor``` class.
|
||||
This class is the builder object for creating new nodes in the graph of relations. At the same time it stores the end nodes of this graph.
|
||||
Most of the times this async relationship graph is started by using ```newConveyorAndFeeder``` which return a connected input and output
|
||||
class. You can provide the templated data to the feeder and if you have built up a graph with the Conveyor class, it will get passed along the
|
||||
chain.
|
||||
|
||||
It is necessary to create an ```EventLoop``` instance and activate it on the current thread by creating a ```WaitScope``` class before using the
|
||||
Async features.
|
||||
|
||||
## External events
|
||||
|
||||
Since a lot of external events may occur which originate from the OS in some way, we require an additional class called ```EventPort```.
|
||||
You can create your async context by calling ```setupAsyncIo()``` which creates this OS dependent ```EventPort``` for you.
|
||||
Only the ```WaitScope``` has to be created afterwards so these classes are active on the current thread.
|
||||
Most of the times you want to create the ```AsyncIoContext``` on the main thread while in the future other threads can or should have a custom implementation
|
||||
of ```EventPort``` to allow for external events arriving for these threads as well. In the context of threads external means outside of the mentioned thread.
|
||||
|
||||
Cross-Thread communication currently is implemented differently due to missing features. It is done either by implementing your own thread-safe data
|
||||
transfer or using the network features to communicate across threads.
|
||||
|
||||
# Schema Structure
|
||||
|
||||
Message description currently is achieved by a series of templated schema classes found in ```kelgin/schema.h``` as seen below
|
||||
Message description is achieved by a series of templated schema description classes found in ```kelgin/schema.h``` as seen below
|
||||
|
||||
```
|
||||
using BasicStruct = schema::Struct<
|
||||
|
@ -38,9 +65,9 @@ using BasicStruct = schema::Struct<
|
|||
schema::NamedMember<String, "bar">
|
||||
>;
|
||||
```
|
||||
These schema classes are just meant to describe the schema itself. By itself, it can't do anything.
|
||||
These schema classes are just meant to describe the schema structure. By itself, it can't do anything.
|
||||
For a message we create an instance of any MessageRoot class such as `HeapMessageRoot`.
|
||||
Using those schemas and appropriate container classes, we can now build a message class
|
||||
Using those schema classes and an appropriate container class, we can now build a message class as seen below.
|
||||
|
||||
```
|
||||
HeapMessageRoot<BasicStruct, MessageContainer<BasicStruct>> buildBasicMessage(){
|
||||
|
@ -57,7 +84,7 @@ HeapMessageRoot<BasicStruct, MessageContainer<BasicStruct>> buildBasicMessage(){
|
|||
}
|
||||
```
|
||||
|
||||
The current default message container stores each value in stl containers as `std::string`, `std::vector`, `std::tuple`, `std::variant`
|
||||
The current default message container stores each value in stl containers such as `std::string`, `std::vector`, `std::tuple`, `std::variant`
|
||||
or in its primitive form.
|
||||
Though it is planned to allow storing those directly in buffers.
|
||||
|
||||
|
@ -71,7 +98,7 @@ this library. Though no schema or io features are used there.
|
|||
|
||||
* Zerocopy for message templates during parsing
|
||||
* Tls with gnutls (Client side partly done. Server side missing)
|
||||
* Windows/Mac Support
|
||||
* Windows/Mac/Wasm Support
|
||||
* Multithreaded conveyor communication
|
||||
* Logger implementation
|
||||
* Minimal logger implementation to help describe the async graphs with dot files
|
||||
* Reintroduce JSON without dynamic message parsing or at least with more streaming support
|
||||
|
|
10
SConstruct
10
SConstruct
|
@ -29,9 +29,9 @@ def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, ta
|
|||
sources.append( self.StaticObject( target=target_name, source=path ) )
|
||||
pass
|
||||
|
||||
env=Environment(ENV=os.environ, CPPPATH=['#source/kelgin','#source','#','#driver'],
|
||||
env=Environment(ENV=os.environ, CPPPATH=['#source/forstio','#source','#','#driver'],
|
||||
CXX='clang++',
|
||||
CPPDEFINES=['GIN_UNIX'],
|
||||
CPPDEFINES=['SAW_UNIX'],
|
||||
CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
|
||||
LIBS=['gnutls'])
|
||||
env.__class__.add_source_files = add_kel_source_files
|
||||
|
@ -47,7 +47,7 @@ env.driver_sources = []
|
|||
env.driver_headers = []
|
||||
|
||||
Export('env')
|
||||
SConscript('source/kelgin/SConscript')
|
||||
SConscript('source/forstio/SConscript')
|
||||
SConscript('driver/SConscript')
|
||||
|
||||
# Library build
|
||||
|
@ -56,11 +56,11 @@ env_library = env.Clone()
|
|||
|
||||
env.objects_shared = []
|
||||
env_library.add_source_files(env.objects_shared, env.sources + env.driver_sources + env.tls_sources, shared=True)
|
||||
env.library_shared = env_library.SharedLibrary('#bin/kelgin', [env.objects_shared])
|
||||
env.library_shared = env_library.SharedLibrary('#bin/forstio', [env.objects_shared])
|
||||
|
||||
env.objects_static = []
|
||||
env_library.add_source_files(env.objects_static, env.sources + env.driver_sources + env.tls_sources)
|
||||
env.library_static = env_library.StaticLibrary('#bin/kelgin', [env.objects_static])
|
||||
env.library_static = env_library.StaticLibrary('#bin/forstio', [env.objects_static])
|
||||
|
||||
env.Alias('library', [env.library_shared, env.library_static])
|
||||
env.Alias('library_shared', env.library_shared)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
namespace unix {
|
||||
IFdOwner::IFdOwner(UnixEventPort &event_port, int file_descriptor, int fd_flags,
|
||||
uint32_t event_mask)
|
||||
|
@ -279,4 +279,4 @@ ErrorOr<AsyncIoContext> setupAsyncIo() {
|
|||
return criticalError("Out of memory");
|
||||
}
|
||||
}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef GIN_UNIX
|
||||
#ifndef SAW_UNIX
|
||||
#error "Don't include this"
|
||||
#endif
|
||||
|
||||
|
@ -26,10 +26,9 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "./io.h"
|
||||
#include "kelgin/io.h"
|
||||
#include "forstio/io.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
namespace unix {
|
||||
constexpr int MAX_EPOLL_EVENTS = 256;
|
||||
|
||||
|
@ -439,4 +438,4 @@ public:
|
|||
EventLoop &eventLoop();
|
||||
};
|
||||
} // namespace unix
|
||||
} // namespace gin
|
||||
} // namespace saw
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
namespace {
|
||||
thread_local EventLoop *local_loop = nullptr;
|
||||
|
||||
|
@ -344,4 +344,4 @@ void detachConveyor(Conveyor<void> &&conveyor) {
|
|||
ConveyorSinks &sink = loop.daemon();
|
||||
sink.add(std::move(conveyor));
|
||||
}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -10,7 +10,7 @@
|
|||
#include <queue>
|
||||
#include <type_traits>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
class ConveyorNode {
|
||||
public:
|
||||
ConveyorNode();
|
||||
|
@ -409,11 +409,11 @@ template <typename Func> ConveyorResult<Func, void> yieldNext(Func &&func);
|
|||
template <typename Func> ConveyorResult<Func, void> yieldLater(Func &&func);
|
||||
|
||||
template <typename Func> ConveyorResult<Func, void> yieldLast(Func &&func);
|
||||
} // namespace gin
|
||||
} // namespace saw
|
||||
|
||||
// Secret stuff
|
||||
// Aka private semi hidden classes
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
|
||||
template <typename Out, typename In> struct FixVoidCaller {
|
||||
template <typename Func> static Out apply(Func &func, In &&in) {
|
||||
|
@ -878,6 +878,6 @@ public:
|
|||
|
||||
*/
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
||||
|
||||
#include "async.tmpl.h"
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
|
||||
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func) {
|
||||
Conveyor<void> conveyor{FixVoid<void>{}};
|
||||
|
@ -65,7 +65,7 @@ template <typename T> Conveyor<T> Conveyor<T>::buffer(size_t size) {
|
|||
size);
|
||||
ConveyorStorage *storage_ptr =
|
||||
static_cast<ConveyorStorage *>(storage_node.get());
|
||||
GIN_ASSERT(storage) { return Conveyor<T>{nullptr, nullptr}; }
|
||||
SAW_ASSERT(storage) { return Conveyor<T>{nullptr, nullptr}; }
|
||||
|
||||
storage->setParent(storage_ptr);
|
||||
return Conveyor<T>{std::move(storage_node), storage_ptr};
|
||||
|
@ -104,7 +104,7 @@ SinkConveyor Conveyor<void>::sink(ErrorFunc &&error_func) {
|
|||
ConveyorStorage *storage_ptr =
|
||||
static_cast<ConveyorStorage *>(sink_node.get());
|
||||
|
||||
GIN_ASSERT(storage) { return SinkConveyor{}; }
|
||||
SAW_ASSERT(storage) { return SinkConveyor{}; }
|
||||
storage->setParent(storage_ptr);
|
||||
|
||||
return SinkConveyor{std::move(sink_node)};
|
||||
|
@ -228,7 +228,7 @@ template <typename T> void QueueBufferConveyorNode<T>::childHasFired() {
|
|||
}
|
||||
|
||||
template <typename T> void QueueBufferConveyorNode<T>::parentHasFired() {
|
||||
GIN_ASSERT(parent) { return; }
|
||||
SAW_ASSERT(parent) { return; }
|
||||
|
||||
if (parent->space() == 0) {
|
||||
return;
|
||||
|
@ -261,7 +261,7 @@ template <typename T> void ImmediateConveyorNode<T>::childHasFired() {
|
|||
}
|
||||
|
||||
template <typename T> void ImmediateConveyorNode<T>::parentHasFired() {
|
||||
GIN_ASSERT(parent) { return; }
|
||||
SAW_ASSERT(parent) { return; }
|
||||
assert(parent->space() > 0);
|
||||
|
||||
if (queued() > 0) {
|
||||
|
@ -287,7 +287,7 @@ template <typename T> MergeConveyor<T>::~MergeConveyor() {}
|
|||
|
||||
template <typename T> void MergeConveyor<T>::attach(Conveyor<T> conveyor) {
|
||||
auto sp = data.lock();
|
||||
GIN_ASSERT(sp) { return; }
|
||||
SAW_ASSERT(sp) { return; }
|
||||
|
||||
sp->attach(std::move(conveyor));
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ template <typename T> void MergeConveyor<T>::attach(Conveyor<T> conveyor) {
|
|||
template <typename T>
|
||||
MergeConveyorNode<T>::MergeConveyorNode(Our<MergeConveyorNodeData<T>> d)
|
||||
: data{d} {
|
||||
GIN_ASSERT(data) { return; }
|
||||
SAW_ASSERT(data) { return; }
|
||||
|
||||
data->merger = this;
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ template <typename T>
|
|||
void MergeConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept {
|
||||
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>();
|
||||
|
||||
GIN_ASSERT(data) { return; }
|
||||
SAW_ASSERT(data) { return; }
|
||||
|
||||
/// @todo search appendages for result
|
||||
|
||||
|
@ -334,7 +334,7 @@ void MergeConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept {
|
|||
}
|
||||
|
||||
template <typename T> void MergeConveyorNode<T>::fire() {
|
||||
GIN_ASSERT(queued() > 0) { return; }
|
||||
SAW_ASSERT(queued() > 0) { return; }
|
||||
|
||||
if (parent) {
|
||||
parent->childHasFired();
|
||||
|
@ -348,7 +348,7 @@ template <typename T> void MergeConveyorNode<T>::fire() {
|
|||
template <typename T> size_t MergeConveyorNode<T>::space() const { return 0; }
|
||||
|
||||
template <typename T> size_t MergeConveyorNode<T>::queued() const {
|
||||
GIN_ASSERT(data) { return 0; }
|
||||
SAW_ASSERT(data) { return 0; }
|
||||
|
||||
size_t queue_count = 0;
|
||||
|
||||
|
@ -365,7 +365,7 @@ template <typename T> void MergeConveyorNode<T>::childHasFired() {
|
|||
}
|
||||
|
||||
template <typename T> void MergeConveyorNode<T>::parentHasFired() {
|
||||
GIN_ASSERT(parent) { return; }
|
||||
SAW_ASSERT(parent) { return; }
|
||||
if (queued() > 0) {
|
||||
if (parent->space() > 0) {
|
||||
armLater();
|
||||
|
@ -374,7 +374,7 @@ template <typename T> void MergeConveyorNode<T>::parentHasFired() {
|
|||
}
|
||||
|
||||
template <typename T> size_t MergeConveyorNode<T>::Appendage::space() const {
|
||||
GIN_ASSERT(merger) { return 0; }
|
||||
SAW_ASSERT(merger) { return 0; }
|
||||
|
||||
if (error_or_value.has_value()) {
|
||||
return 0;
|
||||
|
@ -384,7 +384,7 @@ template <typename T> size_t MergeConveyorNode<T>::Appendage::space() const {
|
|||
}
|
||||
|
||||
template <typename T> size_t MergeConveyorNode<T>::Appendage::queued() const {
|
||||
GIN_ASSERT(merger) { return 0; }
|
||||
SAW_ASSERT(merger) { return 0; }
|
||||
|
||||
if (error_or_value.has_value()) {
|
||||
return 1;
|
||||
|
@ -397,7 +397,7 @@ template <typename T>
|
|||
void MergeConveyorNode<T>::Appendage::getAppendageResult(ErrorOrValue &eov) {
|
||||
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>();
|
||||
|
||||
GIN_ASSERT(queued() > 0) {
|
||||
SAW_ASSERT(queued() > 0) {
|
||||
err_or_val = criticalError("No element queued in Merge Appendage Node");
|
||||
return;
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ void MergeConveyorNode<T>::Appendage::getAppendageResult(ErrorOrValue &eov) {
|
|||
}
|
||||
|
||||
template <typename T> void MergeConveyorNode<T>::Appendage::childHasFired() {
|
||||
GIN_ASSERT(!error_or_value.has_value()) { return; }
|
||||
SAW_ASSERT(!error_or_value.has_value()) { return; }
|
||||
ErrorOr<FixVoid<T>> eov;
|
||||
child->getResult(eov);
|
||||
|
||||
|
@ -426,9 +426,9 @@ template <typename T> void MergeConveyorNode<T>::Appendage::parentHasFired() {
|
|||
|
||||
template <typename T>
|
||||
void MergeConveyorNode<T>::Appendage::setParent(ConveyorStorage *par) {
|
||||
GIN_ASSERT(merger) { return; }
|
||||
SAW_ASSERT(merger) { return; }
|
||||
|
||||
GIN_ASSERT(child) { return; }
|
||||
SAW_ASSERT(child) { return; }
|
||||
|
||||
parent = par;
|
||||
}
|
||||
|
@ -541,7 +541,7 @@ template <typename T> void AdaptConveyorNode<T>::childHasFired() {
|
|||
}
|
||||
|
||||
template <typename T> void AdaptConveyorNode<T>::parentHasFired() {
|
||||
GIN_ASSERT(parent) { return; }
|
||||
SAW_ASSERT(parent) { return; }
|
||||
|
||||
if (parent->space() == 0) {
|
||||
return;
|
||||
|
@ -644,4 +644,4 @@ template <typename T> void OneTimeConveyorNode<T>::fire() {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -6,7 +6,7 @@
|
|||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
Error Buffer::push(const uint8_t &value) {
|
||||
size_t write_remain = writeCompositeLength();
|
||||
if (write_remain > 0) {
|
||||
|
@ -429,4 +429,4 @@ Error ArrayBuffer::writeRequireLength(size_t bytes) {
|
|||
return noError();
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -9,7 +9,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
/*
|
||||
* Access class to reduce templated BufferSegments bloat
|
||||
*/
|
||||
|
@ -189,4 +189,4 @@ public:
|
|||
|
||||
Error writeRequireLength(size_t bytes) override;
|
||||
};
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -5,29 +5,29 @@
|
|||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
|
||||
#define GIN_CONCAT_(x, y) x##y
|
||||
#define GIN_CONCAT(x, y) GIN_CONCAT_(x, y)
|
||||
#define GIN_UNIQUE_NAME(prefix) GIN_CONCAT(prefix, __LINE__)
|
||||
#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 GIN_FORBID_COPY(classname) \
|
||||
#define SAW_FORBID_COPY(classname) \
|
||||
classname(const classname &) = delete; \
|
||||
classname &operator=(const classname &) = delete
|
||||
|
||||
#define GIN_FORBID_MOVE(classname) \
|
||||
#define SAW_FORBID_MOVE(classname) \
|
||||
classname(classname &&) = delete; \
|
||||
classname &operator=(classname &&) = delete
|
||||
|
||||
#define GIN_DEFAULT_COPY(classname) \
|
||||
#define SAW_DEFAULT_COPY(classname) \
|
||||
classname(const classname &) = default; \
|
||||
classname &operator=(const classname &) = default
|
||||
|
||||
#define GIN_DEFAULT_MOVE(classname) \
|
||||
#define SAW_DEFAULT_MOVE(classname) \
|
||||
classname(classname &&) = default; \
|
||||
classname &operator=(classname &&) = default
|
||||
|
||||
#define GIN_ASSERT(expression) \
|
||||
#define SAW_ASSERT(expression) \
|
||||
assert(expression); \
|
||||
if (!(expression))
|
||||
|
||||
|
@ -69,4 +69,4 @@ template <typename T> struct VoidUnfix { typedef T Type; };
|
|||
template <> struct VoidUnfix<Void> { typedef void Type; };
|
||||
template <typename T> using UnfixVoid = typename VoidUnfix<T>::Type;
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -1,6 +1,6 @@
|
|||
#include "error.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
Error::Error() : error_{static_cast<Error::Code>(0)} {}
|
||||
|
||||
Error::Error(const std::string_view &msg, Error::Code code)
|
||||
|
@ -70,4 +70,4 @@ Error recoverableError(const std::string_view &generic, Error::Code c) {
|
|||
|
||||
Error noError() { return Error{}; }
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
/**
|
||||
* Utility class for generating errors. Has a base distinction between
|
||||
* critical and recoverable errors. Additional code ids can be provided to the
|
||||
|
@ -31,7 +31,7 @@ public:
|
|||
Error(std::string &&msg, Error::Code code);
|
||||
Error(Error &&error);
|
||||
|
||||
GIN_FORBID_COPY(Error);
|
||||
SAW_FORBID_COPY(Error);
|
||||
|
||||
Error &operator=(Error &&) = default;
|
||||
|
||||
|
@ -138,4 +138,4 @@ private:
|
|||
ErrorOr() = delete;
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
|
||||
AsyncIoStream::AsyncIoStream(Own<IoStream> str)
|
||||
: stream{std::move(str)}, read_ready{stream->readReady()
|
||||
|
@ -22,9 +22,9 @@ AsyncIoStream::AsyncIoStream(Own<IoStream> str)
|
|||
.sink()} {}
|
||||
|
||||
void AsyncIoStream::read(void *buffer, size_t min_length, size_t max_length) {
|
||||
GIN_ASSERT(buffer && max_length >= min_length && min_length > 0) { return; }
|
||||
SAW_ASSERT(buffer && max_length >= min_length && min_length > 0) { return; }
|
||||
|
||||
GIN_ASSERT(!read_stepper.read_task.has_value()) { return; }
|
||||
SAW_ASSERT(!read_stepper.read_task.has_value()) { return; }
|
||||
|
||||
read_stepper.read_task =
|
||||
ReadTaskAndStepHelper::ReadIoTask{buffer, min_length, max_length, 0};
|
||||
|
@ -44,9 +44,9 @@ Conveyor<void> AsyncIoStream::onReadDisconnected() {
|
|||
}
|
||||
|
||||
void AsyncIoStream::write(const void *buffer, size_t length) {
|
||||
GIN_ASSERT(buffer && length > 0) { return; }
|
||||
SAW_ASSERT(buffer && length > 0) { return; }
|
||||
|
||||
GIN_ASSERT(!write_stepper.write_task.has_value()) { return; }
|
||||
SAW_ASSERT(!write_stepper.write_task.has_value()) { return; }
|
||||
|
||||
write_stepper.write_task =
|
||||
WriteTaskAndStepHelper::WriteIoTask{buffer, length, 0};
|
||||
|
@ -58,4 +58,4 @@ Conveyor<size_t> AsyncIoStream::writeDone() {
|
|||
write_stepper.write_done = std::move(caf.feeder);
|
||||
return std::move(caf.conveyor);
|
||||
}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
/*
|
||||
* Input stream
|
||||
*/
|
||||
|
@ -132,4 +132,4 @@ struct AsyncIoContext {
|
|||
};
|
||||
|
||||
ErrorOr<AsyncIoContext> setupAsyncIo();
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
void ReadTaskAndStepHelper::readStep(InputStream &reader) {
|
||||
while (read_task.has_value()) {
|
||||
ReadIoTask &task = *read_task;
|
||||
|
@ -82,4 +82,4 @@ void WriteTaskAndStepHelper::writeStep(OutputStream &writer) {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -6,7 +6,7 @@
|
|||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
/*
|
||||
* Helper classes for the specific driver implementations
|
||||
*/
|
||||
|
@ -50,4 +50,4 @@ public:
|
|||
public:
|
||||
void writeStep(OutputStream &writer);
|
||||
};
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -3,7 +3,7 @@
|
|||
#include "async.h"
|
||||
#include "io.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
|
||||
template <typename Codec, typename Incoming, typename Outgoing>
|
||||
class StreamingIoPeer {
|
||||
|
@ -22,4 +22,4 @@ public:
|
|||
Conveyor<Incoming> startReadPump();
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -1,7 +1,7 @@
|
|||
#include "log.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
LogIo::LogIo(EventLoop &loop) : loop{loop} {}
|
||||
|
||||
Log::Log(LogIo ¢ral, EventLoop &loop) : central{central}, loop{loop} {}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
class EventLoop;
|
||||
class LogIo;
|
||||
class Log {
|
||||
|
@ -23,4 +23,4 @@ private:
|
|||
public:
|
||||
LogIo(EventLoop &loop);
|
||||
};
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -14,7 +14,7 @@
|
|||
#include "schema.h"
|
||||
#include "string_literal.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
class MessageBase {
|
||||
protected:
|
||||
bool set_explicitly = false;
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
SchemaIsArray<
|
||||
typename MessageParameterPackType<i, V...>::Type>::Value,
|
||||
typename Container::template ElementType<i>::Builder>::type
|
||||
init(size_t size) {
|
||||
init(size_t size = 0) {
|
||||
auto array_builder =
|
||||
typename Container::template ElementType<i>::Builder{
|
||||
message.container.template get<i>(), size};
|
||||
|
@ -234,7 +234,7 @@ public:
|
|||
SchemaIsArray<
|
||||
typename MessageParameterPackType<i, V...>::Type>::Value,
|
||||
typename Container::template ElementType<i>::Builder>::type
|
||||
init(size_t size) {
|
||||
init(size_t size = 0) {
|
||||
return typename Container::template ElementType<i>::Builder{
|
||||
message.container.template get<i>(), size};
|
||||
}
|
||||
|
@ -332,6 +332,8 @@ public:
|
|||
}
|
||||
|
||||
size_t size() const { return message.container.size(); }
|
||||
|
||||
void resize(size_t size) { message.container.resize(size); }
|
||||
};
|
||||
|
||||
class Reader {
|
||||
|
@ -394,7 +396,7 @@ public:
|
|||
SchemaIsArray<
|
||||
typename MessageParameterPackType<i, T...>::Type>::Value,
|
||||
typename Container::template ElementType<i>::Builder>::type
|
||||
init(size_t size) {
|
||||
init(size_t size = 0) {
|
||||
return typename Container::template ElementType<i>::Builder{
|
||||
message.container.template get<i>(), size};
|
||||
}
|
||||
|
@ -557,4 +559,4 @@ inline HeapMessageRoot<Schema, Container> heapMessageRoot() {
|
|||
Own<Message<Schema, Container>> root = heap<Message<Schema, Container>>();
|
||||
return HeapMessageRoot<Schema, Container>{std::move(root)};
|
||||
}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "schema.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
template <class T> class MessageContainer;
|
||||
|
||||
template <class T, class Container = MessageContainer<T>> class Message;
|
||||
|
@ -238,4 +238,4 @@ public:
|
|||
|
||||
const ValueType &get() const { return value; }
|
||||
};
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -4,9 +4,7 @@
|
|||
#include "message.h"
|
||||
#include "stream_endian.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
/// @todo replace types with these
|
||||
/*
|
||||
* I'm not really sure if anyone will use a union which is
|
||||
|
@ -493,6 +491,8 @@ struct ProtoKelDecodeImpl<Message<schema::Array<T>, Container>> {
|
|||
}
|
||||
}
|
||||
|
||||
data.resize(array_length);
|
||||
|
||||
for (size_t i = 0; i < array_length; ++i) {
|
||||
Error error =
|
||||
ProtoKelDecodeImpl<typename Container::ElementType>::decode(
|
||||
|
@ -582,4 +582,4 @@ Error ProtoKelCodec::decode(
|
|||
return noError();
|
||||
}
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "string_literal.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
namespace schema {
|
||||
|
||||
template <class T, StringLiteral Literal> struct NamedMember {};
|
||||
|
@ -48,4 +48,4 @@ using Float32 = Primitive<FloatingPoint, 4>;
|
|||
using Float64 = Primitive<FloatingPoint, 8>;
|
||||
|
||||
} // namespace schema
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
namespace gin {
|
||||
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
|
||||
|
@ -149,4 +149,4 @@ public:
|
|||
|
||||
template <typename T> using StreamValue = ShiftStreamValue<T>;
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -3,7 +3,7 @@
|
|||
#include <array>
|
||||
#include <string_view>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
/**
|
||||
* Helper object which creates a templated string from the provided string
|
||||
* literal. It guarantees compile time uniqueness and thus allows using strings
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
};
|
||||
|
||||
template <typename T, T... Chars>
|
||||
constexpr gin::StringLiteral<T, sizeof...(Chars)> operator""_key() {
|
||||
return gin::StringLiteral<T, sizeof...(Chars) + 1u>{Chars..., '\0'};
|
||||
constexpr StringLiteral<T, sizeof...(Chars)> operator""_key() {
|
||||
return StringLiteral<T, sizeof...(Chars) + 1u>{Chars..., '\0'};
|
||||
}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
#include <chrono>
|
||||
|
||||
namespace gin {}
|
||||
namespace saw {}
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
|
||||
class Tls::Impl {
|
||||
public:
|
||||
|
@ -28,9 +28,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static ssize_t kelgin_tls_push_func(gnutls_transport_ptr_t p, const void *data,
|
||||
static ssize_t forst_tls_push_func(gnutls_transport_ptr_t p, const void *data,
|
||||
size_t size);
|
||||
static ssize_t kelgin_tls_pull_func(gnutls_transport_ptr_t p, 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>()} {}
|
||||
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
TlsServer::TlsServer(Own<Server> srv) : internal{std::move(srv)} {}
|
||||
|
||||
Conveyor<Own<IoStream>> TlsServer::accept() {
|
||||
GIN_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; }
|
||||
SAW_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; }
|
||||
return internal->accept().then([](Own<IoStream> stream) -> Own<IoStream> {
|
||||
/// @todo handshake
|
||||
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
{}
|
||||
|
||||
void setupTurn(){
|
||||
GIN_ASSERT(stream){
|
||||
SAW_ASSERT(stream){
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ public:
|
|||
void turn(){
|
||||
if(stream){
|
||||
// Guarantee that the receiving end is already setup
|
||||
GIN_ASSERT(feeder){
|
||||
SAW_ASSERT(feeder){
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -159,12 +159,12 @@ TlsNetworkAddress::TlsNetworkAddress(Own<NetworkAddress> net_addr, const std::st
|
|||
: internal{std::move(net_addr)}, host_name{host_name_}, tls{tls_} {}
|
||||
|
||||
Own<Server> TlsNetworkAddress::listen() {
|
||||
GIN_ASSERT(internal) { return nullptr; }
|
||||
SAW_ASSERT(internal) { return nullptr; }
|
||||
return heap<TlsServer>(internal->listen());
|
||||
}
|
||||
|
||||
Conveyor<Own<IoStream>> TlsNetworkAddress::connect() {
|
||||
GIN_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; }
|
||||
SAW_ASSERT(internal) { return Conveyor<Own<IoStream>>{nullptr, nullptr}; }
|
||||
|
||||
// Helper setups
|
||||
auto caf = newConveyorAndFeeder<Own<IoStream>>();
|
||||
|
@ -192,8 +192,8 @@ Conveyor<Own<IoStream>> TlsNetworkAddress::connect() {
|
|||
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, kelgin_tls_push_func);
|
||||
gnutls_transport_set_pull_function(session, kelgin_tls_pull_func);
|
||||
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);
|
||||
|
||||
|
@ -209,7 +209,7 @@ Conveyor<Own<IoStream>> TlsNetworkAddress::connect() {
|
|||
return caf.conveyor.attach(std::move(helper));
|
||||
}
|
||||
|
||||
static ssize_t kelgin_tls_push_func(gnutls_transport_ptr_t p, const void *data,
|
||||
static ssize_t forst_tls_push_func(gnutls_transport_ptr_t p, const void *data,
|
||||
size_t size) {
|
||||
IoStream *stream = reinterpret_cast<IoStream *>(p);
|
||||
if (!stream) {
|
||||
|
@ -224,7 +224,7 @@ static ssize_t kelgin_tls_push_func(gnutls_transport_ptr_t p, const void *data,
|
|||
return static_cast<ssize_t>(length.value());
|
||||
}
|
||||
|
||||
static ssize_t kelgin_tls_pull_func(gnutls_transport_ptr_t p, void *data, size_t size) {
|
||||
static ssize_t forst_tls_pull_func(gnutls_transport_ptr_t p, void *data, size_t size) {
|
||||
IoStream *stream = reinterpret_cast<IoStream *>(p);
|
||||
if (!stream) {
|
||||
return -1;
|
||||
|
@ -263,4 +263,4 @@ Conveyor<Own<NetworkAddress>> TlsNetwork::parseAddress(const std::string &addr,
|
|||
std::optional<Own<TlsNetwork>> setupTlsNetwork(Network &network) {
|
||||
return std::nullopt;
|
||||
}
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -6,7 +6,7 @@
|
|||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
class Tls {
|
||||
private:
|
||||
class Impl;
|
||||
|
@ -66,4 +66,4 @@ public:
|
|||
|
||||
std::optional<Own<TlsNetwork>> setupTlsNetwork(Network &network);
|
||||
|
||||
} // namespace gin
|
||||
} // namespace saw
|
|
@ -10,7 +10,7 @@ dir_path = Dir('.').abspath
|
|||
env.test_sources = sorted(glob.glob(dir_path + "/*.cpp"))
|
||||
|
||||
env_test = env.Clone()
|
||||
env_test.Append(CPPDEFINES=['GIN_COMPILE_TEST_BINARY'])
|
||||
env_test.Append(CPPDEFINES=['SAW_COMPILE_TEST_BINARY'])
|
||||
env.test_objects = []
|
||||
env.test_sources.append(dir_path+'/suite/suite.cpp')
|
||||
env.test_headers = [dir_path + '/suite/suite.h']
|
||||
|
|
106
test/async.cpp
106
test/async.cpp
|
@ -1,10 +1,10 @@
|
|||
#include "suite/suite.h"
|
||||
|
||||
#include "source/kelgin/async.h"
|
||||
#include "source/forstio/async.h"
|
||||
|
||||
namespace {
|
||||
GIN_TEST("Async Immediate"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Immediate"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -19,13 +19,13 @@ GIN_TEST("Async Immediate"){
|
|||
|
||||
ErrorOr<bool> error_or_number = is_number.take();
|
||||
|
||||
GIN_EXPECT(!error_or_number.isError(), error_or_number.error().message());
|
||||
GIN_EXPECT(error_or_number.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(error_or_number.value(), "Value is not 5");
|
||||
SAW_EXPECT(!error_or_number.isError(), error_or_number.error().message());
|
||||
SAW_EXPECT(error_or_number.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(error_or_number.value(), "Value is not 5");
|
||||
}
|
||||
|
||||
GIN_TEST("Async Adapt"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Adapt"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -36,14 +36,14 @@ GIN_TEST("Async Adapt"){
|
|||
|
||||
ErrorOr<size_t> foo = feeder_conveyor.conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo.isError(), foo.error().message());
|
||||
GIN_EXPECT(foo.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo.value() == 5, "Values not 5, but " + std::to_string(foo.value()));
|
||||
SAW_EXPECT(!foo.isError(), foo.error().message());
|
||||
SAW_EXPECT(foo.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo.value() == 5, "Values not 5, but " + std::to_string(foo.value()));
|
||||
}
|
||||
|
||||
|
||||
GIN_TEST("Async Adapt Multiple"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Adapt Multiple"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -54,17 +54,17 @@ GIN_TEST("Async Adapt Multiple"){
|
|||
|
||||
ErrorOr<size_t> foo = feeder_conveyor.conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo.isError(), foo.error().message());
|
||||
GIN_EXPECT(foo.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo.value() == 5, "Values not 5, but " + std::to_string(foo.value()));
|
||||
SAW_EXPECT(!foo.isError(), foo.error().message());
|
||||
SAW_EXPECT(foo.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo.value() == 5, "Values not 5, but " + std::to_string(foo.value()));
|
||||
|
||||
feeder_conveyor.feeder->feed(10);
|
||||
|
||||
ErrorOr<size_t> bar = feeder_conveyor.conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo.isError(), bar.error().message());
|
||||
GIN_EXPECT(bar.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(bar.value() == 10, "Values not 10, but " + std::to_string(bar.value()));
|
||||
SAW_EXPECT(!foo.isError(), bar.error().message());
|
||||
SAW_EXPECT(bar.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(bar.value() == 10, "Values not 10, but " + std::to_string(bar.value()));
|
||||
|
||||
feeder_conveyor.feeder->feed(2);
|
||||
feeder_conveyor.feeder->feed(4234);
|
||||
|
@ -72,17 +72,17 @@ GIN_TEST("Async Adapt Multiple"){
|
|||
ErrorOr<size_t> a = feeder_conveyor.conveyor.take();
|
||||
ErrorOr<size_t> b = feeder_conveyor.conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo.isError(), a.error().message());
|
||||
GIN_EXPECT(a.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(a.value() == 2, "Values not 2, but " + std::to_string(a.value()));
|
||||
SAW_EXPECT(!foo.isError(), a.error().message());
|
||||
SAW_EXPECT(a.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(a.value() == 2, "Values not 2, but " + std::to_string(a.value()));
|
||||
|
||||
GIN_EXPECT(!foo.isError(), b.error().message());
|
||||
GIN_EXPECT(b.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(b.value() == 4234, "Values not 4234, but " + std::to_string(b.value()));
|
||||
SAW_EXPECT(!foo.isError(), b.error().message());
|
||||
SAW_EXPECT(b.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(b.value() == 4234, "Values not 4234, but " + std::to_string(b.value()));
|
||||
}
|
||||
|
||||
GIN_TEST("Async Conversion"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Conversion"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -97,13 +97,13 @@ GIN_TEST("Async Conversion"){
|
|||
|
||||
ErrorOr<std::string> foo = string_conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo.isError(), foo.error().message());
|
||||
GIN_EXPECT(foo.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo.value() == std::to_string(10), "Values is not 10, but " + foo.value());
|
||||
SAW_EXPECT(!foo.isError(), foo.error().message());
|
||||
SAW_EXPECT(foo.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo.value() == std::to_string(10), "Values is not 10, but " + foo.value());
|
||||
}
|
||||
|
||||
GIN_TEST("Async Conversion Multistep"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Conversion Multistep"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -122,13 +122,13 @@ GIN_TEST("Async Conversion Multistep"){
|
|||
|
||||
ErrorOr<bool> foo = conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo.isError(), foo.error().message());
|
||||
GIN_EXPECT(foo.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo.value(), "Values is not true");
|
||||
SAW_EXPECT(!foo.isError(), foo.error().message());
|
||||
SAW_EXPECT(foo.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo.value(), "Values is not true");
|
||||
}
|
||||
|
||||
GIN_TEST("Async Scheduling"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Scheduling"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -165,25 +165,25 @@ GIN_TEST("Async Scheduling"){
|
|||
|
||||
ErrorOr<std::string> foo_10 = string_conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo_10.isError(), foo_10.error().message());
|
||||
GIN_EXPECT(foo_10.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo_10.value() == (std::string{"pre"} + std::to_string(11) + std::string{"post"}), "Values is not pre11post, but " + foo_10.value());
|
||||
SAW_EXPECT(!foo_10.isError(), foo_10.error().message());
|
||||
SAW_EXPECT(foo_10.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo_10.value() == (std::string{"pre"} + std::to_string(11) + std::string{"post"}), "Values is not pre11post, but " + foo_10.value());
|
||||
|
||||
ErrorOr<std::string> foo_20 = string_conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo_20.isError(), foo_20.error().message());
|
||||
GIN_EXPECT(foo_20.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo_20.value() == (std::string{"pre"} + std::to_string(22) + std::string{"post"}), "Values is not pre22post, but " + foo_20.value());
|
||||
SAW_EXPECT(!foo_20.isError(), foo_20.error().message());
|
||||
SAW_EXPECT(foo_20.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo_20.value() == (std::string{"pre"} + std::to_string(22) + std::string{"post"}), "Values is not pre22post, but " + foo_20.value());
|
||||
|
||||
ErrorOr<std::string> foo_30 = string_conveyor.take();
|
||||
|
||||
GIN_EXPECT(!foo_30.isError(), foo_30.error().message());
|
||||
GIN_EXPECT(foo_30.isValue(), "Return is not a value");
|
||||
GIN_EXPECT(foo_30.value() == (std::string{"pre"} + std::to_string(33) + std::string{"post"}), "Values is not pre33post, but " + foo_30.value());
|
||||
SAW_EXPECT(!foo_30.isError(), foo_30.error().message());
|
||||
SAW_EXPECT(foo_30.isValue(), "Return is not a value");
|
||||
SAW_EXPECT(foo_30.value() == (std::string{"pre"} + std::to_string(33) + std::string{"post"}), "Values is not pre33post, but " + foo_30.value());
|
||||
}
|
||||
|
||||
GIN_TEST("Async Detach"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Detach"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -196,11 +196,11 @@ GIN_TEST("Async Detach"){
|
|||
|
||||
wait_scope.poll();
|
||||
|
||||
GIN_EXPECT(num == 10, std::string{"Bad value: Expected 10, but got "} + std::to_string(num));
|
||||
SAW_EXPECT(num == 10, std::string{"Bad value: Expected 10, but got "} + std::to_string(num));
|
||||
}
|
||||
|
||||
GIN_TEST("Async Merge"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Async Merge"){
|
||||
using namespace saw;
|
||||
|
||||
EventLoop event_loop;
|
||||
WaitScope wait_scope{event_loop};
|
||||
|
@ -224,7 +224,7 @@ GIN_TEST("Async Merge"){
|
|||
|
||||
wait_scope.poll();
|
||||
|
||||
GIN_EXPECT(!wrong_value, std::string{"Expected values 10 or 11"});
|
||||
GIN_EXPECT(elements_passed == 3, std::string{"Expected 2 passed elements, got only "} + std::to_string(elements_passed));
|
||||
SAW_EXPECT(!wrong_value, std::string{"Expected values 10 or 11"});
|
||||
SAW_EXPECT(elements_passed == 3, std::string{"Expected 2 passed elements, got only "} + std::to_string(elements_passed));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,20 +3,20 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "source/kelgin/message.h"
|
||||
#include "source/kelgin/schema.h"
|
||||
#include "source/forstio/message.h"
|
||||
#include "source/forstio/schema.h"
|
||||
|
||||
namespace {
|
||||
namespace schema {
|
||||
using namespace gin::schema;
|
||||
using namespace saw::schema;
|
||||
}
|
||||
|
||||
using TestTuple = schema::Tuple<schema::UInt32, schema::String>;
|
||||
|
||||
GIN_TEST("Message Tuple"){
|
||||
SAW_TEST("Message Tuple"){
|
||||
std::string test_string_1 = "banana";
|
||||
|
||||
auto root = gin::heapMessageRoot<TestTuple>();
|
||||
auto root = saw::heapMessageRoot<TestTuple>();
|
||||
auto builder = root.build();
|
||||
auto uint = builder.init<0>();
|
||||
uint.set(10);
|
||||
|
@ -27,16 +27,16 @@ GIN_TEST("Message Tuple"){
|
|||
auto uint_reader = reader.get<0>();
|
||||
auto string_reader = reader.get<1>();
|
||||
|
||||
GIN_EXPECT( uint_reader.get() == 10 && string_reader.get() == test_string_1, "wrong values");
|
||||
SAW_EXPECT( uint_reader.get() == 10 && string_reader.get() == test_string_1, "wrong values");
|
||||
}
|
||||
|
||||
using NestedTestTuple = schema::Tuple<schema::Tuple<schema::UInt32, schema::String>, schema::String>;
|
||||
|
||||
GIN_TEST("Message Tuple nested"){
|
||||
SAW_TEST("Message Tuple nested"){
|
||||
std::string test_string_1 = "banana";
|
||||
std::string test_string_2 = "bat";
|
||||
|
||||
auto root = gin::heapMessageRoot<NestedTestTuple>();
|
||||
auto root = saw::heapMessageRoot<NestedTestTuple>();
|
||||
auto builder = root.build();
|
||||
auto inner_list = builder.init<0>();
|
||||
auto uint = inner_list.init<0>();
|
||||
|
@ -53,7 +53,7 @@ GIN_TEST("Message Tuple nested"){
|
|||
auto inner_string_reader = inner_reader.get<1>();
|
||||
auto string_reader = root_reader.get<1>();
|
||||
|
||||
GIN_EXPECT(uint_reader.get() == 20 && inner_string_reader.get() == test_string_2 && string_reader.get() == test_string_1, "wrong values");
|
||||
SAW_EXPECT(uint_reader.get() == 20 && inner_string_reader.get() == test_string_2 && string_reader.get() == test_string_1, "wrong values");
|
||||
}
|
||||
|
||||
using TestStruct = schema::Struct<
|
||||
|
@ -62,9 +62,9 @@ using TestStruct = schema::Struct<
|
|||
schema::NamedMember<schema::String, "test_name">
|
||||
>;
|
||||
|
||||
GIN_TEST("Message Struct"){
|
||||
SAW_TEST("Message Struct"){
|
||||
std::string test_string = "foo";
|
||||
auto root = gin::heapMessageRoot<TestStruct>();
|
||||
auto root = saw::heapMessageRoot<TestStruct>();
|
||||
auto builder = root.build();
|
||||
auto uint = builder.init<"test_uint">();
|
||||
uint.set(23);
|
||||
|
@ -83,12 +83,12 @@ GIN_TEST("Message Struct"){
|
|||
*/
|
||||
test_string = "foo2";
|
||||
|
||||
GIN_EXPECT(uint_reader.get() == 23 && string_reader.get() != test_string && string_reader.get() == "foo" && name_reader.get() == "test_name", "Wrong values");
|
||||
SAW_EXPECT(uint_reader.get() == 23 && string_reader.get() != test_string && string_reader.get() == "foo" && name_reader.get() == "test_name", "Wrong values");
|
||||
}
|
||||
|
||||
using TestArray = schema::Array<schema::UInt32>;
|
||||
|
||||
void arrayCheck(gin::Message<TestArray>::Builder builder){
|
||||
void arrayCheck(saw::Message<TestArray>::Builder builder){
|
||||
auto one = builder.init(0);
|
||||
auto two = builder.init(1);
|
||||
auto three = builder.init(2);
|
||||
|
@ -99,11 +99,11 @@ void arrayCheck(gin::Message<TestArray>::Builder builder){
|
|||
|
||||
auto reader = builder.asReader();
|
||||
|
||||
GIN_EXPECT(reader.get(0).get() == 24 && reader.get(1).get() == 45 && reader.get(2).get(), "Wrong values");
|
||||
SAW_EXPECT(reader.get(0).get() == 24 && reader.get(1).get() == 45 && reader.get(2).get(), "Wrong values");
|
||||
}
|
||||
|
||||
GIN_TEST("Message Array"){
|
||||
auto root = gin::heapMessageRoot<TestArray>();
|
||||
SAW_TEST("Message Array"){
|
||||
auto root = saw::heapMessageRoot<TestArray>();
|
||||
|
||||
auto builder = root.build(3);
|
||||
|
||||
|
@ -114,8 +114,8 @@ using TestArrayStruct = schema::Struct<
|
|||
schema::NamedMember<TestArray, "array">
|
||||
>;
|
||||
|
||||
GIN_TEST("Message Array in Struct"){
|
||||
auto root = gin::heapMessageRoot<TestArrayStruct>();
|
||||
SAW_TEST("Message Array in Struct"){
|
||||
auto root = saw::heapMessageRoot<TestArrayStruct>();
|
||||
|
||||
auto builder = root.build();
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "suite/suite.h"
|
||||
|
||||
#include "source/kelgin/proto_kel.h"
|
||||
#include "source/forstio/proto_kel.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
namespace schema {
|
||||
using namespace gin::schema;
|
||||
using namespace saw::schema;
|
||||
}
|
||||
using TestSize = schema::UInt32;
|
||||
|
||||
|
@ -23,8 +23,8 @@ using TestUnion = schema::Union<
|
|||
schema::NamedMember<schema::String, "test_string">
|
||||
>;
|
||||
|
||||
GIN_TEST("Primitive Encoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Primitive Encoding"){
|
||||
using namespace saw;
|
||||
uint32_t value = 5;
|
||||
|
||||
auto root = heapMessageRoot<TestSize>();
|
||||
|
@ -37,14 +37,14 @@ GIN_TEST("Primitive Encoding"){
|
|||
|
||||
Error error = codec.encode<TestSize>(root.read(), temp_buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(temp_buffer.readCompositeLength() == (sizeof(value)+sizeof(msg_packet_length_t)), "Bad Size: " + std::to_string(temp_buffer.readCompositeLength()));
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(temp_buffer.readCompositeLength() == (sizeof(value)+sizeof(msg_packet_length_t)), "Bad Size: " + std::to_string(temp_buffer.readCompositeLength()));
|
||||
constexpr size_t pkt_shift = sizeof(msg_packet_length_t);
|
||||
GIN_EXPECT(temp_buffer[pkt_shift] == 5 && temp_buffer[pkt_shift+1] == 0 && temp_buffer[pkt_shift+2] == 0 && temp_buffer[pkt_shift+3] == 0, "Wrong encoded values");
|
||||
SAW_EXPECT(temp_buffer[pkt_shift] == 5 && temp_buffer[pkt_shift+1] == 0 && temp_buffer[pkt_shift+2] == 0 && temp_buffer[pkt_shift+3] == 0, "Wrong encoded values");
|
||||
}
|
||||
|
||||
GIN_TEST("List Encoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("List Encoding"){
|
||||
using namespace saw;
|
||||
|
||||
auto root = heapMessageRoot<TestTuple>();
|
||||
auto builder = root.build();
|
||||
|
@ -59,13 +59,13 @@ GIN_TEST("List Encoding"){
|
|||
|
||||
Error error = codec.encode<TestTuple>(root.read(), buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(buffer.readCompositeLength() == 14, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
GIN_EXPECT("06 00 00 00\n00 00 00 00\nbf 94 20 00\n5f ab" == buffer.toHex(), "Not equal encoding\n"+buffer.toHex());
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(buffer.readCompositeLength() == 14, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
SAW_EXPECT("06 00 00 00\n00 00 00 00\nbf 94 20 00\n5f ab" == buffer.toHex(), "Not equal encoding\n"+buffer.toHex());
|
||||
}
|
||||
|
||||
GIN_TEST("Struct Encoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Struct Encoding"){
|
||||
using namespace saw;
|
||||
|
||||
auto root = heapMessageRoot<TestStruct>();
|
||||
auto builder = root.build();
|
||||
|
@ -85,14 +85,14 @@ GIN_TEST("Struct Encoding"){
|
|||
|
||||
Error error = codec.encode<TestStruct>(builder.asReader(), buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(buffer.readCompositeLength() == 40, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
GIN_EXPECT("20 00 00 00\n00 00 00 00\n17 00 00 00\n03 00 00 00\n00 00 00 00\n66 6f 6f 09\n00 00 00 00\n00 00 00 74\n65 73 74 5f\n6e 61 6d 65"
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(buffer.readCompositeLength() == 40, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
SAW_EXPECT("20 00 00 00\n00 00 00 00\n17 00 00 00\n03 00 00 00\n00 00 00 00\n66 6f 6f 09\n00 00 00 00\n00 00 00 74\n65 73 74 5f\n6e 61 6d 65"
|
||||
== buffer.toHex(), "Not equal encoding:\n"+buffer.toHex());
|
||||
}
|
||||
|
||||
GIN_TEST("Union Encoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Union Encoding"){
|
||||
using namespace saw;
|
||||
{
|
||||
auto root = heapMessageRoot<TestUnion>();
|
||||
auto builder = root.build();
|
||||
|
@ -105,9 +105,9 @@ GIN_TEST("Union Encoding"){
|
|||
|
||||
Error error = codec.encode<TestUnion>(builder.asReader(), buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(buffer.readCompositeLength() == 16, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
GIN_EXPECT("08 00 00 00\n00 00 00 00\n00 00 00 00\n17 00 00 00"
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(buffer.readCompositeLength() == 16, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
SAW_EXPECT("08 00 00 00\n00 00 00 00\n00 00 00 00\n17 00 00 00"
|
||||
== buffer.toHex(), "Not equal encoding:\n"+buffer.toHex());
|
||||
}
|
||||
{
|
||||
|
@ -122,15 +122,15 @@ GIN_TEST("Union Encoding"){
|
|||
|
||||
Error error = codec.encode<TestUnion>(builder.asReader(), buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(buffer.readCompositeLength() == 23, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
GIN_EXPECT("0f 00 00 00\n00 00 00 00\n01 00 00 00\n03 00 00 00\n00 00 00 00\n66 6f 6f"
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(buffer.readCompositeLength() == 23, "Bad Size: " + std::to_string(buffer.readCompositeLength()));
|
||||
SAW_EXPECT("0f 00 00 00\n00 00 00 00\n01 00 00 00\n03 00 00 00\n00 00 00 00\n66 6f 6f"
|
||||
== buffer.toHex(), "Not equal encoding:\n"+buffer.toHex());
|
||||
}
|
||||
}
|
||||
|
||||
GIN_TEST("Tuple Decoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Tuple Decoding"){
|
||||
using namespace saw;
|
||||
const uint8_t buffer_raw[] = {0x06, 0, 0, 0, 0, 0, 0, 0, 0xbf, 0x94, 0x20, 0x00, 0x5f, 0xab};
|
||||
|
||||
RingBuffer buffer;
|
||||
|
@ -142,18 +142,18 @@ GIN_TEST("Tuple Decoding"){
|
|||
auto builder = root.build();
|
||||
|
||||
Error error = codec.decode<TestTuple>(builder, buffer);
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
|
||||
auto reader = builder.asReader();
|
||||
|
||||
auto first = reader.get<0>();
|
||||
auto second = reader.get<1>();
|
||||
|
||||
GIN_EXPECT(first.get() == 2135231 && second.get() == 43871, "Values not correctly decoded");
|
||||
SAW_EXPECT(first.get() == 2135231 && second.get() == 43871, "Values not correctly decoded");
|
||||
}
|
||||
|
||||
GIN_TEST("Struct Decoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Struct Decoding"){
|
||||
using namespace saw;
|
||||
const uint8_t buffer_raw[] = {0x20,0,0,0,0,0,0,0,0x17,0,0,0,0x03,0,0,0,0,0,0,0,0x66,0x6f,0x6f,0x09,0,0,0,0,0,0,0,0x74,0x65,0x73,0x74,0x5f,0x6e,0x61,0x6d,0x65};
|
||||
|
||||
RingBuffer buffer;
|
||||
|
@ -171,12 +171,12 @@ GIN_TEST("Struct Decoding"){
|
|||
auto test_uint = reader.get<"test_uint">();
|
||||
auto test_name = reader.get<"test_name">();
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(foo_string.get() == "foo" && test_uint.get() == 23 && test_name.get() == "test_name", "Values not correctly decoded");
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(foo_string.get() == "foo" && test_uint.get() == 23 && test_name.get() == "test_name", "Values not correctly decoded");
|
||||
}
|
||||
|
||||
GIN_TEST("Union Decoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Union Decoding"){
|
||||
using namespace saw;
|
||||
const uint8_t buffer_raw[] = {0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x6f,0x6f};
|
||||
|
||||
RingBuffer buffer;
|
||||
|
@ -190,18 +190,18 @@ GIN_TEST("Union Decoding"){
|
|||
|
||||
Error error = codec.decode<TestUnion>(builder, buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), error.message());
|
||||
GIN_EXPECT(reader.hasAlternative<"test_string">(), "Wrong union value");
|
||||
SAW_EXPECT(!error.failed(), error.message());
|
||||
SAW_EXPECT(reader.hasAlternative<"test_string">(), "Wrong union value");
|
||||
auto str_rd = reader.get<"test_string">();
|
||||
GIN_EXPECT(str_rd.get() == "foo", "Wrong value: " + std::string{str_rd.get()});
|
||||
SAW_EXPECT(str_rd.get() == "foo", "Wrong value: " + std::string{str_rd.get()});
|
||||
}
|
||||
|
||||
using TestArrayStruct = schema::Array<
|
||||
TestStruct
|
||||
>;
|
||||
|
||||
GIN_TEST("Array Encoding"){
|
||||
using namespace gin;
|
||||
SAW_TEST("Array Encoding"){
|
||||
using namespace saw;
|
||||
|
||||
ProtoKelCodec codec;
|
||||
auto root = heapMessageRoot<TestArrayStruct>();
|
||||
|
@ -222,6 +222,6 @@ GIN_TEST("Array Encoding"){
|
|||
|
||||
Error error = codec.encode<TestArrayStruct>(root.read(), buffer);
|
||||
|
||||
GIN_EXPECT(!error.failed(), "Error occured");
|
||||
SAW_EXPECT(!error.failed(), "Error occured");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
namespace test {
|
||||
|
||||
TestCase* testCaseHead = nullptr;
|
||||
|
@ -100,10 +100,10 @@ namespace test {
|
|||
}
|
||||
}
|
||||
|
||||
#if GIN_COMPILE_TEST_BINARY
|
||||
#if SAW_COMPILE_TEST_BINARY
|
||||
|
||||
int main() {
|
||||
gin::test::TestRunner runner;
|
||||
saw::test::TestRunner runner;
|
||||
runner.allowAll();
|
||||
int rv = runner.run();
|
||||
return rv<0?-1:0;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
namespace gin {
|
||||
namespace saw {
|
||||
namespace test {
|
||||
class TestRunner;
|
||||
class TestCase {
|
||||
|
@ -28,15 +28,15 @@ public:
|
|||
};
|
||||
}
|
||||
}
|
||||
#define GIN_TEST(description) \
|
||||
class GIN_UNIQUE_NAME(TestCase) : public ::gin::test::TestCase { \
|
||||
#define SAW_TEST(description) \
|
||||
class SAW_UNIQUE_NAME(TestCase) : public ::saw::test::TestCase { \
|
||||
public: \
|
||||
GIN_UNIQUE_NAME(TestCase)(): ::gin::test::TestCase(__FILE__,__LINE__,description) {} \
|
||||
SAW_UNIQUE_NAME(TestCase)(): ::saw::test::TestCase(__FILE__,__LINE__,description) {} \
|
||||
void run() override; \
|
||||
}GIN_UNIQUE_NAME(testCase); \
|
||||
void GIN_UNIQUE_NAME(TestCase)::run()
|
||||
}SAW_UNIQUE_NAME(testCase); \
|
||||
void SAW_UNIQUE_NAME(TestCase)::run()
|
||||
|
||||
#define GIN_EXPECT(expr, msg_split) \
|
||||
#define SAW_EXPECT(expr, msg_split) \
|
||||
if( ! (expr) ){ \
|
||||
auto msg = msg_split; \
|
||||
throw std::runtime_error{std::string{msg}};\
|
||||
|
|
Loading…
Reference in New Issue