#pragma once
#include <Winsock2.h>
#include "SyncObject.h"



class COverlappedSocket
{
public:
	COverlappedSocket(void);
	virtual ~COverlappedSocket(void);

	//////////////////////////////////////////////////////////////////////////////////
	//	初期化など
	//////////////////////////////////////////////////////////////////////////////////
	//!	使用開始
	virtual int AttachSocket(SOCKET sock);

	//!	閉じる
	virtual void Close();

	//!	ソケット取得
	virtual SOCKET GetSocket() { return m_socket; };

	//////////////////////////////////////////////////////////////////////////////////
	//	設定
	//////////////////////////////////////////////////////////////////////////////////
	//!	タイムアウト時間指定
	virtual void SetTimeOut(int timeout) { m_timeout = timeout; };

	//!	中断イベント設定
	virtual void SetBreakEvent(HANDLE breakEvent) { m_breakEvent = breakEvent;};

	//!	中断イベント取得
	virtual HANDLE GetBreakEvent() { return m_breakEvent; };

	//!	切断イベント取得
	virtual HANDLE GetCloseEvent() { return m_closeEvent; };

	//!	最終エラー取得
	int GetLastError() { return m_lastError; };

	//!	最終エラー設定
	void SetLastError(int error = OVRS_ERROR_AUTO_SET);

	enum OVRS_ERROR
	{
		OVRS_ERROR_AUTO_SET	= -1,

		OVRS_ERROR_NO_ERROR	= 0,
		OVRS_ERROR_TIMEOUT	= 1000,
		OVRS_ERROR_CLOSE	= 1100,
		OVRS_ERROR_BREAK	= 1101,
		OVRS_ERROR_OTHER	= 1200,
	};

	//////////////////////////////////////////////////////////////////////////////////
	//	通信処理
	//////////////////////////////////////////////////////////////////////////////////
	//!	バッファを送信(ブロッキングされる)
	virtual int BlockingSend(char *buf, int len, int timeOut=-1);

	//! バッファへ受信(ブロッキングされる)
	virtual int BlockingRecv(char *buf, int len, int timeOut=-1);

	//!	切断しているか取得
	virtual int IsDisconnect();

protected:
	//////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	//////////////////////////////////////////////////////////////////////////////////
	//!	ソケット
	SOCKET		m_socket;

	//!	通信処理用イベント（通信で変化）
	CSyncEvent	m_event;

	//!	ソケットが閉じたことを検出するイベント
	CSyncEvent	m_closeEvent;

	//!	中断イベント（セットで中断）
	HANDLE		m_breakEvent;

	//!	標準タイムアウト時間
	int			m_timeout;

	//!	最終エラー
	int			m_lastError;
};
