#include "cphstr.h"

/* ========================================================================	*/
/* Declare global variable to hold Handle to DLL and PBORCA Handle
/* ========================================================================	*/
static HANDLE hDLL ;
static HPSTR lpHStrStr ;

#ifdef USE_HSTRSTR2
static HPSTR lpHStrStr2 ;
#endif

/* ========================================================================	*/
/* Main Library Routines
/* ========================================================================	*/
BOOL WINAPI DllMain ( HANDLE hInst, DWORD ul_reason_for_call, LPVOID lpReserved ) 

	{
		switch( ul_reason_for_call ) 
			{
			case DLL_PROCESS_ATTACH:

				hDLL = hInst ;
				if ((lpHStrStr = (HPSTR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (MAX_STR_LEN + 1))) == NULL)
					{
						return FALSE ;
					}
	
				#ifdef USE_HSTRSTR2
					if ((lpHStrStr2 = (HPSTR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (MAX_STR_LEN + 1))) == NULL)
					{
						return FALSE ;
					}
				#endif
	
				return TRUE;

			case DLL_THREAD_ATTACH:
				return TRUE;

			case DLL_THREAD_DETACH:
				return TRUE;

			case DLL_PROCESS_DETACH:
				return TRUE;
				break;
			}

		return TRUE;
	}

/* ========================================================================	*/
/* LoadCPHSTR: Generic function to load this DLL.
/* ========================================================================	*/
PBINT __stdcall LoadCPHSTR (PBINT iDummy)
{
	return 0 ;
}

/* ========================================================================	*/
/*  Hstrupr:  Convert string to UpperCase
/* ========================================================================	*/
HPSTR __stdcall Hstrupr(HPSTR hpStr)
{
	long lCur ;
	
	if (hpStr == NULL)
		return (NULL) ;
	
	for (lCur = 0 ; hpStr[lCur] != '\0' ; ++lCur)
		hpStr[lCur] = (char) toupper((PBINT) hpStr[lCur]) ;
	
	return (hpStr) ;
}

/* ========================================================================	*/
/*  Hstrlwr:  Convert string to LowerCase
/* ========================================================================	*/
HPSTR __stdcall Hstrlwr(HPSTR hpStr)
{
	long lCur ;
	
	if (hpStr == NULL)
		return (NULL) ;
	
	for (lCur = 0 ; hpStr[lCur] != '\0' ; ++lCur)
		hpStr[lCur] = (char) tolower((PBINT) hpStr[lCur]) ;
	
	return (hpStr) ;
}

/* ========================================================================	*/
/*  Hstrlen:  Obtain string length
/* ========================================================================	*/
long __stdcall Hstrlen(HPSTR hpStr)
{
	long nCur ;
	
	for (nCur = 0 ; hpStr[nCur] != '\0' ; ++nCur)
		;
	
	return nCur ;
}

/* ========================================================================	*/
/*  Hstrcpy:  Copy string
/* ========================================================================	*/
HPSTR __stdcall Hstrcpy(HPSTR hpStr1, HPSTR hpStr2)
{
	long lStrLen ;
	
	lStrLen = Hstrlen(hpStr2) ;
	hmemcpy((void _huge *) hpStr1, (const void _huge *) hpStr2, lStrLen) ;
	hpStr1[lStrLen] = '\0' ;
	
	return ((HPSTR) hpStr1) ;
}

/* ========================================================================	*/
/*  Hstrncpy:  Copy string for specified length
/* ========================================================================	*/
HPSTR __stdcall Hstrncpy(HPSTR hpStr1, HPSTR hpStr2, long lStrCpy)
{
	long lStrLen ;
	
	lStrLen = Hstrlen(hpStr2) ;
	if (lStrCpy < 0)
	{
		lStrCpy = 0 ;
	}
		
	if (lStrCpy <= lStrLen)
	{
		hmemcpy((void _huge *) hpStr1, (const void _huge *) hpStr2, lStrCpy) ;
		hpStr1[lStrCpy] = '\0' ;
	}
	else
	{
		hmemcpy((void _huge *) hpStr1, (const void _huge *) hpStr2, lStrLen) ;
		hpStr1[lStrLen] = '\0' ;
	}
	
	return ((HPSTR) hpStr1) ;
}

/* ========================================================================	*/
/*  Hmemset:  
/* ========================================================================	*/
void __stdcall Hmemset(void *hpSrc, char ch, long lLen)
{
	long lCur ;
	HPSTR hpStr ;
	
	hpStr = (HPSTR) hpSrc ;
	for (lCur = 0 ; lCur < lLen ; ++lCur)
		hpStr[lCur] = ch ;

}

