Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
13
Добавлен:
17.04.2013
Размер:
24.92 Кб
Скачать
/*******************************************************************************
* file:         dm_core.h                                                      *
* version:      0.9.1                                                          *
* author:       d-evil [tmd] (mailto:d-evil.tmd@mail.ru)                       *
* description:  not available                                                  *
*******************************************************************************/

#ifndef DM_CORE_INCLUDED
#define DM_CORE_INCLUDED

////////////////////////////////////////////////////////////////////////////////
// headers
#include <malloc.h>
#include <time.h>
#include <afxwin.h>
#include <winsock2.h>



namespace dm_core {

////////////////////////////////////////////////////////////////////////////////
// global options
static const int DEFAULT_DATAGRAM_SIZE	= 0xFFF*2;

////////////////////////////////////////////////////////////////////////////////
// datagrams description
static const int DTGM_TYPE_REQUEST		= 0x1;	// ask server to recv file
static const int DTGM_TYPE_DATA			= 0x2;	// data
static const int DTGM_TYPE_APPEAL		= 0x4;	// ask client to send file block
static const int DTGM_TYPE_DISCARD		= 0x8;	// cancel send/recv

////////////////////////////////////////////////////////////////////////////////
// discard types
static const int DISCARD_TYPE_CANCEL	= 0x1;	// cancel
	// data[int]:
	//	-1	-	discard all (close connection)
	//	0	-	discard requests (connection accepted)
	//	>0	-	discard a number of blocks, successfully received number of info blocks (success)
	// param: not used
static const int DISCARD_TYPE_DONE		= 0x2;	// done
	// data[int]: total parts done
	// param: not used
static const int DISCARD_TYPE_CONFIRM	= 0x3;	// confirm
	// data: not used
	// param: not used
									

struct sdm_dtgm {
	int type;
	int session_id;	// session id
};

struct sdm_dtgm_request {
	int type;
	int session_id;	// session id
	int pckt_sz;
	unsigned int file_sz;
	int fn_len;
	char fname[1];
};

struct sdm_dtgm_data {
	int type;		// type of datagram
	int session_id;	// session id
	int ss_id;		// id of sub system
	int num;		// number of datablock
	int data_sz;	// actual data size
	char data[1];
};

struct sdm_dtgm_appeal {
	int type;
	int session_id;	// session id
	int ss_id;
	int pckt_sz;
	int done_parts;
	int count;
	int nums[1];
};



////////////////////////////////////////////////////////////////////////////////
// sfx_data declaration
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; }
};


struct sdm_dtgm_discard {
	int type;
	int session_id;	// session id
	int ss_id;		// -1 if not used
	int dtype;		// discard type
	sfx_data data;
	sfx_data param;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_dl_item declaration
class cdm_dl_item {
public:
	cdm_dl_item(const int refc = 1): _refc(refc) {}
	cdm_dl_item(cdm_dl_item *const next,
				cdm_dl_item *const prev,
				const int refc = 1)
	{
		_next = next;
		_prev = prev;
		_refc = refc;
	}
	
	int refc() const { return _refc; }
	void set_refc(const int refc) { _refc = refc; }
	int inc_refc() { return ++_refc;}
	int dec_refc() { return --_refc;}

	void set(cdm_dl_item *const next, cdm_dl_item *const prev = NULL) {
		_next = next; _prev = prev;
	}
	void set_next(cdm_dl_item *const next) { _next = next; }
	void set_prev(cdm_dl_item *const prev) { _prev = prev; }
	cdm_dl_item *next() const { return _next; }
	cdm_dl_item *prev() const { return _prev; }

private:
	int _refc;
	cdm_dl_item *_next;
	cdm_dl_item *_prev;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_dl_list declaration
class cdm_dls_list {
public:
	cdm_dls_list();
	~cdm_dls_list();

	cdm_dl_item *first() const { return _first; }
	int count() const { return _inum; }

	int add(cdm_dl_item *const item, const int timeout = INFINITE);
	int del(cdm_dl_item *const item, const int timeout = INFINITE);

	int lock(const int timeout = -1);
	int ulock();

private:
	int _inum;
	cdm_dl_item *_first;

	HANDLE _mutex;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_addr_info declaration
class cdm_addr_info {
public:
	////////////////////////////////////////////////////////////////////////////
	// error codes [-5000...-5099]
	static const int ERC_CANTRESOLVE = -5005;
	static const int ERC_NOMEM = -5010;
	static const int ERC_WSA = -5066;

