@ -1,2 +0,0 @@ | |||
#pragma once | |||
@ -1,10 +0,0 @@ | |||
#pragma one | |||
#include <gp/array.hpp> | |||
#include <gp/iterator.hpp> | |||
#include <gp/integer_math.hpp> | |||
template<typename T, size_t depth> | |||
class flat_tree { | |||
gp::array<T, ((1 << depth) << 1) & 1> data_; | |||
}; |
@ -1,56 +0,0 @@ | |||
#pragma once | |||
#include "gp_config.hpp" | |||
#include "gp/exception.hpp" | |||
#include <type_traits> | |||
namespace gp{ | |||
template<class T, typename I = std::enable_if_t<gp_config::memory_module::is_ok,int>> | |||
class default_memory_allocator | |||
{ | |||
public: | |||
using pointer_type = T*; | |||
using reference_type = T&; | |||
using const_pointer_type = const T*; | |||
using const_reference_type = const T&; | |||
pointer_type allocate(size_t sz) | |||
{ | |||
return reinterpret_cast <pointer_type> (gp_config::memory_module::memory_allocator<gp_config::memory_module::memory_mode>(sizeof(T) * sz)); | |||
} | |||
void deallocate(pointer_type ptr) | |||
{ | |||
gp_config::memory_module::memory_deallocator<gp_config::memory_module::memory_mode>(ptr); | |||
} | |||
template<typename ...params> | |||
pointer_type construct(pointer_type ptr, params... args) | |||
{ | |||
new(ptr) T(args...); | |||
return ptr; | |||
} | |||
void destroy(pointer_type v) | |||
{ | |||
v->~T(); | |||
} | |||
}; | |||
} | |||
void* operator new(size_t sz) | |||
{ | |||
auto ptr = gp_config::memory_module::memory_allocator<gp_config::memory_module::memory_mode>(sz); | |||
if constexpr (gp_config::has_exceptions) | |||
{ | |||
if(!ptr) | |||
{ | |||
throw gp::bad_alloc{}; | |||
} | |||
} | |||
return ptr; | |||
} | |||
void operator delete (void* ptr) noexcept | |||
{ | |||
gp_config::memory_module::memory_deallocator<gp_config::memory_module::memory_mode>(ptr); | |||
} |
@ -1,26 +0,0 @@ | |||
#pragma once | |||
#include <stddef.h> | |||
#include <stdint.h> | |||
#include <gp/buffer.hpp> | |||
template<typename T> | |||
struct subtree_iterator final | |||
{ | |||
gp::buffer<T> target; | |||
size_t idx; | |||
public: | |||
subtree_iterator() | |||
: target{} | |||
, idx{0} | |||
{} | |||
subtree_iterator(gp::buffer<T> data, size_t itr_idx) | |||
: target{data} | |||
, idx{itr_idx} | |||
{} | |||
template<typename func> | |||
void climb_traversal(func& traverser) { | |||
} | |||
}; |
@ -1,2 +0,0 @@ | |||
#pragma once | |||
@ -1,142 +0,0 @@ | |||
#pragma once | |||
#include <stdint.h> | |||
#include <stddef.h> | |||
#include <gp/integer_math.hpp> | |||
#include <algorithm> | |||
#include <array> | |||
template<typename word_t = uint32_t, size_t r = 20, size_t b = 128, word_t P = 0xb7e15163L, word_t Q = 0x9e3779b9L> | |||
class RC6 { | |||
static constexpr size_t word_size = 8*sizeof(word_t); | |||
constexpr static word_t r_l(const word_t& w, size_t v) { | |||
return (w << v) | ( w >> (word_size-v)); | |||
} | |||
constexpr static word_t r_r(const word_t& w, size_t v) { | |||
return (w >> v) | ( w << (word_size-v)); | |||
} | |||
class RC6_KeySched { | |||
using sched_t = std::array<word_t, 2*r+4>; | |||
public: | |||
static constexpr size_t c = (b+word_size-1)/word_size; | |||
static constexpr size_t v_3 = std::max(c, 2*r+4); | |||
static constexpr size_t v = v_3*3; | |||
private: | |||
sched_t S; | |||
public: | |||
constexpr RC6_KeySched(std::array<word_t, c> L) | |||
{ | |||
assert(r_l(r_r(13,13),13) == 13); | |||
auto it = S.begin(); | |||
*(it++) = P; | |||
for(; it != S.end(); ++it) | |||
{ | |||
*it = *(it-1) + Q; | |||
} | |||
word_t A = 0; | |||
word_t B = 0; | |||
word_t i = 0; | |||
word_t j = 0; | |||
for(size_t s = 0; s < v; ++s) | |||
{ | |||
A = S[i] = r_l( S[i] + A + B, 3 ); | |||
B = L[j] = r_l( L[j] + A + B, (A + B)%(word_size)); | |||
i = s % S.size(); | |||
j = s % L.size(); | |||
} | |||
} | |||
const auto cbegin() | |||
{ | |||
return S.cbegin(); | |||
} | |||
const auto cend() | |||
{ | |||
return S.cend(); | |||
} | |||
const auto crbegin() | |||
{ | |||
return S.crbegin(); | |||
} | |||
const auto crend() | |||
{ | |||
return S.crend(); | |||
} | |||
}; | |||
RC6_KeySched S; | |||
public: | |||
typedef std::array<word_t, RC6_KeySched::c> key_type; | |||
typedef std::array<word_t, 4> block_type; | |||
constexpr RC6(const key_type& key) | |||
: S(key) | |||
{} | |||
constexpr block_type encrypt(block_type plaintext) { | |||
using namespace gp::math; | |||
auto& A = plaintext[0]; | |||
auto& B = plaintext[1]; | |||
auto& C = plaintext[2]; | |||
auto& D = plaintext[3]; | |||
auto it = S.cbegin(); | |||
B += *(it++); | |||
D += *(it++); | |||
for(size_t i = 0; i < r; ++i) | |||
{ | |||
auto u = r_l( D * ( 2 * D + 1 ), msb(word_size)); | |||
auto t = r_l( B * ( 2 * B + 1 ), msb(word_size)); | |||
A = r_l((A ^ t), u % word_size) + *(it++); | |||
C = r_l((C ^ u), t % word_size) + *(it++); | |||
std::rotate(plaintext.begin(), plaintext.begin()+1, plaintext.end()); | |||
} | |||
A += *(it++); | |||
C += *(it++); | |||
assert(it == S.cend()); | |||
return plaintext; | |||
} | |||
constexpr block_type decrypt(block_type plaintext) { | |||
using namespace gp::math; | |||
auto& A = plaintext[0]; | |||
auto& B = plaintext[1]; | |||
auto& C = plaintext[2]; | |||
auto& D = plaintext[3]; | |||
auto it = S.crbegin(); | |||
C -= *(it++); | |||
A -= *(it++); | |||
for(size_t i = 0; i < r; ++i) | |||
{ | |||
std::rotate(plaintext.begin(), plaintext.end()-1, plaintext.end()); | |||
auto u = r_l( D * ( 2 * D + 1 ), msb(word_size)); | |||
auto t = r_l( B * ( 2 * B + 1 ), msb(word_size)); | |||
C = r_r( (C - *(it++)) , t % word_size) ^ u ; | |||
A = r_r( (A - *(it++)) , u % word_size) ^ t ; | |||
} | |||
D -= *(it++); | |||
B -= *(it++); | |||
assert(it == S.crend()); | |||
return plaintext; | |||
} | |||
}; |
@ -1,2 +0,0 @@ | |||
#pragma once | |||
@ -1,381 +0,0 @@ | |||
#pragma once | |||
#include <fcntl.h> | |||
#include <unistd.h> | |||
#include <sys/mman.h> | |||
#include <sys/stat.h> | |||
#include <sys/types.h> | |||
#include <sys/socket.h> | |||
#include <netinet/in.h> | |||
#include <sys/un.h> | |||
#include <string> | |||
#include <sstream> | |||
#include <atomic> | |||
#include <array> | |||
#include <variant> | |||
#include <cassert> | |||
namespace gp{ | |||
using open_opt_flags = int; | |||
enum class open_options : open_opt_flags { | |||
append = O_APPEND, | |||
create = O_CREAT, | |||
async = O_ASYNC, | |||
direct = O_DIRECT, | |||
data_sync = O_DSYNC, | |||
file_sync = O_SYNC, | |||
exclusive = O_EXCL, | |||
no_access_time = O_NOATIME, | |||
no_follow = O_NOFOLLOW, | |||
read = O_RDONLY, | |||
write = O_WRONLY, | |||
#ifdef O_TEMP | |||
temporary = O_TEMP, | |||
#endif | |||
#ifdef O_TRUC | |||
truncate = O_TRUC, | |||
#endif | |||
}; | |||
using open_opt_mode = int; | |||
enum class open_modes : open_opt_mode { | |||
user_read = S_IRUSR, | |||
user_write = S_IWUSR, | |||
user_exec = S_IXUSR, | |||
group_read = S_IRGRP, | |||
group_write = S_IWGRP, | |||
group_exec = S_IXGRP, | |||
other_read = S_IROTH, | |||
other_write = S_IWOTH, | |||
other_exec = S_IXOTH, | |||
set_uid = S_ISUID, | |||
set_gid = S_ISGID, | |||
sticky_bit = S_ISVTX, | |||
}; | |||
enum class socket_domain : int { | |||
ip4 = AF_INET, | |||
ip6 = AF_INET6, | |||
unix = AF_UNIX | |||
}; | |||
enum class socket_protocol : int { | |||
tcp_like = SOCK_STREAM, | |||
udp_like = SOCK_DGRAM | |||
}; | |||
using socket_opt_flags = int; | |||
enum class net_socket_opt_flags : socket_opt_flags { | |||
non_blocking = SOCK_NONBLOCK, | |||
close_on_exec = SOCK_CLOEXEC, | |||
}; | |||
using socket_opt_flags = int; | |||
enum class unix_socket_opt_flags : socket_opt_flags { | |||
non_blocking = SOCK_NONBLOCK, | |||
close_on_exec = SOCK_CLOEXEC, | |||
}; | |||
using address = std::variant<sockaddr_in, sockaddr_in6, sockaddr_un>; | |||
template<typename T> | |||
struct stream_expect{ | |||
const T v; | |||
stream_expect(T value) | |||
: v(value) | |||
{} | |||
}; | |||
template<typename T> | |||
std::istream& operator>>(std::istream& in, const stream_expect<T>& expector) | |||
{ | |||
T vin; | |||
in >> vin; | |||
if(vin != expector.v) | |||
throw std::runtime_error("Expector failed"); | |||
return in; | |||
} | |||
address make_ipv4(const std::string_view addr, const uint16_t port) | |||
{ | |||
std::stringstream din; | |||
din<<addr; | |||
std::array<uint8_t, 4> address{0}; | |||
int ex; | |||
din>>ex | |||
>>stream_expect<char>('.'); | |||
address[0]=ex; | |||
din>>ex | |||
>>stream_expect<char>('.'); | |||
address[1]=ex; | |||
din>>ex | |||
>>stream_expect<char>('.'); | |||
address[2]=ex; | |||
din>>ex; | |||
address[3]=ex; | |||
sockaddr_in ret; | |||
in_addr ret_addr; | |||
ret_addr.s_addr = *((uint32_t*)&address); | |||
ret.sin_family = AF_INET; | |||
ret.sin_addr = ret_addr; | |||
ret.sin_port = htons(port); | |||
return ret; | |||
} | |||
// TODO: make an IPv6 parser | |||
//address make_ipv6(const std::string_view addr, const uint16_t port){} | |||
address make_unix(const std::string_view filename) | |||
{ | |||
sockaddr_un ret; | |||
if(filename.size()>(sizeof(ret.sun_path)-1)) | |||
throw std::runtime_error("Filename too long"); | |||
ret.sun_family = AF_UNIX; | |||
*std::copy(filename.begin(), filename.end(), ret.sun_path) = '\0'; | |||
return ret; | |||
} | |||
class shared_fd { | |||
int fd; | |||
std::atomic_int* guard; | |||
int last_error; | |||
shared_fd(int fd_v) | |||
: fd(fd_v) | |||
, guard(new std::atomic_int{1}) | |||
, last_error(0) | |||
{} | |||
public: | |||
shared_fd() | |||
: fd(-1) | |||
, guard(nullptr) | |||
, last_error(0) | |||
{} | |||
shared_fd(const shared_fd& oth) | |||
: fd(oth.fd) | |||
, guard(oth.guard) | |||
, last_error(0) | |||
{ | |||
if(guard) | |||
guard->fetch_add(1, std::memory_order_acq_rel); | |||
} | |||
shared_fd(shared_fd&& oth) | |||
: last_error(0) | |||
{ | |||
fd=oth.fd; | |||
guard=oth.guard; | |||
oth.fd=-1; | |||
oth.guard=nullptr; | |||
} | |||
const int get() const { | |||
return fd; | |||
} | |||
void operator=(const shared_fd& oth) | |||
{ | |||
this->~shared_fd(); | |||
fd = oth.fd; | |||
guard = oth.guard; | |||
if(guard) | |||
guard->fetch_add(1, std::memory_order_acq_rel); | |||
} | |||
void operator=(shared_fd&& oth) | |||
{ | |||
std::swap(fd,oth.fd); | |||
std::swap(guard,oth.guard); | |||
} | |||
static shared_fd open(const std::string& filename, const open_opt_flags& flags, const open_opt_mode& mode = 0) | |||
{ | |||
shared_fd ret{::open(filename.c_str(), flags, mode)}; | |||
return ret; | |||
} | |||
static shared_fd create(const std::string& filename, const open_opt_mode& mode) | |||
{ | |||
shared_fd ret{::creat(filename.c_str(), mode)}; | |||
return ret; | |||
} | |||
static shared_fd tcp_socket() | |||
{ | |||
shared_fd ret; | |||
auto res = ::socket(AF_INET, SOCK_STREAM, 0); | |||
if(res >= 0) | |||
{ | |||
ret = shared_fd{res}; | |||
fcntl(res, F_SETFL, O_NONBLOCK); | |||
} | |||
else | |||
ret.last_error = errno; | |||
return ret; | |||
} | |||
static shared_fd socket(const socket_domain& dom, const socket_protocol& proto)//, const net_socket_opt_flags& flags) | |||
{ | |||
shared_fd ret; | |||
auto res = ::socket((int)dom, (int)proto, (int)0); | |||
if(res >= 0) | |||
{ | |||
ret = shared_fd{res}; | |||
} | |||
else | |||
ret.last_error = errno; | |||
return ret; | |||
} | |||
static shared_fd unix_socket(const socket_protocol& proto, const socket_opt_flags flags) { | |||
shared_fd ret; | |||
auto res = ::socket((int)AF_UNIX, (int)proto, (int)flags); | |||
if(res >= 0) | |||
ret = shared_fd{res}; | |||
return ret; | |||
} | |||
static std::pair<shared_fd,shared_fd> unix_socket_pair(const socket_protocol& proto, const net_socket_opt_flags flags) { | |||
std::pair<gp::shared_fd, gp::shared_fd> ret; | |||
int fds[2]; | |||
auto result = ::socketpair((int)AF_UNIX, (int)proto, (int)flags, fds); | |||
if(result != 0) | |||
return ret; | |||
ret.first = shared_fd(fds[0]); | |||
ret.second = shared_fd(fds[1]); | |||
return ret; | |||
} | |||
bool is_valid() const { | |||
return guard && (fd>=0); | |||
} | |||
bool has_failed() const { | |||
return last_error; | |||
} | |||
bool was_connection_refused() const { | |||
return last_error==ECONNREFUSED; | |||
} | |||
bool in_progress() const { | |||
return last_error==EINPROGRESS; | |||
} | |||
bool must_retry() const { | |||
return last_error==EAGAIN; | |||
} | |||
int error() const { | |||
return last_error; | |||
} | |||
void bind(const address& addr) | |||
{ | |||
int ret; | |||
std::visit([&](const auto& v){ | |||
ret = ::bind(fd, (struct sockaddr*)&v, sizeof(v)); | |||
}, addr); | |||
if(ret==0) | |||
{ | |||
last_error = 0; | |||
return; | |||
} | |||
else | |||
last_error = errno; | |||
} | |||
void connect(const address& addr) | |||
{ | |||
int ret; | |||
std::visit([&](const auto& v){ | |||
ret = ::connect(fd, (struct sockaddr*)&v, sizeof(v)); | |||
}, addr); | |||
if(ret!=0) | |||
{ | |||
last_error = errno; | |||
return; | |||
} | |||
last_error = 0; | |||
} | |||
void listen(const int& backlog = 16) | |||
{ | |||
int ret = 0; | |||
std::visit([&](){ | |||
ret = ::listen(fd, backlog); | |||
}); | |||
if(ret!=0) | |||
{ | |||
last_error = errno; | |||
return; | |||
} | |||
last_error = 0; | |||
} | |||
shared_fd accept() | |||
{ | |||
int ret = 0; | |||
std::array<uint8_t, 256> buffer; | |||
socklen_t len; | |||
ret = ::accept(fd,(sockaddr*)buffer.begin(), &len); | |||
if(ret!=0) | |||
{ | |||
last_error = errno; | |||
return shared_fd{}; | |||
} | |||
last_error = 0; | |||
return shared_fd{ret}; | |||
} | |||
std::string_view read(const std::string_view buffer) | |||
{ | |||
int sz = ::read(fd, (void*)(buffer.begin()), buffer.size()); | |||
if(sz<0) | |||
last_error = errno; | |||
else | |||
last_error = 0; | |||
sz = sz<0?0:sz; | |||
return std::string_view(buffer.begin(), sz); | |||
} | |||
std::string_view write(const std::string_view buffer) | |||
{ | |||
int sz = ::write(fd, (void*)(buffer.begin()), buffer.size()); | |||
if(sz<0) | |||
last_error = errno; | |||
else | |||
last_error = 0; | |||
sz = sz<0?0:sz; | |||
return std::string_view(buffer.begin()+sz, buffer.size()-sz); | |||
} | |||
~shared_fd() | |||
{ | |||
if(guard) | |||
if(guard->fetch_sub(1, std::memory_order_acq_rel) == 1) | |||
{ | |||
assert(guard->load() == 0); | |||
assert(fd >= 0); | |||
delete guard; | |||
guard = nullptr; | |||
if(fd >= 0) | |||
{ | |||
::close(fd); | |||
} | |||
} | |||
} | |||
}; | |||
} |
@ -1,2 +0,0 @@ | |||
#pragma once | |||
@ -1 +0,0 @@ | |||
#pragma once |
@ -1,2 +0,0 @@ | |||
#pragma once | |||
@ -1,2 +0,0 @@ | |||
#pragma once | |||
@ -1 +0,0 @@ | |||
#pragma once |
@ -1,88 +0,0 @@ | |||
#include "rc6_generic.hpp" | |||
#include "test_scaffold.h" | |||
#include <iostream> | |||
#include <ios> | |||
struct RC6test : public test_scaffold { | |||
RC6test() { | |||
name = __FILE__ ":1"; | |||
} | |||
virtual int run() { | |||
using rc = RC6<>; | |||
rc::key_type key = {0,0,0,0}; | |||
rc::block_type plaintext = {0,0,0,0}; | |||
rc::block_type expected = {0x8fc3a536,0x56b1f778,0xc129df4e,0x9848a41e}; | |||
/* | |||
std::cout<<"plain:"; | |||
for(auto a : plaintext) | |||
std::cout << std::hex << a; | |||
*/ | |||
auto cipher = rc{key}; | |||
plaintext = cipher.encrypt(plaintext); | |||
/*std::cout<<"\nkey__:"; | |||
for(auto a : key) | |||
std::cout << std::hex << a; | |||
std::cout<<"\nciphe:"; | |||
for(auto a : plaintext) | |||
std::cout << std::hex << a; | |||
std::cout<<"\nexpec:"; | |||
for(auto a : expected) | |||
std::cout << std::hex << a; | |||
std::cout << std::endl; | |||
*/ | |||
return plaintext != expected; | |||
} | |||
}; | |||
append_test dummy_szfhu5463(new RC6test{}); | |||
struct RC6test2 : public test_scaffold { | |||
RC6test2() { | |||
name = __FILE__ ":2"; | |||
} | |||
virtual int run() { | |||
using rc = RC6<>; | |||
rc::key_type key = {0,0,0,0}; | |||
rc::block_type plaintext = {0,0,0,0}; | |||
rc::block_type expected = {0,0,0,0}; | |||
/* | |||
std::cout<<"plain:"; | |||
for(auto a : plaintext) | |||
std::cout << std::hex << a; | |||
*/ | |||
auto cipher = rc{key}; | |||
plaintext = cipher.encrypt(plaintext); | |||
/*std::cout<<"\nkey__:"; | |||
for(auto a : key) | |||
std::cout << std::hex << a; | |||
std::cout<<"\nciphe:"; | |||
for(auto a : plaintext) | |||
std::cout << std::hex << a; | |||
*/ | |||
plaintext = cipher.decrypt(plaintext); | |||
/*std::cout<<"\ncidec:"; | |||
for(auto a : plaintext) | |||
std::cout << std::hex << a; | |||
std::cout<<"\nexpec:"; | |||
for(auto a : expected) | |||
std::cout << std::hex << a; | |||
std::cout << std::endl; | |||
*/ | |||
return plaintext != expected; | |||
} | |||
}; | |||
append_test dummy_szmltz63(new RC6test2{}); |
@ -1,286 +0,0 @@ | |||
#include "shared_fd.hpp" | |||
#include "test_scaffold.h" | |||
#include <thread> | |||
#include <chrono> | |||
#include <iostream> | |||
#include <iomanip> | |||
struct create_test : public test_scaffold { | |||
create_test() { | |||
name = __FILE__ ":1"; | |||
} | |||
virtual int run() { | |||
auto fd = gp::shared_fd::create("./bin/test_n", int(gp::open_modes::user_read) | int(gp::open_modes::user_write)); | |||
return fd.is_valid()?0:1; | |||
} | |||
}; | |||
append_test dummy_sdfhuisd3(new create_test{}); | |||
struct open_test : public test_scaffold { | |||
open_test() { | |||
name = __FILE__ ":2"; | |||
} | |||
virtual int run() { | |||
auto fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::append)); | |||
return fd.is_valid()?0:1; | |||
} | |||
}; | |||
append_test dummy_sdf564dd3(new open_test{}); | |||
struct manip_test : public test_scaffold { | |||
manip_test() { | |||
name = __FILE__ ":3"; | |||
} | |||
virtual int run() { | |||
auto fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::append)); | |||
int error = fd.is_valid()?0:1; | |||
error += !(fd.get()>=0); | |||
auto fd_cpy = fd; | |||
error += fd_cpy.is_valid()?0:1; | |||
gp::shared_fd constr_cpy(fd_cpy); | |||
error += constr_cpy.is_valid()?0:1; | |||
gp::shared_fd constr_mv(std::move(constr_cpy)); | |||
error += constr_mv.is_valid()?0:1; | |||
gp::shared_fd assign_cpy; | |||
assign_cpy.operator=(fd_cpy); | |||
error += assign_cpy.is_valid()?0:1; | |||
gp::shared_fd assign_mv; | |||
assign_mv.operator=(std::move(assign_cpy)); | |||
error += assign_mv.is_valid()?0:1; | |||
error += (!assign_cpy.is_valid())?0:1; | |||
return error; | |||
} | |||
}; | |||
append_test dummy_lkjs64dd3(new manip_test{}); | |||
struct rw_test : public test_scaffold { | |||
rw_test() { | |||
name = __FILE__ ":4"; | |||
} | |||
virtual int run() { | |||
auto fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::write)); | |||
int error = fd.is_valid()?0:1; | |||
fd.write("potatoes"); | |||
error += fd.has_failed(); | |||
fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::read)); | |||
std::array<char,8> buffer; | |||
auto str = fd.read(std::string_view(buffer.begin(), buffer.size())); | |||
error += fd.has_failed(); | |||
error += (str != "potatoes"); | |||
return error; | |||
} | |||
}; | |||
append_test dummy_l6z5e4rdd3(new rw_test{}); | |||
struct rw_err_test : public test_scaffold { | |||
rw_err_test() { | |||
name = __FILE__ ":5"; | |||
} | |||
virtual int run() { | |||
auto fd = gp::shared_fd::create("./bin/test_n", int(gp::open_modes::user_read) | int(gp::open_modes::user_write)); | |||
fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::read)); | |||
int error = fd.is_valid()?0:1; | |||
fd.write("potatoes"); | |||
error += fd.has_failed(); | |||
fd = gp::shared_fd::open("./bin/test_n", int(gp::open_options::write)); | |||
error += fd.is_valid()?0:1; | |||
std::array<char,8> buffer; | |||
auto str = fd.read(std::string_view(buffer.begin(), buffer.size())); | |||
error += fd.has_failed(); | |||
return error == 2 ? 0 : 1; | |||
} | |||
}; | |||
append_test dummy_l6987erd3(new rw_err_test{}); | |||
/* | |||
struct make_address_test : public test_scaffold { | |||
make_address_test() { | |||
name = __FILE__ ":6"; | |||
} | |||
virtual int run() { | |||
int error = 0; | |||
gp::address ipv4 = gp::make_ipv4("127.0.0.1", 0x1234); | |||
auto p = std::get<sockaddr_in>(ipv4); | |||
error += (p.sin_family != AF_INET); | |||
error += (p.sin_addr.s_addr != htonl(0x7F000001)); | |||
error += (p.sin_port != htons(0x1234)); | |||
try{ | |||
gp::make_ipv4("not an IP", 1234); | |||
error += 1; | |||
}catch(...){} | |||
std::string filename = "/tmp/my_socket"; | |||
gp::address unix = gp::make_unix(filename); | |||
auto q = std::get<sockaddr_un>(unix); | |||
error += (q.sun_family != AF_UNIX); | |||
error += strcmp(filename.c_str(), q.sun_path); | |||
try{ | |||
std::string long_str(1024, 'p'); | |||
gp::make_unix(long_str); | |||
error += 1; | |||
}catch(...){} | |||
return error; | |||
} | |||
}; | |||
append_test dummy_l6923ml3(new make_address_test{}); | |||
struct sockets_test : public test_scaffold { | |||
sockets_test() { | |||
name = __FILE__ ":7"; | |||
} | |||
virtual int run() { | |||
int error = 0; | |||
auto v = gp::shared_fd::socket(gp::socket_domain::ip4, gp::socket_protocol::tcp_like); | |||
error += !(v.is_valid()); | |||
v = gp::shared_fd::socket(gp::socket_domain::ip4, gp::socket_protocol::tcp_like); | |||
error += !(v.is_valid()); | |||
auto pair_v = gp::shared_fd::unix_socket_pair(gp::socket_protocol::tcp_like, (gp::net_socket_opt_flags)0); | |||
error += !(pair_v.first.is_valid()); | |||
error += !(pair_v.second.is_valid()); | |||
pair_v = gp::shared_fd::unix_socket_pair(gp::socket_protocol::tcp_like, (gp::net_socket_opt_flags)-1); | |||
error += pair_v.first.is_valid(); | |||
error += pair_v.second.is_valid(); | |||
auto u_v = gp::shared_fd::unix_socket(gp::socket_protocol::tcp_like, (gp::socket_opt_flags)0); | |||
error += !(u_v.is_valid()); | |||
u_v = gp::shared_fd::unix_socket(gp::socket_protocol::tcp_like, (gp::socket_opt_flags)-1); | |||
error += u_v.is_valid(); | |||
return error; | |||
} | |||
}; | |||
append_test dummy_r3321443(new sockets_test{}); | |||
using namespace std::chrono_literals; | |||
struct sockets_co_test : public test_scaffold { | |||
sockets_co_test() { | |||
name = __FILE__ ":8"; | |||
} | |||
virtual int run() { | |||
std::atomic_int error = 0; | |||
{ | |||
auto v2 = gp::shared_fd::tcp_socket(); | |||
error += !(v2.is_valid()); | |||
std::thread sside([&](){ | |||
auto v1 = gp::shared_fd::tcp_socket(); | |||
v1.bind(gp::make_ipv4("0.0.0.0",1235)); | |||
error += v1.has_failed(); | |||
v1.listen(); | |||
std::cout << "listens?:" << v1.is_valid()<<std::endl; | |||
error += !(v1.is_valid()); | |||
gp::shared_fd listener = v1; | |||
gp::shared_fd v3; | |||
do | |||
{ | |||
v3 = listener.accept(); | |||
std::this_thread::sleep_for(500ms); | |||
std::cout << "accept_attempt:" << v3.error()<<std::endl; | |||
}while(listener.must_retry()); | |||
puts("accepted"); | |||
error += !(listener.has_failed()); | |||
do | |||
{ | |||
v3.write("potatoes"); | |||
std::this_thread::sleep_for(1ms); | |||
}while(v3.must_retry()); | |||
puts("sent"); | |||
error += !(v3.has_failed()); | |||
return; | |||
}); | |||
std::this_thread::sleep_for(6ms); | |||
v2.connect(gp::make_ipv4("255.255.255.255",1235)); | |||
error += v2.has_failed(); | |||
do{ | |||
v2.connect(gp::make_ipv4("127.0.0.1",1235)); | |||
std::this_thread::sleep_for(500ms); | |||
std::cout << "connect_attempt:" << v2.is_valid() << " with " << v2.error()<<std::endl; | |||
}while(v2.error() != EISCONN); | |||
std::this_thread::sleep_for(1ms); | |||
auto status = v2.was_connection_refused(); | |||
error += status; | |||
if(!status) | |||
{ | |||
puts("connected"); | |||
std::array<char, 32> buffer; | |||
std::string_view retstr; | |||
do | |||
{ | |||
retstr = v2.read(std::string_view(buffer.begin(), buffer.size())); | |||
std::this_thread::sleep_for(1ms); | |||
} | |||
while(v2.must_retry()); | |||
puts("received"); | |||
std::cout<< "out:" << std::quoted(retstr) << std::endl; | |||
error += !(v2.has_failed()); | |||
error += retstr != "potatoes"; | |||
if(sside.joinable()) | |||
sside.join(); | |||
} | |||
return error; | |||
} | |||
return error; | |||
} | |||
}; | |||
// append_test dummy_polmdf43(new sockets_co_test{}); | |||
*/ |