/*
Copyright 1990-2003 Sun Microsystems, Inc. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions: The above copyright notice and this
permission notice shall be included in all copies or substantial
portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.


Except as contained in this notice, the names of The Open Group and/or
Sun Microsystems, Inc. shall not be used in advertising or otherwise to
promote the sale, use or other dealings in this Software without prior
written authorization from The Open Group and/or Sun Microsystems,
Inc., as applicable.


X Window System is a trademark of The Open Group

OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
logo, LBX, X Window System, and Xinerama are trademarks of the Open
Group. All other trademarks and registered trademarks mentioned herein
are the property of their respective owners. No right, title or
interest in or to any trademark, service mark, logo or trade name of
Sun Microsystems, Inc. or its licensors is granted.

*/

/*
**  Operations on JWORD.
*/

#include "PYIM.h"

VOID    GetAsciiFromJword(JWORD* pwJwordArray, CHAR* szAsciiArray, JINT nLen);
JINT    JwordValidLen(JWORD* pwJwordArray, JINT nMaxLen);
JINT    JwordHanziLen(JWORD* pwJwordArray, JINT nMaxLen);
JINT    JwordStrStrReplace(JWORD* pwDst, JWORD* pwSrc1, JWORD* pwSrc2, JINT nLenSrc2);
JWORD*  StrToJword(CHAR* szStr);
VOID    JwordInfo(JWORD* pwJwordArray, JINT nMaxLen);
VOID    Jword2Uchar(JWORD* pwJword, UCHAR* szUch, JINT nMaxLen);
UCHAR*  RecovDyz2244(UCHAR *szDyz2244);
JINT    JwordNCmp(JWORD* pwSrc1, JWORD* pwSrc2, JINT nNum);
VOID    JwordNCpy(JWORD* pwDst, JWORD* pwSrc, JINT nLen);

JWORD * JwordCopy(JWORD *w1, JWORD *w2) {
    while(*w2 != 0) *w1 ++ = *w2 ++;
    *w1 = 0;
    return w1;
}

JWORD * JwordCat(JWORD *w1, JWORD *w2) {
    while(*w1 != 0) w1 ++;
    while(*w2 != 0) *w1 ++ = *w2 ++;
    *w1 = 0;
    return w1;
}

JINT JwordLen(JWORD *w) {
    JINT i = 0;
    while(*w ++ != 0) i ++;
    return i;
}

/*
**  Convert CHAR* to JWORD*. Zero was appended.
*/
JWORD* StrToJword(CHAR* szStr)
{
	JINT    i, nLen;
	static  JWORD*  pwRet = NULL;	
	
	nLen = strlen(szStr);
	
	free(pwRet);
	pwRet = (JWORD*)malloc((nLen + MALIGN) * sizeof(JWORD));
	if(pwRet == NULL)
	{
		fprintf (stderr, "Failed to alloc Memory in StrToJword().\n");
		exit (FALSE);
	}
	memset(pwRet, '\0', (nLen + MALIGN) * sizeof(JWORD));

	for (i = 0; i < nLen; i++)
		pwRet[i]  = (JWORD)szStr[i];
	
	return pwRet;
}

/*
**  List JWORD Array Information.
**  For Debug Only.
*/
VOID JwordInfo(JWORD* pwJwordArray, JINT nMaxLen)
{
	JINT    i, j, nLen;
	JWORD   wTmp;
	UCHAR   szStr[1024];
	
	nLen = JwordValidLen(pwJwordArray, nMaxLen);

	memset(szStr, '\0', 1024);

	i = j = 0;
	for (i = 0; i < nLen; i++)
	{
		wTmp = *(pwJwordArray + i);
		if ( (wTmp & 0xFF00) > 0)
		{
			*(szStr + j) = (UCHAR)(( wTmp & 0xFF00) >> 8);
			j++;
			
			*(szStr + j) = (UCHAR)(wTmp & 0x00FF);
			j++;
		}
		else if ((wTmp < 0x0080) && (wTmp != 0x0009))
		{
			*(szStr + j)  = (UCHAR)(wTmp & 0x00FF);
			j++;
		}
	}
	
	fprintf (stderr, "%d  %s\n", j, szStr);
/*	fprintf (stderr, "%d  %s\n", j, RecovDyz2244(szStr));	*/
}