	cdm_addr_info();
	cdm_addr_info(const char *const host, const unsigned short port);
	~cdm_addr_info();

	in_addr ip() const { return _saddr_in.sin_addr; }
	unsigned short port() const { return _saddr_in.sin_port; }
	int afam() const { return _saddr_in.sin_family; }
	char *ip_str() const { return _ip_str; }
	char *port_str() const { return _port_str; }
	char *host() const { return _host; }

	sockaddr *saddr() { return (sockaddr *)&_saddr_in; }
	sockaddr_in *saddrin() { return &_saddr_in; }
	int saddr_sz() const { return sizeof(_saddr_in); }

	int set(const sockaddr_in *const saddrin);
	int set(const char *const host, const unsigned short port);

	int set_port(const unsigned short port);
	int set_host(const char *const host);

	// return 0 on success and -1 on error
	static int resolve_host(const char *const host, in_addr *const addr);

protected:
	int _set_ip(const in_addr ip);
	int _updt_host();

private:
	static const int MX_PORTLEN = 8;

	sockaddr_in _saddr_in;

	char *_ip_str;
	char *_port_str;
	char *_host;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_file_info declaration
class cdm_file_info {
public:
	cdm_file_info();
	cdm_file_info(const cdm_file_info &ifile);
	cdm_file_info(const char *const path, const bool ch_name);
	cdm_file_info(const char *const name);
	~cdm_file_info();

	char *name() const { return _name; }
	char *path() const { return _path; }
	int name_len() const { return _name_len; }
	int path_len() const { return _path_len; }
	int set_name(const char *const name);
	int set_path(const char *const path, const bool ch_name = true);

	unsigned int sz() const { return _sz; }
	void set_sz(const unsigned int sz) { _sz = sz; }

	static int extract_filename(const char *const path, const int len = 0);

protected:
	void _init();

private:
	char *_name;
	int _name_len;
	char *_path;
	int _path_len;
	unsigned int _sz;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_fwriter declaration
class cdm_fwriter {
public:
	cdm_fwriter();
	~cdm_fwriter();
	
	int id() const { return _id; }
	void set_id(const int id) { _id = id; }

	int next_num() const { return _next_num; }
	int inc_next_num() { return ++_next_num; }

	int open(const char *const mode);
	int close();
	int write(const char *const buf, const int len);

	cdm_addr_info *addr_info() { return &_addr_info; }
	cdm_file_info *file_info() { return &_file_info; }

protected:
private:
	int _id;
	int _next_num;
	FILE *_file;
	cdm_addr_info _addr_info;
	cdm_file_info _file_info;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_socket declaration
class cdm_socket {
public:
	////////////////////////////////////////////////////////////////////////////
	// public cdm_socket states [5100..5199]
	static const int STATE_NONE			= 5100;
	static const int STATE_ZOMBIE		= 5190;

	static const int EXTSTATE_NONE		= 6100;

	cdm_socket();
	~cdm_socket();

	SOCKET sock() const { return _sock; }
	char *dtgm() const { return _buf; }

	void *ui_data() const { return _ui_data; }
	void set_ui_data(void *const ui_data) { _ui_data = ui_data; }

	int pckt_sz() const { return _pckt_sz; }
	int set_pckt_sz(const int pckt_sz);

	sockaddr_in *saddrin() { return &_saddrin; }
	int saddrin_sz() const { return _saddrin_sz; }

	int state() const { return _state; }
	int ext_state() const { return _ext_state; }
	cdm_addr_info *addr_info() { return &_addr_info; }

	int bind();
	int can_read();
	int can_write();
	int can_read_size();

	int recv_dtgm();
	int send_dtgm();
	int send_dtgm(char *const dtgm);
	int send_dtgm(sockaddr_in *const saddrin, const int saddrin_sz);
	int send_dtgm(const char *const dtgm, const int dtgm_size,
				  sockaddr_in *const saddrin, const int saddrin_sz);
	int dtgm_type() { return ((sdm_dtgm *)_buf)->type; }

protected:
	void _set_state(const int state) { _state = state; }
	void _set_ext_state(const int ext_state) { _ext_state = ext_state; }

private:
	SOCKET _sock;
	int _state;
	int _ext_state;
	int _pckt_sz;
	cdm_addr_info _addr_info;

	sockaddr_in _saddrin;
	int _saddrin_sz;

	char *_buf;

	void *_ui_data;

