/***************************************************************************
				BaseSocket ( Base Socket Class )
                -----------------------------------------
	begin      : 2010/03/02
	copyright  : (C) 2005 SolutionBox Inc.
	author     : Service 1 Team
	email      : svc1@solbox.com
	version    : 1.0

	CopyRight(C) 2005 SolutionBox Inc. All Rights reserved.
	Redistribution and use in source and binary forms, with or with out
	modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/

#ifndef __LIBRARY_BASE_SOCKET_H__
#define __LIBRARY_BASE_SOCKET_H__

#include <unistd.h>
#include <sys/types.h>
#include <string>

#include "Logger.h"

#define SOCKET_NOT_VALID					-1
#define DEFAULT_DATA_RECEIVE_TIMEOUT		15		// sec


class CBaseSocket
{

	protected:

		/// @brief socket descriptor
		int m_sock;

		/// @brief socket 의 연결상태인지 여부를 저장하기 위한 변수.
		bool m_bConnected;


	public:

		/// @brief 생성자.
		CBaseSocket( const int & socket );

		/// @brief 소멸자.
		~CBaseSocket();

		/// @brief 소켓의 Close 처리를 수행함.
		void Close(void);

		/// @brief 전달받은 Target 으로 Socket 접속을 수행
		/// @param szTarget [in] 접속 대상 Host name 또는 IP
		/// @param nPort	[in] 접속 Port
		/// @return 접속 성공시 true, 실패시 false 반환. ( 오류 내역은 로깅처리됨.)
		bool Connect( const std::string& szTarget, int nPort );

		/// @brief 멤버 변수인 m_sock 이 유효하고 연결된 상태인 경우 true 반환.
		/// @return socket이 유효하지 않거나 연결이 끊어지 경우 false 반환, 그외에는 true 반환.
		bool IsValidSocket(void);

		/// @brief 멤버변수인 socket 의 접속 상태 여부를 설정하기 위한 함수.
		void SetConnectionStatus( bool bConnected)	{ m_bConnected = bConnected; }

		/// @brief 현재 socket 의 접속 상태를 반환.
		bool GetConnectionStatus( void) { return m_bConnected; }

		//void SetLogger( Logger * pLog ) { m_pLog = pLog; }

	protected:

		/// @brief m_sock  로 부터 지정된 size 만큼 데이터 read 를 시도 ( read 함수와 동일 )
		/// @param vptr [out] Read 된 데이터를 저장하기 위한 변수에 대한 포인터.
		/// @param size [in] read 하고자 하는 데이터의 크기.
		/// @return read 된 데이터의 크기. 0: fd closed, -1: 오류 
		ssize_t Read( void * vptr, size_t size );

		/// @brief m_sock 로부터 지정된 size 만큼 read 를 시도, \n
		///< 만약 지정된 크기만큼 데이터가 존재하지 않을 경우 해당 크기만큼 데이터를 read 할때까지 대기.
		/// @param vptr [out] Read 된 데이터를 저장하기 위한 변수에 대한 포인터.
		/// @param size [in] read 하고자 하는 데이터의 크기.
		/// @return read 된 데이터의 크기. 0: fd closed, -1: 오류 
		ssize_t ReadN( void * vptr, size_t size );

		/// @brief m_sock 로부터 지정된 size 만큼 read 를 시도, \n
		///< 만약 지정된 크기만큼 데이터가 존재하지 않을 경우 해당 크기만큼 데이터를 read 할때까지 대기. \n
		///< 또는 지정된 Timeout 값 동안 read 를 하지 못하는 경우 오류 처리.
		/// @param vptr [out] Read 된 데이터를 저장하기 위한 변수에 대한 포인터.
		/// @param size [in] read 하고자 하는 데이터의 크기.
		/// @param timeout [in] Timeout value (sec)
		/// @return read 된 데이터의 크기. 0: fd closed, -1: 오류, -2: Timeout
		ssize_t ReadNTimeout( void * vptr, size_t size, int timeout = DEFAULT_DATA_RECEIVE_TIMEOUT );

		/// @brief m_sock 로부터 지정된 size 만큼 read 를 시도, \n
		///< 만약 지정된 크기만큼 데이터가 존재하지 않을 경우 해당 크기만큼 데이터를 read 할때까지 대기. \n
		///< 또는 지정된 Timeout 값 동안 read 를 하지 못하는 경우 오류 처리.
		///< 본 함수는 Socket 상에 이미 Data 가 존재하는 경우에만 사용.
		/// @param vptr [out] Read 된 데이터를 저장하기 위한 변수에 대한 포인터.
		/// @param size [in] read 하고자 하는 데이터의 크기.
		/// @param timeout [in] Timeout value (sec)
		/// @return read 된 데이터의 크기. 0: fd closed, -1: 오류, -2: Timeout
		ssize_t ReadNTimeout2( void * vptr, size_t size, int timeout = DEFAULT_DATA_RECEIVE_TIMEOUT );

	public:
		/// @brief m_sock 으로 지정된 크기만큼 vptr 의 데이터를 전송 시도.\n
		///< Send Timeout 옵션 설정으로 Write Timeout 설정 가능. \n
		///< 지정된 횟수만큼 재전송 실패시 오류로 처리함.
		/// @param vptr [in] 전달할 데이터를 저장한 변수에 대한 포인터.
		/// @param size [in] write 하고자 하는 데이터의 크기.
		/// @return write 된 데이터의 크기. 0: fd closed, -1: 오류 
		ssize_t WriteN( const void * vptr, size_t size );

	protected:

		/// @brief 문자열로 전달받은 정보를 검사하여 IP 접속 정보를 생성한다.
		unsigned int ConversionAddr( const char * name );

};

#endif /* __LIBRARY_BASE_SOCKET_H__ */
