Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
17.04.2013
Размер:
17.51 Кб
Скачать
/*******************************************************************************
* 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