	static const int _DEF_PCKT_SZ = DEFAULT_DATAGRAM_SIZE;
	static const int _PCKT_MNSZ = sizeof(int);
};



////////////////////////////////////////////////////////////////////////////////
// cdm_frecv_subs declaration
class cdm_frecver;
class cdm_frecv_subs {
public:
	////////////////////////////////////////////////////////////////////////////
	// cdm_frecv_subs public constants
	static const int STATE_NONE				= 5400;
	static const int STATE_STOPED			= 5405;
	static const int STATE_RUNNING			= 5410;
	static const int STATE_PAUSED			= 5415;
	static const int STATE_LAUNCHED			= 5420;

	static const int EXTSTATE_NONE			= 6400;
	static const int EXTSTATE_ACCEPTING		= 6405;
	static const int EXTSTATE_RECVING		= 6410;
	static const int EXTSTATE_TERMINATING	= 6415;
	static const int EXTSTATE_FINALIZING	= 6420;
	static const int EXTSTATE_ABORTED		= 6425;
	static const int EXTSTATE_DONE			= 6430;

	cdm_frecv_subs();
	~cdm_frecv_subs();

	cdm_addr_info *iaddr() { return &_iaddr; }
	cdm_file_info *ifile() { return &_ifile; }

	int id() const { return _id; }
	void set_id(const int id) { _id = id; }
	int session_id() const { return _session_id; }
	void set_session_id(const int session_id) { _session_id = session_id; }
	int state() const { return _state; }
	int ext_state() const { return _ext_state; }

	int init();
	int start(const bool delayed = false);	// open file, fill appeals buffer
	int stop(const int ext_state = EXTSTATE_NONE);		// close file
	int add_dtgm(sdm_dtgm_data *const dtgm);
	int terminate(const int ext_state = EXTSTATE_FINALIZING);
	bool can_appeal();
	bool need_appeal();
	sdm_dtgm_appeal *get_appeal(const bool will_send = true);
	int send_discard(const int dtype, const int data = 0, const int param = 0);

	int dtgm_size() const { return _dtgm_size; }
	int set_dtgm_size(const int dtgm_size);
	int dtgms_count() const { return _dtgms_count; }
	int set_dtgms_count(const int dtgms_count);
	int appeals_count() const { return _appeals_count; }
	int set_appeals_count(const int appeals_count);
	int reappeal_timeout() const { return _reappeal_timeout; }
	void set_reappeal_timeout(const int t) { _reappeal_timeout = t; }

	cdm_frecver *parent() const { return _parent; }
	void set_parent(cdm_frecver *const parent) { _parent = parent; }
	void *ui_data() const { return _ui_data; }
	void set_ui_data(void *const ui_data) { _ui_data = ui_data; }

	int total_parts() const { return _total_parts; }
	int done_parts() const { return _done_parts; }
	void set_done_parts(const int done_parts) { _done_parts = done_parts; }
	bool total_done() const { return _total_parts == _done_parts; }

	void pause() {
		if (STATE_RUNNING == _state) _state = STATE_PAUSED;
	}
	void resume() {
		if (STATE_PAUSED == _state) _state = STATE_RUNNING;
	}
	bool must_die() { _dying = true; }
	bool is_dying() const { return _dying; }
	int die(const bool delayed = false);

	clock_t up_time() const { return _run_time; }
	void update_time() { clock_t t = clock(); _run_time += (t - _last_time); _last_time = t; }

protected:
	void _init();
	void _alloc_dtgms();
	void _free_dtgms();
	void _realloc_free_tbl();
	void _realloc_bufs();
	void _realloc_appeal();
	void _free_appeal();

	void _set_state(const int state) { _state = state; }
	void _set_ext_state(const int ext_state) { _ext_state = ext_state; }

private:
	char **_dtgms;
	int *_free_tbl;
	int _free_i;
	int _dtgms_count;
	int _dtgm_size;
	int _data_size;

	sdm_dtgm_appeal *_appeal;
	int _appeals_count;

	clock_t _last_time;
	clock_t _run_time;

	int _appeal_max;
	int _appeal_next;
	clock_t _last_appeal_time;
	int _reappeal_timeout;
	int _appeals_need_ahead;
	int _appeals_changed;

	HANDLE _hfile;
	int _done_parts;
	int _total_parts;

	cdm_addr_info _iaddr;
	cdm_file_info _ifile;

	int _id;
	int _state;
	int _ext_state;
	int _session_id;

