Files
integration/luprex/cpp/core/enginewrapper.hpp

243 lines
10 KiB
C++

////////////////////////////////////////////////////////////////////////////////
//
// enginewrapper.hpp
//
// This header file contains driver's interface to class DrivenEngine.
// This is meant to be used across a DLL boundary. Since the DLL may have
// been compiled by a different compiler than the driver, we use only simple
// POD types and we only use C calling conventions.
//
// When calling a wrapper function, you must always pass in the wrapper as
// the first parameter.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef ENGINEWRAPPER_H
#define ENGINEWRAPPER_H
#define DRV_MAX_CHAN 256
#define DRV_MAX_LISTEN_PORTS 256
#define DRV_ERRMSG_SIZE 8192
#define DRV_SHORTSTRING_SIZE 65536
class DrivenEngine;
class PlayLogfile;
class ReplayLogfile;
struct EngineWrapper {
char error[DRV_ERRMSG_SIZE];
char databuffer[DRV_SHORTSTRING_SIZE];
DrivenEngine *engine;
PlayLogfile *wlog;
ReplayLogfile *rlog;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// CONSTRUCTION
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Of course, there's no constructor, since this is a C struct.
// To initialize it, you use 'dlsym' or 'GetProcAddress' to get the
// address of the function 'init_engine_wrapper'. Then, you call
// the function init_engine_wrapper(&wrapper).
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// GETTERS
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Get a list of all the listening ports. The driver is expected
// to fetch this set shortly after the event_init callback is invoked.
//
void (*get_listen_ports)(EngineWrapper *w, uint32_t *nports, const uint32_t **ports);
// Get a list of all recently-opened channels that were created using
// new_outgoing_channel. The driver should initiate outgoing
// connections for these channels.
//
void (*get_new_outgoing)(EngineWrapper *w, uint32_t *nchanids, const uint32_t **chanids);
// Get a string_view of the target of a channel. A target is a string like
// "cert:whatever.com:80" or "nocert:whatever.com:80".
// The first word indicate whether or not a valid SSL certificate
// is required. The second word is the hostname. The third word is
// the port number. The char string returned here is valid until
// the channel is closed.
//
const char *(*get_target)(EngineWrapper *w, uint32_t chid);
// Return true if the user has released all references to this channel.
// In this case, the driver should initiate shutdown of the channel,
// and the driver should eventually call notify_close.
//
bool (*get_channel_released)(EngineWrapper *w, uint32_t chid);
// Get a pointer to the bytes in the outgoing buffer. The char pointer
// returned here is naturally only valid until the buffer is changed.
// This function is used for all channels, including sockets and stdio.
//
void (*get_outgoing)(EngineWrapper *w, uint32_t chid, uint32_t *len, const char **data);
// Return true if the outgoing buffer is empty.
//
bool (*get_outgoing_empty)(EngineWrapper *w, uint32_t chid);
// Get the clock.
//
// Get the current time. This is equal to the last value passed
// in by invoke_event_update.
//
double (*get_clock)(EngineWrapper *w);
// Check the 'rescan_lua_source' flag. If this flag is set, it means
// that the engine wants the driver to rescan the lua source code.
// When the driver sees this flag, it should rescan the source and call
// set_lua_source.
//
bool (*get_rescan_lua_source)(EngineWrapper *w);
// If true, the engine is done. Stop the driver.
//
bool (*get_stop_driver)(EngineWrapper *w);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// MUTATORS USED ONLY IN PLAY MODE
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Create the driven engine. argc and argv allow you to specify what
// kind of engine you want. You must pass in the initial state of the lua
// source, if you have any. You may optionally also specify a replay log.
// If you don't want to create a replay log, pass a null pointer.
//
// Check to see if the error buffer contains a message after calling
// this function.
//
void (*play_initialize)(EngineWrapper *w, uint32_t argc, char **argv, uint32_t srcpklen, const char *srcpk, const char *logfn);
// Clear the list of recently-opened channels. You are meant to fetch
// new outgoing channels using get_new_outgoing, then you call
// clear_new_outgoing after you've opened those channels.
//
void (*play_clear_new_outgoing)(EngineWrapper *w);
// Notifies the channel that some bytes were transmitted. This causes those
// bytes to be removed from the outgoing buffer. This function is used for
// all channels, including sockets and stdio.
//
void (*play_sent_outgoing)(EngineWrapper *w, uint32_t chid, uint32_t nbytes);
// Notifies the channel that some bytes were received. This causes those
// bytes to be appended to the incoming buffer. This function is used for
// all channels, including sockets and stdio.
//
void (*play_recv_incoming)(EngineWrapper *w, uint32_t chid, uint32_t len, const char *data);
// Notify the channel that the connection was closed. This includes all
// sorts of closes, including friendly termination, all the way to network
// failure. Closing the channel doesn't delete it. The engine is
// responsible for noticing that the channel closed and the engine must
// delete it. Closing a channel prevents it from showing up in
// 'list_channels'.
//
void (*play_notify_close)(EngineWrapper *w, uint32_t chid, uint32_t len, const char *data);
// Notify the DrivenEngine that somebody connected to an incoming port.
// This will cause the DrivenEngine to allocate a new channel and put the
// new channel into the incoming channels queue. Returns the new channel
// ID. The new incoming channel appears in the 'list_channels' list,
// even before the engine pops the channel from the incoming channels queue.
//
uint32_t (*play_notify_accept)(EngineWrapper *w, uint32_t port);
// Invoke the update event.
//
// The clock value must absolutely be monotonically increasing,
// and it should roughly be equal to the number of seconds since
// the program started.
//
void (*play_invoke_event_update)(EngineWrapper *w, double clock);
// Store the lua source code.
//
void (*play_set_lua_source)(EngineWrapper *w, uint32_t srcpklen, const char *srcpk);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// MUTATORS USED ONLY IN REPLAY MODE
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Begin a replay.
//
// Opens the logfile and prepares to replay the log.
// If an error occurs, the error buffer contains a message,
// and the done flag is set to true.
//
void (*replay_initialize)(EngineWrapper *w, const char *logfn);
// Execute a single step from the replay log.
//
// Calling this when 'done' is true is a no-op.
//
void (*replay_step)(EngineWrapper *w);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// CALLBACKS USED ONLY IN REPLAY MODE
//
// The driver can store function pointers here. If it does so, these
// functions will get called during replay_step operations.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void (*replay_cb_sent_outgoing)(void *vp, int chid, int nbytes, const char *data);
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// VOID POINTER USED IN REPLAY CALLBACKS
//
// The driver can store a void pointer here. This void pointer will get passed
// to all the replay callbacks.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void *replay_cb_vp;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// FUNCTIONS THAT CAN BE USED AT ANY TIME
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Restore the wrapper to its initial blank state.
//
// Note that the wrapper must have already been initialized using
// init_engine_wrapper. Otherwise, the 'release' function pointer would not
// be initialized. If writing a logfile, this stores a 'clean exit' marker
// in the logfile, indicating that the engine exited cleanly, as opposed to
// crashing.
//
// If the wrapper is already in its clear state, this is a no-op.
//
void (*release)(EngineWrapper *w);
};
#endif // ENGINEWRAPPER_HPP