#include "StdAfx.h"
#include "ManagedInterfaceMapper.h"

CManagedInterfaceMapper::CManagedInterfaceMapper(void)
{
}

CManagedInterfaceMapper::~CManagedInterfaceMapper(void)
{
}


///////////////////////////////////////////////////////////////////
//	IMappedInterface(読み込みロック)
///////////////////////////////////////////////////////////////////
/*!
	インタフェース存在確認
*/
int CManagedInterfaceMapper::InterfaceIsExist(LPCSTR interfacePath)
{
	//	読み込みスコープロック
	CFastReadWriteLockReadScope	readLock(m_readWriteLock);

	//	検索
	if(FindInterface(interfacePath) != -1)
		return(TRUE);
	return(FALSE);
}

/*!
	関数存在確認
*/
int CManagedInterfaceMapper::FunctionIsExist(LPCSTR interfacePath, LPCSTR funcName)
{
	//	読み込みスコープロック
	CFastReadWriteLockReadScope	readLock(m_readWriteLock);

	//	取得
	IManagedInterfaceImplementPtr ifPtr = GetInterface(interfacePath);
	if(ifPtr == NULL)
		return(-1);

	//	確認
	return(ifPtr->FunctionIsExist(funcName));
}

/*!
	関数の実行
*/
int CManagedInterfaceMapper::Invoke(LPCSTR interfacePath, LPCSTR funcName, IManagedInterfaceArgStackPtr args)
{
	//	読み込みスコープロック
	CFastReadWriteLockReadScope	readLock(m_readWriteLock);

	//	取得
	IManagedInterfaceImplementPtr ifPtr = GetInterface(interfacePath);
	if(ifPtr == NULL)
		return(-1);

	//	実行を支持
	return(ifPtr->Invoke(funcName, args));
}


///////////////////////////////////////////////////////////////////
//	IMappedInterfaceRegister(書き込みロック)
///////////////////////////////////////////////////////////////////
/*!
	登録
*/
int CManagedInterfaceMapper::RegisterInterface(CString ifPath, IManagedInterfaceImplementPtr regit, int overload)
{
	//	書き込みスコープロック
	CFastReadWriteLockWriteScope	writeLock(m_readWriteLock);

	//	追加
	return(AddInterface(ifPath, regit, overload));
}

/*!
	削除
*/
int CManagedInterfaceMapper::UnRegisterInterface(CString ifPath, IManagedInterfaceImplementPtr toUnRegist)
{
	//	書き込みスコープロック
	CFastReadWriteLockWriteScope	writeLock(m_readWriteLock);

	//	削除
	return(DeleteInterface(ifPath, toUnRegist));
}


///////////////////////////////////////////////////////////////////
//	補助(配列用クリティカルセクションで保護)
///////////////////////////////////////////////////////////////////
/*!
	追加
*/
int CManagedInterfaceMapper::AddInterface(CString ifPath, IManagedInterfaceImplementPtr regist, int overload)
{
	//	配列アクセスの保護
	SCOPE_LOCK();

	//	上書き確認
	int	index = FindInterface(ifPath);
	if(index != -1)
	{
		//	オーバーロードしない
		if(!overload)
			return(-1);

		//	削除
		DeleteInterface(ifPath, regist);
	}

	//	追加
	m_interfacePath.Add(ifPath);
	m_interface.Add(regist);
	return(0);
}


/*!
	インタフェース取得
*/
IManagedInterfaceImplementPtr CManagedInterfaceMapper::GetInterface(CString ifPath)
{
	//	配列アクセスの保護
	SCOPE_LOCK();

	//	上書き確認
	int	index = FindInterface(ifPath);
	if(index != -1)
		return m_interface[index];

	return(NULL);
}

/*!
	削除
*/
int CManagedInterfaceMapper::DeleteInterface(CString ifPath, IManagedInterfaceImplementPtr toUnRegist)
{
	//	配列アクセスの保護
	SCOPE_LOCK();

	//	上書き確認
	int	index = FindInterface(ifPath);
	if(index != -1)
	{
		if(m_interface[index] == toUnRegist)
		{
			//	削除
			m_interfacePath.RemoveAt(index);
			m_interface.RemoveAt(index);
			return(0);
		}
	}
	return(-1);
}


/*!
	インタフェース名から検索
*/
int CManagedInterfaceMapper::FindInterface(CString ifPath)
{
	//	配列アクセスの保護
	SCOPE_LOCK();

	//	検索
	for(int i=0;i<m_interfacePath.GetSize();i++)
	{
		if(m_interfacePath[i].CompareNoCase(ifPath) == 0)
			return(i);
	}

	return(-1);
}