	cdm_frecver *_parent;
	void *_ui_data;

	bool _dying;

	static const int _DEF_DTGMS_COUNT = 32;
	static const int _DEF_APEALS_COUNT = 4;
	static const int _DEF_DTGM_SIZE = DEFAULT_DATAGRAM_SIZE;
	static const int _DEF_REAPPEAL_TIMEOUT = 200;	// in mseconds
	static const int _DEF_APPEALS_NEEDAHEAD = _DEF_APEALS_COUNT * 2/3;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_frecver declaration
class cdm_frecver: public cdm_socket {
public:
	////////////////////////////////////////////////////////////////////////////
	// public cdm_frecver sates [5200..5399]
	static const int STATE_RUNNING			= 5305;
	static const int STATE_PAUSED			= 5310;
	static const int STATE_STOPED			= 5315;
	static const int STATE_LAUNCHED			= 5320;

	static const int EXTSTATE_LISTENING		= 6305;
	static const int EXTSTATE_ACCEPTING		= 6310;
	static const int EXTSTATE_TERMINATING	= 6315;

	cdm_frecver();
	~cdm_frecver();

	cdm_frecv_subs *new_subs() const { return new _cdm_frecv_subs; }
	void del_subs(cdm_frecv_subs *const subs) { delete (_cdm_frecv_subs *)subs; }

	void add_subs(cdm_frecv_subs *const subs);
	void remove_subs(cdm_frecv_subs *const subs);
	int subs_count() const { return _subs.count(); }

	cdm_frecv_subs *get_subs(const int id);
	cdm_frecv_subs *get_session(const int session_id);
	cdm_frecv_subs *subs_first() const { return (_cdm_frecv_subs *)_subs.first(); }
	cdm_frecv_subs *subs_next(cdm_frecv_subs *const subs) const {
		return (_cdm_frecv_subs *)(((_cdm_frecv_subs *)subs)->next());
	}

	int start(const bool delayed = false);
	int stop();

	void pause() {
		if (STATE_RUNNING == state()) _set_state(STATE_PAUSED);
	}
	void resume() {
		if (STATE_PAUSED == state()) _set_state(STATE_RUNNING);
	}
	bool must_die() { _dying = true; }
	bool is_dying() const { return _dying; }
	int die(const bool delayed = false);
	int kill_subs(cdm_frecv_subs *const subs);

protected:
	class _cdm_frecv_subs: public cdm_frecv_subs, public cdm_dl_item {};

private:
	cdm_dls_list _subs;
	bool _binded;
	bool _dying;

};



////////////////////////////////////////////////////////////////////////////////
// cdm_fsender declaration
class cdm_fsender: public cdm_socket {
public:
	////////////////////////////////////////////////////////////////////////////
	// public cdm_fsender sates [5200..5399]
	static const int STATE_RUNNING			= 5205;
	static const int STATE_PAUSED			= 5210;
	static const int STATE_STOPED			= 5215;
	static const int STATE_LAUNCHED			= 5220;

	static const int EXTSTATE_REQUESTING	= 6205;
	static const int EXTSTATE_SENDING		= 6210;
	static const int EXTSTATE_TERMINATING	= 6215;
	static const int EXTSTATE_CANCELED		= 6220;
	static const int EXTSTATE_DONE			= 6225;

	cdm_fsender();
	~cdm_fsender();

	cdm_file_info *ifile() { return &_ifile; }
	cdm_addr_info *iaddr() { return &_iaddr; }
	int session_id() const { return _session_id; }
	void set_session_id(const int session_id) { _session_id = session_id; }

	int start(const bool delayed = false);
	int stop(const int ext_state = EXTSTATE_NONE);
	bool need_request();
	int send_request();
	void accepted() { _set_ext_state(EXTSTATE_SENDING); }
	int send_data(const int id, int *const appeals, const int count);
	int send_discard(const int ss_id, const int dtype, const int data = 0, const int param = 0);

	int total_parts() const { return _total_parts; }
	int done_parts() const { return _done_parts; }
	int add_parts(const int num);
	void set_done_parts(const int done_parts) { _done_parts = done_parts; }

	void pause() {
		if (STATE_RUNNING == state()) _set_state(STATE_PAUSED);
	}
	void resume() {
		if (STATE_PAUSED == state()) _set_state(STATE_RUNNING);
	}
	bool must_die() { _dying = true; }
	bool is_dying() const { return _dying; }
	int die(const bool delayed = false);