/*
**  Search pwDst for the first occurance of pwSrc1, and replace it with
**  pwSrc2. The length of pwSrc2 is indicated in argument nLenSrc2.
**
**  If pwSrc1 is not found in pwDst, False is return.
**  Call function must assure pwDst big enough to contain all the 
**  replaced pwSrc2.
**
**  NOTICE: This function is not designed for general usage!!!!
**          Because there are assumptions about the length of pwDst,
**          pwSrc1, pwSrc2!!!! 
*/
JINT JwordStrStrReplace(JWORD* pwDst, JWORD* pwSrc1, JWORD* pwSrc2, JINT nLenSrc2)
{
	JINT   i, j, k, nLenDst, nLenSrc1, nFoundFlag, nFirstAddr;
	
	nFoundFlag = 0;
	nLenDst    = JwordValidLen(pwDst, 256);
	nLenSrc1   = JwordValidLen(pwSrc1, 80);
	
	/*
	**  Find the startup offset in PwDst.
	**  THE FOLLOWING CODE TO BE TESTED TO REPLACE ABOVE CODE!! MXL 97-12-06
	*/
	i = j = k = 0;
	for(i = 0; (i < nLenDst) && (j < nLenSrc1); i++)
	{
		if (pwDst[i] == pwSrc1[j])
			j++;
		else
			j = 0;
	}

	if (j == nLenSrc1)
	{
#ifdef _DEBUG
		/* If there is a SPACE char in the end of found pwSrc1 in pwDst. */
		if ( pwDst[i] == (JWORD)' ')
		{
			fprintf (stderr, "JwordStrStrReplace():  THERE IS A SPACE!\n");
			nLenSrc1 += 1;
		}
#endif

		/* 
		**  NOTES: Don't change the sequence of the following exchange and 
		**  the FOR sentence sequence 
		*/
		nFirstAddr = i - j;
		if (nLenSrc1 >= nLenSrc2)
		{
			for (i = nFirstAddr; i < (nFirstAddr + nLenSrc2); i++)
				pwDst[i]  = pwSrc2[i - nFirstAddr];
			for (i = (nFirstAddr + nLenSrc2); i < (nLenDst - (nLenSrc1 - nLenSrc2)); i++)
				pwDst[i]  = pwDst[i + (nLenSrc1 - nLenSrc2)];
			for (i = (nLenDst - (nLenSrc1 - nLenSrc2)); i < 256; i++)
				pwDst[i]  = 0x0000;
		}
		else if (nLenSrc1 < nLenSrc2)
		{
			for (i = (nLenDst + (nLenSrc2 - nLenSrc1)); i < 256; i++)
				pwDst[i]  = 0x0000;
			for (i = (nFirstAddr + nLenSrc2); i < (nLenDst + nLenSrc2 - nLenSrc1); i++)
				pwDst[i]  = pwDst[i - (nLenSrc2 - nLenSrc1)];
			for (i = nFirstAddr; i < (nFirstAddr + nLenSrc2); i++)
				pwDst[i]  = pwSrc2[i - nFirstAddr];
		}
		return TRUE;
	}
	else
	{
#ifdef _DEBUG
		fprintf(stderr, "Cannot find string to be replaced in pwdst. JwordStrStrReplace().\n");
#endif
		return FALSE;
	}
}


/*
**  Get the valid length of JWORD array in 16 bits. 
**  Valid means contains really data.
*/
JINT JwordValidLen(JWORD* pwJwordArray, JINT nMaxLen)
{
	JINT   i, nValidLen;
	
	i = 0;
	nValidLen = 0;
	while ((i < nMaxLen) && (*(pwJwordArray + i) != 0))
	{
		i++;
		nValidLen++;
	}
		
	return nValidLen;
}


/*
**  Get the Hanzi Number in Jword Array.
**  Notice:   Hanzi is in GBK2244.
**
**  MXL: 97-12-27: TO be rewroten????
*/
JINT JwordHanziLen(JWORD* pwJwordArray, JINT nMaxLen)
{
	JINT   i, nValidLen;
	
	i = 0;
	nValidLen = 0;
	while ((i < nMaxLen) && (pwJwordArray[i] != 0))
	{
		i++;
		if (pwJwordArray[i] != 0x0009)
			nValidLen++;
	}
		
	return nValidLen;
}


/*
**  Assume szAsciiArray is big enough to contain all ASCII characters in pwJwordArray.
**  End part of szAsciiArray was filled with '\0'
*/
VOID GetAsciiFromJword(JWORD* pwJwordArray, CHAR* szAsciiArray, JINT nLen)
{
	JINT   i, j;
	
	i = j = 0;
	for (i = 0; i < nLen; i++)
	{
		if ( *(pwJwordArray + i) < 0x0080)
		{
			*(szAsciiArray + j) = (CHAR)(*(pwJwordArray + i));
			j++;
		}
	}
	
	for ( ; j < nLen; j++)
		*(szAsciiArray + j) = '\0';
}


/*
**  Convert a Jword array to UCHAR string. Max Length of pwJword is
**  given in parameter nMaxLen. Caller must assure that size of szUch 
**  is 2 * nMaxLen.
**
**  Notice: nMaxLen is in JWORD, not in BYTE!!
*/
VOID Jword2Uchar(JWORD* pwJword, UCHAR* szUch, JINT nMaxLen)
{
	JINT     i, j;
	
	j = 0;
	for(i = 0; i < nMaxLen; i++)
	{
		if(pwJword[i] >= 0x0100)		/* OR 0x8140: First char defined in GBK */
		{
			szUch[j++] = (UCHAR)((pwJword[i] & 0xFF00) >> 8);
			szUch[j++] = (UCHAR)(pwJword[i] & 0x00FF);
		}
		else
			szUch[j++] = (UCHAR)(pwJword[i] & 0x00FF);
	}
}


/*
**  This Function similar to strncmp() in standard ANSI library.
**  RETURN:  0        pwSrc1 == pwSrc2
**          -1        pwSrc1 <  pwSrc2
**           1        pwSrc1 >  pwSrc2
**
**  Notice: because Jword hava no StringZero characteristics,
**          SO, must give a proper nNum value!!!
**          nNum is in JWORD, not in BYTE!!
*/
JINT JwordNCmp(JWORD* pwSrc1, JWORD* pwSrc2, JINT nNum)
{
	JINT    i;
	JINT    nRet;

	nRet = 0;
	for(i = 0; (i < nNum) && (nRet == 0); i++)
	{
		if(pwSrc1[i] > pwSrc2[i])
		{
			nRet = 1;
			break;
		}
		else if(pwSrc1[i] < pwSrc2[i])
		{
			nRet = -1;
			break;
		}
	}

	return nRet;
}


VOID JwordNCpy(JWORD* pwDst, JWORD* pwSrc, JINT nLen)
{
	JINT    i;
	
	for (i = 0; i < nLen; i++)
		pwDst[i] = pwSrc[i];
}