/* ========================================================================	*/
/*  Hstrfunc:  
/* ========================================================================	*/
long __stdcall Hstrfunc(HPSTR hpSrc, HPSTR hpSearch, FuncType ftFunc)
{                                        
	long lSrc, lSearch, lCur, lFoundLen, lFoundIndex, lCurLen ;
	long iPass, iCur ;
	HPSTR hpCur, hpFound ;
	char chTmp = '\0' ;
	LPSTR (__cdecl *lpFunc1)(LPSTR lpStr1, LPSTR lpStr2) ;
	LPSTR (__cdecl *lpFunc2)(LPSTR lpStr1, int ch) ;

	lpFunc1 = NULL ;
	lpFunc2 = NULL ;
	
	switch (ftFunc)
	{
		case Func_strstr :
			lpFunc1 = _fstrstr ;
			break ;
			
		case Func_strpbrk :
			lpFunc1 = _fstrpbrk ;
			break ;
			
		case Func_strrchr :
			lpFunc2 = _fstrrchr ;
			chTmp = hpSearch[0] ;
			break ;
		
		default :
			return (-100) ;
	}

	lSrc = Hstrlen(hpSrc) ;
	lSearch = Hstrlen(hpSearch) ;
	
	hpCur = lpHStrStr ;
	
	if (lSrc <= (long) MAX_STR_LEN)
	{
		Hstrcpy(hpCur, hpSrc) ;
		if (lpFunc1 != NULL)
		{
			hpFound = (HPSTR) (*lpFunc1)((LPSTR) hpCur, (LPSTR) hpSearch) ;
		}
		else if (lpFunc2 != NULL)
		{
			hpFound = (HPSTR) (*lpFunc2)((LPSTR) hpCur, (PBINT) chTmp) ;
		}
		
		if (hpFound != NULL)
		{
			lFoundLen = Hstrlen(hpFound) ;
			lFoundIndex = lSrc - lFoundLen ;
			lFoundIndex = (lFoundIndex < 0) ? -1 : lFoundIndex ;
			return (lFoundIndex) ;
		}
		else
		{
			return (-1L) ;
		}
	}
	
	/*  else ...  */
	iPass = ((long) lSrc / (long) MAX_STR_LEN) + 1 ;
	
	for (iCur = 0 ; iCur < iPass ; ++iCur)
	{
		lCur = (iCur * MAX_STR_LEN) - lSearch + 1 ;
		if (lCur < 0)
			lCur = 0 ;
		
		Hstrncpy(hpCur, (HPSTR) &(hpSrc[lCur]), MAX_STR_LEN) ;
		if (lpFunc1 != NULL)
		{
			hpFound = (HPSTR) (*lpFunc1)((LPSTR) hpCur, (LPSTR) hpSearch) ;
		}
		else if (lpFunc2 != NULL)
		{
			hpFound = (HPSTR) (*lpFunc2)((LPSTR) hpCur, (PBINT) chTmp) ;
		}

		if (hpFound != NULL)                 
		{
			lFoundLen = Hstrlen(hpFound) ;
			lCurLen = Hstrlen(hpCur) ;
			lFoundIndex = lCur + (lCurLen - lFoundLen) ;
			lFoundIndex = (lFoundIndex < 0) ? -1 : lFoundIndex ;
			return (lFoundIndex) ;
		}
		else
		{
			return (-1L) ;
		}
	}
	
	return (-1L) ;
}

/* ========================================================================	*/
/*  Hstrstrn:  Find string in string, returns position
/* ========================================================================	*/
long __stdcall Hstrstrn(HPSTR hpSrc, LPSTR lpSearch)
{
	long lFoundIndex ;
	
	lFoundIndex = Hstrfunc(hpSrc, lpSearch, Func_strstr) ;
	
	return lFoundIndex ;
}

/* ========================================================================	*/
/*  Hstrstr:  Find string in string, returns string
/* ========================================================================	*/
HPSTR __stdcall Hstrstr(HPSTR hpSrc, LPSTR lpSearch)
{
	HPSTR hpRet ;
	long lFoundIndex ;
	
	lFoundIndex = Hstrstrn(hpSrc, lpSearch) ;
	if (lFoundIndex >= 0)
	{
		hpRet = (HPSTR) &(hpSrc[lFoundIndex]) ;
	}
	else
	{
		hpRet = NULL ;
	}
	
	return hpRet ;
}

/* ========================================================================	*/
/*  Hstrchr:  Find char in string, returns string
/* ========================================================================	*/
HPSTR __stdcall Hstrchr(HPSTR hpStr, char ch)
{
	char szch[2] ;
	
	szch[0] = ch ;
	szch[1] = '\0' ;
	
	return (Hstrstr(hpStr, (HPSTR) szch)) ;
}

/* ========================================================================	*/
/*  Hstrrchrn:  Find char in string, returns position
/* ========================================================================	*/
long __stdcall Hstrrchrn(HPSTR hpSrc, char ch)
{
	long lFoundIndex ;
	char szch[2] ;
	
	szch[0] = ch ;
	szch[1] = '\0' ;
	
	lFoundIndex = Hstrfunc(hpSrc, szch, Func_strrchr) ;
	
	return lFoundIndex ;
}

/* ========================================================================	*/
/*  Hstrrchr:  
/* ========================================================================	*/
HPSTR __stdcall Hstrrchr(HPSTR hpSrc, char ch)
{
	long lFoundIndex ;
	HPSTR hpRet ;
	
	lFoundIndex = Hstrrchrn(hpSrc, ch) ;
	if (lFoundIndex >= 0)
	{
		hpRet = (HPSTR) &(hpSrc[lFoundIndex]) ;
	}
	else
	{
		hpRet = NULL ;
	}
	
	return hpRet ;
}

/* ========================================================================	*/
/*  Hstrpbrkn:  
/* ========================================================================	*/
long __stdcall Hstrpbrkn(HPSTR hpSrc, LPSTR lpSearch)
{
	long lFoundIndex ;
	
	lFoundIndex = Hstrfunc(hpSrc, lpSearch, Func_strpbrk) ;
	
	return lFoundIndex ;
}

/* ========================================================================	*/
/*  Hstrpbrk:  
/* ========================================================================	*/
HPSTR __stdcall Hstrpbrk(HPSTR hpSrc, LPSTR lpSearch)
{
	long lFoundIndex ;
	HPSTR hpRet ;
	
	lFoundIndex = Hstrpbrkn(hpSrc, lpSearch) ;
	if (lFoundIndex >= 0)
	{
		hpRet = (HPSTR) &(hpSrc[lFoundIndex]) ;
	}
	else
	{
		hpRet = NULL ;
	}
	
	return (hpRet) ;
}