	clock_t up_time() const { return _run_time; }
	void update_time() { clock_t t = clock(); _run_time += (t - _last_time); _last_time = t; }

protected:
	// int _realloc_dtgm(const int new_pckt_sz = 0);
	// int _free_dtgm();

private:
	int _data_sz;
	sdm_dtgm_data *_send_dtgm;
	int _session_id;
	bool _dying;

	HANDLE _hfile;
	int _total_parts;
	int _done_parts;

	clock_t _last_request_time;
	int _rerequest_timeout;	// in milliseconds
	clock_t _run_time;
	clock_t _last_time;

	cdm_file_info _ifile;
	cdm_addr_info _iaddr;

	static const int _DEF_REREQUEST_TIMEOUT = 2000;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_uiproto declaration
class cdm_uiproto {
public:
	////////////////////////////////////////////////////////////////////////////
	// cdm_uiproto public constants
	static const int FSENDER_CH_STATE		= 0x1;
	// static const int FSENDER_CH_EXTSTATE	= 0x2;
	static const int FSENDER_CH_IADDR		= 0x4;
	static const int FSENDER_CH_IFILE		= 0x8;
	static const int FSENDER_CH_PROGRESS	= 0x10;
	static const int FSENDER_CH_ALL			= 0xFFFFFFFF;

	static const int FRECVER_CH_STATE		= 0x1;
	// static const int FRECVER_CH_EXTSTATE	= 0x2;
	static const int FRECVER_CH_IADDR		= 0x4;
	// static const int FRECVER_CH_IFILE		= 0x8;
	// static const int FRECVER_CH_PROGRESS	= 0x10;
	static const int FRECVER_CH_ALL			= 0xFFFFFFFF;

	static const int FSUBS_CH_STATE			= 0x1;
	static const int FSUBS_CH_EXTSTATE		= 0x2;
	static const int FSUBS_CH_IADDR			= 0x4;
	static const int FSUBS_CH_IFILE			= 0x8;
	static const int FSUBS_CH_PROGRESS		= 0x10;
	static const int FSUBS_CH_PARENT		= 0x20;
	static const int FSUBS_CH_ALL			= 0xFFFFFFFF;

	virtual int on_pure_dm_error(const int dm_error) = 0;
	virtual int on_error(const int dm_error, const int os_error) = 0;
	virtual int on_ext_error(void *const error) = 0;

	virtual int on_frecver_ch(cdm_frecver *const frecver, const int ch_mask) = 0;
	virtual int on_fsender_ch(cdm_fsender *const fsender, const int ch_mask) = 0;
	virtual int on_subs_ch(cdm_frecv_subs *const subs, const int ch_mask) = 0;

	virtual int on_frecver_rm(cdm_frecver *const frecver) = 0;
	virtual int on_fsender_rm(cdm_fsender *const fsender) = 0;
	virtual int on_subs_rm(cdm_frecv_subs *const subs) = 0;

	virtual int on_accept(cdm_frecv_subs *const frecv_subs) = 0;
	virtual int on_quit() = 0;
};



////////////////////////////////////////////////////////////////////////////////
// cdm_core declaration
class cdm_core {
public:
	////////////////////////////////////////////////////////////////////////////
	// dm error codes [-1..-4999]
	// common errors
	static const int ERC_ERROR			= -1;
	// threads and synchronization errors
	static const int ERC_CRTHREAD		= -1001;
	static const int ERC_THRSUSPEND		= -1002;
	static const int ERC_THRRESUME		= -1003;
	static const int ERC_PAUSEMAIN		= -1004;
	// sockets errors
	static const int ERC_SOCKSINIT		= -1101;
	static const int ERC_SOCKSBIND		= -1102;
	static const int ERC_SOCKSRESOLVE	= -1103;
	// memory errors
	// static const int ERC_NOMEM			= -1201;
	// other errors
	static const int ERC_ADDFSENDER		= -4101;
	static const int ERC_ADDFRECVER		= -4102;
	static const int ERC_STARTFSENDER	= -4105;
	static const int ERC_STARTFRECVER	= -4106;
	static const int ERC_STARTFSUBS		= -4107;
	static const int ERC_FSENDER_SPIT	= -4110;
	static const int ERC_FSENDER_FSIZE	= -4210;


