# pragma once
# include <cassert>
# include <iostream>
# include <string>
# include <vector>
# include <filesystem>
# include <sys/mman.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include "cereal/messaging/messaging.h"
# include "cereal/messaging/event.h"
template < typename TSubSocket >
class FakeSubSocket : public TSubSocket {
private :
Event * recv_called = nullptr ;
Event * recv_ready = nullptr ;
EventState * state = nullptr ;
public :
FakeSubSocket ( ) : TSubSocket ( ) { }
~ FakeSubSocket ( ) {
delete recv_called ;
delete recv_ready ;
if ( state ! = nullptr ) {
munmap ( state , sizeof ( EventState ) ) ;
}
}
int connect ( Context * context , std : : string endpoint , std : : string address , bool conflate = false , bool check_endpoint = true ) override {
const char * cereal_prefix = std : : getenv ( " CEREAL_FAKE_PREFIX " ) ;
char * mem ;
std : : string identifier = cereal_prefix ! = nullptr ? std : : string ( cereal_prefix ) : " " ;
event_state_shm_mmap ( endpoint , identifier , & mem , nullptr ) ;
this - > state = ( EventState * ) mem ;
this - > recv_called = new Event ( state - > fds [ EventPurpose : : RECV_CALLED ] ) ;
this - > recv_ready = new Event ( state - > fds [ EventPurpose : : RECV_READY ] ) ;
return TSubSocket : : connect ( context , endpoint , address , conflate , check_endpoint ) ;
}
Message * receive ( bool non_blocking = false ) override {
if ( this - > state - > enabled ) {
this - > recv_called - > set ( ) ;
this - > recv_ready - > wait ( ) ;
this - > recv_ready - > clear ( ) ;
}
return TSubSocket : : receive ( non_blocking ) ;
}
} ;
class FakePoller : public Poller {
private :
std : : vector < SubSocket * > sockets ;
public :
void registerSocket ( SubSocket * socket ) override ;
std : : vector < SubSocket * > poll ( int timeout ) override ;
~ FakePoller ( ) { }
} ;