// ★コメント未記入
// BregPool.cpp: CBregPool クラスのインプリメンテーション
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "shitarabian.h"
#include "BregPool.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////

CBregPool::CBregPool()
{
	m_Dll = NULL;
	m_ProcMatch = NULL;
	m_ProcSubst = NULL;
	m_ProcFree = NULL;
	m_ProcVersion = NULL;

	m_nmax = 1;
	m_rxpool = new BREGEXP*[m_nmax]; 
	ZeroMemory(m_rxpool,sizeof(BREGEXP*)*m_nmax);

	LoadDll();
}

CBregPool*	CBregPool::GetInstance()
{
	static CBregPool s_BregPool;

	return( &s_BregPool );
}


CBregPool::~CBregPool()
{
	DestroyFree();

	if ( m_rxpool != NULL )
	{
		delete [] m_rxpool;
	}

	FreeDll();
}
// デストラクタから呼ばれるFree
void CBregPool::DestroyFree()
{
	if ( m_ProcFree != NULL )
	{
		if (m_rxpool == 0)
			return;
		for (int i = 0;i < m_nmax;i++) {
			if (m_rxpool[i])
				m_ProcFree(m_rxpool[i]);
		}
		delete [] m_rxpool;
		m_rxpool = NULL;
	}
}

void CBregPool::Free(
	BREGEXP*	rxp
)
{
	if ( m_ProcFree != NULL )
	{
		m_ProcFree( rxp );
		ZeroMemory(m_rxpool,sizeof(BREGEXP*)*m_nmax);
	}
};

// BREGEXPの作成
BREGEXP* CBregPool::Get(char *regstr)
{
	if ( m_ProcMatch != NULL )
	{
		BREGEXP *r;
		for (int i = 0;i < m_nmax;i++) {
			r = m_rxpool[i];
			if (r == 0)
				break;
			if (r->parap == 0)
				break;
			// Check same Regular Expression
			if (memcmp(regstr,r->parap,(r->paraendp - r->parap) + 1) == 0)
				return r;		// we got !!!
		}
		if (i > m_nmax - 1)
			i = m_nmax - 1;
		if (m_rxpool[i])
			return m_rxpool[i];
		char msg[80];
		char p[] = " ";
		// Make Compile Block
		m_ProcMatch(regstr,p,p+1,&m_rxpool[i],msg);

		return m_rxpool[i];
	}
	return( NULL );
}



BOOL CBregPool::LoadDll()
{
	m_Dll = LoadLibrary( _T("BREGEXP.DLL") );

	if ( m_Dll != NULL )
	{
		m_ProcMatch = (ProcMatch)GetProcAddress(
		  m_Dll,					// handle to DLL module
		  "BMatch"				// name of function
		);

		m_ProcSubst = (ProcSubst)GetProcAddress(
		  m_Dll,					// handle to DLL module
		  "BSubst"					// name of function
		);

		m_ProcFree = (ProcFree)GetProcAddress(
		  m_Dll,					// handle to DLL module
		  "BRegfree"			// name of function
		);

		m_ProcVersion = (ProcVersion)GetProcAddress(
		  m_Dll,					// handle to DLL module
		  "BRegexpVersion"		// name of function
		);

		TRACE( (char*)m_ProcVersion() );
		return( TRUE );
	}
	return( FALSE );
}


BOOL CBregPool::FreeDll()
{
	if ( m_Dll != NULL )
	{
		BOOL	bFree = FreeLibrary( m_Dll );
		if ( bFree )
		{
			m_ProcMatch = NULL;
			m_ProcSubst = NULL;
			m_ProcFree = NULL;
			m_ProcVersion = NULL;
			m_Dll = NULL;
			return( TRUE );
		}
		else
		{
			return( FALSE );
		}
	}
	return( TRUE );
}



BOOL CBregPool::Match(
char* regstr,char *target,char *targetendp, BREGEXP **rxp,char *msg
)
{
	if ( m_ProcMatch != NULL )
	{
		BOOL bExists = m_ProcMatch(
			regstr,
			target,
			targetendp,
			rxp,
			msg
		);

		return( bExists );
	}
	return( FALSE );
}



BOOL CBregPool::Subst(
char* regstr,char *target,char *targetendp, BREGEXP **rxp,char *msg
)
{
	if ( m_ProcMatch != NULL )
	{
		BOOL bExists = m_ProcSubst(
			regstr,
			target,
			targetendp,
			rxp,
			msg
		);

		return( bExists );
	}
	return( FALSE );
}