#include "cphstr.h"

/* Declare global variable to hold Handle to DLL and PBORCA Handle  */
#ifdef USE_HSTRSTR2
extern HANDLE hDLL ;
extern HPSTR lpHStrStr ;

extern HPSTR lpHStrStr2 ;

/* ========================================================================	*/
/*  Hstrfunc2:  
/* ========================================================================	*/
PBINT __stdcall Hstrfunc2(HPSTR hpStr1, HPSTR hpStr2, FuncType ftFunc, long nSize)
{                                        
	long lLen1, lLen2, lCur, lMax, lCmp ;
	long iPass, iCur, iRetVal ;
	HPSTR hpCur1, hpCur2 ;
	PBINT (__cdecl *lpFunc1)(LPSTR lpStr1, LPSTR lpStr2) ;
	PBINT (__cdecl *lpFunc2)(LPSTR lpStr1, LPSTR lpStr2, size_t nSize) ;
	PBINT (__cdecl *lpFunc3)(LPCSTR lpStr1, LPCSTR lpStr2) ;

	lpFunc1 = NULL ;
	lpFunc2 = NULL ;
	lpFunc3 = NULL ;
	
	switch (ftFunc)
	{
		case Func_strcmp :
			lpFunc1 = _fstrcmp ;
			break ;
			
		case Func_stricmp :
			lpFunc1 = _fstricmp ;
			break ;
			
		case Func_strncmp :
			lpFunc2 = _fstrncmp ;
			break ;
			
		case Func_strnicmp :
			lpFunc2 = _fstrnicmp ;
			break ;
			
		case Func_strspn :
			lpFunc3 = _fstrspn ;
			break ;
			
		case Func_strcspn :
			lpFunc3 = _fstrcspn ;
			break ;
			
		default :
			return (-100) ;
	}
	
	lLen1 = Hstrlen(hpStr1) ;
	lLen2 = Hstrlen(hpStr2) ;
	lMax = (lLen1 > lLen2) ? lLen1 : lLen2 ;
	nSize = (nSize > lMax) ? lMax : nSize ;
	
	hpCur1 = lpHStrStr ;
	hpCur2 = lpHStrStr2 ;
	
	if (lMax <= (long) MAX_STR_LEN)
	{
		Hstrcpy(hpCur1, hpStr1) ;
		Hstrcpy(hpCur2, hpStr2) ;
		
		if (lpFunc1 != NULL)
		{
			iRetVal = (*lpFunc1)(hpCur1, hpCur2) ;
			return iRetVal ;
		}
		else if (lpFunc2 != NULL)
		{
			iRetVal = (*lpFunc2)(hpCur1, hpCur2, (size_t) nSize) ;
			return iRetVal ;
		}
		else if (lpFunc3 != NULL)
		{
			iRetVal = (*lpFunc3)((LPCSTR) hpCur1, (LPCSTR) hpCur2) ;
			return iRetVal ;
		}
	}
	
	/*  else ...  */
	iPass = ((long) lMax / (long) MAX_STR_LEN) + 1 ;
	
	for (iCur = 0 ; iCur < iPass ; ++iCur)
	{
		lCur = (iCur * MAX_STR_LEN) ;
		
		/*  This should never happen, but still, just in case ...  */
		if ((lCur > lLen1) || (lCur > lLen2))
		{
			return -100 ;
		}
		
		Hstrncpy(hpCur1, (HPSTR) &(hpStr1[lCur]), MAX_STR_LEN) ;
		Hstrncpy(hpCur2, (HPSTR) &(hpStr2[lCur]), MAX_STR_LEN) ;
		
		if (lpFunc1 != NULL)
		{
			iRetVal = (*lpFunc1)(hpCur1, hpCur2) ;
			if (iRetVal != 0)
			{
				return iRetVal ;
			}
		}
		else if (lpFunc2 != NULL)
		{
			lCmp = nSize - lCur ;
			lCmp = (lCmp > (long) MAX_STR_LEN) ? (long) MAX_STR_LEN : lCmp ;
			
			iRetVal = (*lpFunc2)(hpCur1, hpCur2, (size_t) lCmp) ;
			if (iRetVal != 0)
			{
				return iRetVal ;
			}
		}
		else if (lpFunc3 != NULL)
		{
			lCmp = nSize - lCur ;
			lCmp = (lCmp > (long) MAX_STR_LEN) ? (long) MAX_STR_LEN : lCmp ;
			
			iRetVal = (*lpFunc3)((LPCSTR) hpCur1, (LPCSTR) hpCur2) ;
			if (iRetVal != 0)
			{
				return iRetVal ;
			}
		}
	}
	
	return (0L) ;
}

/* ========================================================================	*/
/*  Hstrspn:  
/* ========================================================================	*/
long __stdcall Hstrspn(HPCSTR hpSrc, LPCSTR lpSearch)
{
	long lFoundIndex ;
	
	lFoundIndex = Hstrfunc2((HPSTR) hpSrc, (LPSTR) lpSearch, Func_strspn, 0) ;
	
	return lFoundIndex ;
}

/* ========================================================================	*/
/*  Hstrcspn:  
/* ========================================================================	*/
long __stdcall Hstrcspn(HPCSTR hpSrc, LPCSTR lpSearch)
{
	long lFoundIndex ;
	
	lFoundIndex = Hstrfunc2((HPSTR) hpSrc, (LPSTR) lpSearch, Func_strcspn, 0) ;
	
	return lFoundIndex ;
}

/* ========================================================================	*/
/*  Hstrcmp:  Compare string to string
/* ========================================================================	*/
PBINT __stdcall Hstrcmp(HPSTR hpStr1, HPSTR hpStr2)
{
	return (Hstrfunc2(hpStr1, hpStr2, Func_strcmp, 0L)) ;
}

/* ========================================================================	*/
/*  Hstricmp:  Compare string to string
/* ========================================================================	*/
PBINT __stdcall Hstricmp(HPSTR hpStr1, HPSTR hpStr2)
{
	return (Hstrfunc2(hpStr1, hpStr2, Func_stricmp, 0L)) ;
}

/* ========================================================================	*/
/*  Hstrncmp:  Compare string to string
/* ========================================================================	*/
PBINT __stdcall Hstrncmp(HPSTR hpStr1, HPSTR hpStr2, long nSize)
{
	return (Hstrfunc2(hpStr1, hpStr2, Func_strncmp, nSize)) ;
}

/* ========================================================================	*/
/*  Hstrnicmp:  Compare string to string
/* ========================================================================	*/
PBINT __stdcall Hstrnicmp(HPSTR hpStr1, HPSTR hpStr2, long nSize)
{
	return (Hstrfunc2(hpStr1, hpStr2, Func_strnicmp, nSize)) ;
}

#endif
