
Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы / 2 / lab.01.by mice / fexchange / fx_core
.h/*******************************************************************************
* file: fx_core.h *
* version: 0.3.0 *
* author: d-evil [tmd] (mailto:d-evil.tmd@mail.ru) *
* description: fexchange core and core interface *
* interfaces can use only information based on this file and *
* must not make any assumptions about any part of realization *
* *
* most of integer constants are unique *
* cfx_if class uses integer constants in range [1000, 9999] *
* the next principle used to group the integers: *
* [1000,1499] - commands for ui *
* [1500,1999] - commands for core *
* [2000,2099] - states of server *
* [2100,2199] - states of client *
* [3000,3499] - errors returned from core to ui *
* [3500,3999] - errors returned from ui to core *
* *
*******************************************************************************/
#ifndef FX_CORE_INCLUDED
#define FX_CORE_INCLUDED
////////////////////////////////////////////////////////////////////////////////
// for correct linkage order
#include <afx.h>
////////////////////////////////////////////////////////////////////////////////
// OS depended headers
#include <winsock2.h>
////////////////////////////////////////////////////////////////////////////////
// program specific headers
#include "fx_net.h"
namespace fx_ns {
/*******************************************************************************
* declarations *
*******************************************************************************/
union sfx_data {
short s;
unsigned short us;
int i;
unsigned int ui;
void *p;
sfx_data(): p(NULL) {}
sfx_data(short sv) { s = sv; }
sfx_data(unsigned short usv) { us = usv; }
sfx_data(int iv) { i = iv; }
sfx_data(unsigned int uiv) { ui = uiv; }
sfx_data(void *pv) { p = pv; }
operator short() const { return s; }
operator unsigned short() const { return us; }
operator int() const { return i; }
operator unsigned int() const { return ui; }
operator void *() const { return p; }
template<class T> operator T *() const { return (T *)p; }
};
////////////////////////////////////////////////////////////////////////////////
// cfx_if (declaration)
class cfx_core;
class cfx_if {
public:
////////////////////////////////////////////////////////////////////////////
// types
struct sfx_addr_info {
char *host;
char *addres;
unsigned short port;
short family;
};
struct sfx_crserv_info {
char *address;
unsigned short port;
};
struct sfx_sndfile_info {
char *file_name;
char *address;
unsigned short port;
};
struct sfx_serv_item {
sfx_addr_info addr;
int state;
sfx_data if_time; // interface can freely use (modify) this field
sfx_data if_data; // interface can freely use (modify) this field
sfx_serv_item *prev;
sfx_serv_item *next;
};
struct sfx_clnt_item {
sfx_addr_info addr;
int state;
char *file_name;
unsigned int total_sz;
unsigned int done_sz;
sfx_data if_time; // interface can freely use (modify) this field
sfx_data if_data; // interface can freely use (modify) this field
sfx_clnt_item *prev;
sfx_clnt_item *next;
};
////////////////////////////////////////////////////////////////////////////
// interface commands
// interfaces must return ERC_NO_CMDSUPPORT if command not supported
// ldata and rdata and returned value are sfx_data
// i - int
// ui - unsigned int
// p - void *
// s - short
// us - unsigend short
// command: CMD_NONE
// about: tests UI for connection
// ldata[p]: not used (must be NULL)
// rdata[p]: not used (must be NULL)
// return[i]: must return OK_OK, otherwise UI will be detached
static const int CMD_NONE = 1000;
// command: CMD_INVALID_CMD
// about: used for debuging
// ldata[p]: not used (must be NULL)
// rdata[p]: not used (must be NULL)
// return[i]: must return ERC_NO_CMDSUPPORT
static const int CMD_INVALID_CMD = 1001;
// command: CMD_ERROR_REPORT
// about: error message from core
// ldata[i]: fx error id (ERC_ERROR if unknown error)
// rdata[i]: windows error code (0 if not available)
// return[i]: error code (OK_OK on success)
static const int CMD_ERROR_REPORT = 1010;
// command: CMD_ASK_ACCEPTIC
// about: ask to accept incoming connection
// ldata[i]: pointer to sfx_addr_info structure
// rdata[p]: not used (must be NULL)
// result[i]: OK_OK on "ok", OK_CANCEL on "cancel" or error code
static const int CMD_ASK_ACCEPTIC = 1020;
// Command: CMD_ASK_FILENAME
// about: ask for file name (to read from or write to)
// ldata[i]: pointer to cfx_askfile_struct
// rdata[p]: pointer to int to receive file name length
// result[i]: OK_OK if "yes"
// OK_CANCEL if "no"
// OK_REPEAT if "yes" and buffer is too short
static const int CMD_ASK_FILENAME = 1021;
static const int CMD_ASKFN_OPEN = 0x01;
static const int CMD_ASKFN_MSTEX = 0x02; // file must exists
static const int CMD_ASKFN_OVWRITE = 0x04; // file will be cleaned
struct cfx_askfile_struct {
char *init_fname; // initial file name
char *buf; // buffer for file name
int buf_sz; // buffer size
int flags; // flags
};
// command: CMD_US_NEW
// about: update servers list (add new server)
// ldata[p]: pointer sfx_serv_item structure
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CMD_US_NEW = 1040;
// command: CMD_US_MODIFY
// about: update servers list (modify server data)
// ldata[p]: pointer sfx_serv_item structure
// rdata[i]: bit mask (fields to modify)
// return[i]: error code (OK_OK on success)
static const int CMD_US_MODIFY = 1050;
static const int CMD_USMF_ADDR = 1;
static const int CMD_USMF_STATE = 2;
// command: CMD_US_KILL
// about: update servers list (delete server)
// ldata[p]: pointer sfx_serv_item structure
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CMD_US_KILL = 1060;
// command: CMD_UC_NEW
// about: update clients list (add new client)
// ldata[p]: pointer sfx_clnt_item structure
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CMD_UC_NEW = 1070;
// command: CMD_UC_MODIFY
// about: update clients list (modify client data)
// ldata[p]: pointer sfx_clnt_item structure
// rdata[p]: bit mask (fields to modify)
// return[i]: error code (OK_OK on success)
static const int CMD_UC_MODIFY = 1080;
static const int CMD_UCMF_ADDR = 0x01;
static const int CMD_UCMF_STATE = 0x02;
static const int CMD_UCMF_TOTSZ = 0x04;
static const int CMD_UCMF_DONSZ = 0x08;
static const int CMD_UCMF_FNAME = 0x10;
// command: CMD_UC_KILL
// about: update clients list (delete client)
// ldata[p]: pointer sfx_clnt_item structure
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CMD_UC_KILL = 1090;
////////////////////////////////////////////////////////////////////////////
// core commands
// command: CCMD_NONE
// about: tests core for connection
// ldata[p]: not used (must be NULL)
// rdata[p]: not used (must be NULL)
// return[i]: must return OK_OK, otherwise core will be detached
static const int CCMD_NONE = 1500;
// command: CCMD_INVALID_CMD
// about: used for debuging
// ldata[p]: not used (must be NULL)
// rdata[p]: not used (must be NULL)
// return[i]: must return ERC_NO_CMDSUPPORT
static const int CCMD_INVALID_CMD = 1501;
// command: CCMD_CRSERV
// about: create new server
// ldata[p]: pointer to sfx_crserv_info struct
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CCMD_CRSERV = 1510;
// command: CCMD_RUNSERV
// about: run server (if not running)
// ldata[p]: pointer to sfx_serv_item struct
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CCMD_RUNSERV = 1520;
// command: CCMD_STOPSERV
// about: stop server (if running)
// ldata[p]: pointer to sfx_serv_item struct
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CCMD_STOPSERV = 1530;
// command: CCMD_KILLSERV
// about: kills server
// ldata[p]: pointer to sfx_serv_item struct
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CCMD_KILLSERV = 1540;
// command: CCMD_SENDFILE
// about: sends file
// ldata[p]: pointer to sfx_sndfile_info struct
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CCMD_SENDFILE = 1550;
// command: CCMD_EXIT
// about: terminate core
// ldata[i]: reason (OK_OK or error code)
// rdata[p]: not used (must be NULL)
// return[i]: error code (OK_OK on success)
static const int CCMD_EXIT = 1999;
////////////////////////////////////////////////////////////////////////////
// states
static const int ST_SERV_NONE = 2000;
static const int ST_SERV_CREATING = 2005;
static const int ST_SERV_BINDING = 2010;
static const int ST_SERV_STOPED = 2015;
static const int ST_SERV_LISTENING = 2020;
static const int ST_SERV_ACCEPTING = 2025;
static const int ST_SERV_STOPING = 2030;
static const int ST_SERV_CLOSING = 2035;
static const int ST_SERV_CLOSED = 2040;
static const int ST_SERV_KILLING = 2045;
static const int ST_SERV_KILLED = 2050;
static const int ST_SERV_RESOLVING = 2055;
static const int ST_SERV_STARTLSTN = 2060;
static const int ST_CLNT_NONE = 2100;
static const int ST_CLNT_CREATING = 2105;
static const int ST_CLNT_CONNECTING = 2110;
static const int ST_CLNT_CONNECTED = 2115;
static const int ST_CLNT_SENDINGH = 2120;
static const int ST_CLNT_SENDINGD = 2125;
static const int ST_CLNT_RECVINGH = 2130;
static const int ST_CLNT_RECVINGD = 2135;
static const int ST_CLNT_PAUSING = 2140;
static const int ST_CLNT_PAUSED = 2145;
static const int ST_CLNT_RESUMING = 2150;
static const int ST_CLNT_KILLING = 2155;
static const int ST_CLNT_KILLED = 2160;
static const int ST_CLNT_SENDEND = 2165;
static const int ST_CLNT_SENDDONE = 2170;
static const int ST_CLNT_WAIT4DATA = 2175;
static const int ST_CLNT_RECVEND = 2180;
static const int ST_CLNT_RECVDONE = 2185;
static const int ST_CLNT_CANCELED = 2120;
static const int ST_CLNT_RECVINFO = 2130;
////////////////////////////////////////////////////////////////////////////
// virtual functions
//virtual int attach(cfx_core *core) = 0;
//virtual int run() = 0;
//virtual int detach() = 0;
//virtual sfx_data exec_cmd(const int cmd, const sfx_data ldata, const sfx_data rdata) = 0;
virtual sfx_data exec_cmd(const int cmd, const sfx_data ldata, const sfx_data rdata) {
return ERC_NO_CMDSUPPORT;
}
////////////////////////////////////////////////////////////////////////////
// functions
cfx_if(): _core(NULL) {}
int attach_core(cfx_core *const core);
int detach_core();
sfx_data cmd_to_core(const int cmd, const sfx_data ldata, const sfx_data rdata);
private:
////////////////////////////////////////////////////////////////////////////
// private variables
cfx_core *_core;
////////////////////////////////////////////////////////////////////////////
// private functions
cfx_core *_get_core() { return _core; }
void _set_core(cfx_core *const core) { _core = core; }
};
////////////////////////////////////////////////////////////////////////////////
// cfx_core (declaration)
class cfx_core {
public:
////////////////////////////////////////////////////////////////////////////
// error codes
static const int ERC_CORE_ERROR = -3201;
static const int ERC_CORE_SRVNSTOPED2R = -3205;
static const int ERC_CORE_SRVNRUNING2S = -3210;
////////////////////////////////////////////////////////////////////////////
// public functions
cfx_core();
~cfx_core();
int last_error() const { return _last_error; }
void set_iface(cfx_if *const iface) { _iface = iface; }
cfx_if *get_iface() { return _iface; }
sfx_data execute_cmd(const int cmd, const sfx_data ldata, const sfx_data rdata);
int create_server(cfx_if::sfx_serv_item **pitem, const char *const addr,
const unsigned short port, const bool do_run = true);
int stop_server(cfx_if::sfx_serv_item *const item);
int run_server(cfx_if::sfx_serv_item *const item);
int kill_server(cfx_if::sfx_serv_item *const item);
int send_file(char *const fname, char *const addr, const unsigned short port);
int exit();
protected:
////////////////////////////////////////////////////////////////////////////
// protected types
struct sfx_sitem: public cfx_if::sfx_serv_item {
cfx_server *server;
cfx_core *core; // pointer to core, created server.
sfx_sitem *prev;
sfx_sitem *next;
};
struct sfx_citem: public cfx_if::sfx_clnt_item {
cfx_client *client;
cfx_core *core; // pointer to core, created server.
sfx_citem *prev;
sfx_citem *next;
};
////////////////////////////////////////////////////////////////////////////
// protected functions
sfx_sitem *_new_sitem(cfx_server *const server = NULL);
void _del_sitem(sfx_sitem *const item);
sfx_citem *_new_citem(cfx_client *const client = NULL);
void _del_citem(sfx_citem *const item);
int _set_addr_info(const sockaddr_in *const addrin, cfx_if::sfx_addr_info *const ainfo);
void _free_addr_info(cfx_if::sfx_addr_info *const ainfo);
sfx_data cmd_to_iface(const int cmd, const sfx_data ldata, const sfx_data rdata) {
if (NULL != _iface)
return _iface->exec_cmd(cmd, ldata, rdata);
else
return ERC_CORE_NULLIFACE;
}
static int _on_server_event(const int event, cfx_server *const caller, void *const data);
static int _on_client_event(const int event, cfx_client *const caller, void *const data);
// on server events
int _on_ev_listening(cfx_server *const caller, void *const data);
int _on_ev_accepting(cfx_server *const caller, void *const data);
int _on_ev_accepted(cfx_server *const caller, void *const data);
int _on_ev_stoppings(cfx_server *const caller, void *const data);
int _on_ev_stopeds(cfx_server *const caller, void *const data);
// on client events
int _on_ev_need_file2w(cfx_client *const caller, void *const data);
int _on_ev_sending_info(cfx_client *const caller, void *const data);
int _on_ev_sent_info(cfx_client *const caller, void *const data);
int _on_ev_sending_data(cfx_client *const caller, void *const data);
int _on_ev_sent_data(cfx_client *const caller, void *const data);
int _on_ev_send_end(cfx_client *const caller, void *const data);
int _on_ev_send_done(cfx_client *const caller, void *const data);
int _on_ev_killingc(cfx_client *const caller, void *const data);
int _on_ev_killedc(cfx_client *const caller, void *const data);
int _on_ev_waiting4data(cfx_client *const caller, void *const data);
int _on_ev_recving_info(cfx_client *const caller, void *const data);
int _on_ev_recved_info(cfx_client *const caller, void *const data);
int _on_ev_recving_data(cfx_client *const caller, void *const data);
int _on_ev_recved_data(cfx_client *const caller, void *const data);
int _on_ev_recv_end(cfx_client *const caller, void *const data);
int _on_ev_recv_done(cfx_client *const caller, void *const data);
sfx_data _on_cmd_crserv(const sfx_data ldata, const sfx_data rdata);
sfx_data _on_cmd_runserv(const sfx_data ldata, const sfx_data rdata);
sfx_data _on_cmd_stopserv(const sfx_data ldata, const sfx_data rdata);
sfx_data _on_cmd_killserv(const sfx_data ldata, const sfx_data rdata);
sfx_data _on_cmd_sendfile(const sfx_data ldata, const sfx_data rdata);
int _not_wsa_error(const int er) { _last_error = GetLastError(); return er; }
int _wsa_error(const int er) { _last_error = WSAGetLastError(); return er; }
int _error_msg(const int er_id, const int er_code = 0, void *const rdata = NULL);
private:
////////////////////////////////////////////////////////////////////////////
// private constants
static const int _def_mx_fn_sz = 512;
////////////////////////////////////////////////////////////////////////////
// private variables
WSADATA _wsa_data;
cfx_if *_iface;
sfx_sitem *_sitems;
sfx_citem *_citems;
int _mx_fn_sz;
int _last_error;
};
} // end of namespace "fx_ns"
#endif
Соседние файлы в папке fexchange