	////////////////////////////////////////////////////////////////////////////
	// dm frecver changes
	static const int FRECV_CH_HOST		= 0x1;
	static const int FRECV_CH_IP		= 0x2;
	static const int FRECV_CH_PORT		= 0x4;
	static const int FRECV_CH_COUNT		= 0x8;
	static const int FRECV_CH_STATE		= 0x10;

	cdm_core();
	~cdm_core();

	int last_dm_error() { int tmp = _last_dm_error; _last_dm_error = 0; return tmp;}
	int last_error() { int tmp = _last_error; _last_error = 0; return tmp; }

	cdm_uiproto *get_ui() const { return _ui; }
	int attach_ui(cdm_uiproto *const ui);
	int nulljob_delay() const { return _nulljob_delay; }
	int set_nulljob_delay(const int njd) { _nulljob_delay = njd; }

	int init();
	int run(const bool nt = true);	// run in new thread if (nt==true)
	int pause();
	int upause();
	int quit();

	int swallow(cdm_frecver *const recver, int *const ch_mask);
	int spit(cdm_fsender *const sender, int *const ch_mask);
	int accept(cdm_frecver *const recver, int *const ch_mask);
	int get_data(cdm_frecver *const recver, int *const ch_mask);
	int discard(cdm_frecver *const recver, int *const ch_mask);
	int appeal(cdm_fsender *const sender, int *const ch_mask);
	int discard(cdm_fsender *const sender, int *const ch_mask);

	cdm_frecver *new_frecver(const char *const host = NULL, const unsigned short port = 0);
	cdm_fsender *new_fsender(const char *const host = NULL, const unsigned short port = 0);

	int add_frecver(cdm_frecver *const recver);
	int add_fsender(cdm_fsender *const sender);

	int start_frecver(cdm_frecver *const recver, const bool delayed = false);
	int start_fsender(cdm_fsender *const sender, const bool delayed = false);

	int del_frecver(cdm_frecver *const recver);
	int del_fsender(cdm_fsender *const sender);

	int free_frecver(cdm_frecver *const recver);
	int free_fsender(cdm_fsender *const sender);


	char *get_hostname() const { return _hostname; }
	unsigned short get_defport() const { return _def_port; }
	int speeed() const { return _speeed; }
	void reset_speeed() {_speeed = 0; }
	static bool use_bugs() { return _use_bugs; }
	static void set_use_bugs(const bool use_bugs = false) { _use_bugs = use_bugs; }

	char *def_dir() const { return _def_dir; }

protected:
	////////////////////////////////////////////////////////////////////////////
	// protected types
	class _cdm_frecver: public cdm_dl_item, public cdm_frecver {};
	class _cdm_fsender: public cdm_dl_item, public cdm_fsender {};

	int _run();
	static inline int __stdcall _run_helper(cdm_core *const core) {
		return core->_run();
	}

	int _parse_frecvers(int *const num = NULL);
	int _parse_fsenders(int *const num = NULL);

	////////////////////////////////////////////////////////////////////////////
	// protected error loggers
	int _pure_dm_error(const int dm_error = -1) {
		return (_last_dm_error = dm_error);
	}
	int _error(const int dm_error = 0) {
		_last_error = GetLastError();
		return (_last_dm_error = dm_error);
	}
	int _sock_error(const int dm_error = 0) {
		_last_error = WSAGetLastError();
		return (_last_dm_error = dm_error);
	}
	int _ui_on_dm_error() {
		int rev = _ui->on_pure_dm_error(_last_dm_error);
		_last_dm_error = 0;
		return rev;
	}
	int _ui_on_error() {
		int rev = _ui->on_error(_last_dm_error, _last_error);
		_last_dm_error = 0;
		_last_error = 0;
		return rev;
	}

private:
	HANDLE _thread_h;
	DWORD _thread_id;
	HANDLE _running_mtx;
	bool volatile _must_stop;

	cdm_uiproto *_ui;

	cdm_dls_list _frecvers;
	cdm_dls_list _fsenders;

	////////////////////////////////////////////////////////////////////////////
	// event handlers
	// edm_event _ev_ne


	WSADATA _wsa_data;
	int _last_error;
	int _last_dm_error;

	int _nulljob_delay;
	static const int _DEF_NULLJOB_DELAY = 200;
	char *_hostname;
	static const int _HOSTNAME_MXLEN = 256;
	static const unsigned short _def_port = 0xDEAD;

	int volatile _speeed;
	int _speeed_prev;
	static bool _use_bugs;

	char *_def_dir;
};



}	// end of namespace "dm_core"



#endif
Соседние файлы в папке include