//	Zinc Application Framework - Z_STRING.CPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#include <z_env.hpp>
#include <z_string.hpp>

#if defined(ZAF_UNICODE)
#	include "u_string.cpp"
#elif defined(ZAF_ISO8859_1)
#	define LENGTHOF(x)	(int)(sizeof(x)/sizeof((x)[0]))

int ZafStrColl(const ZafIChar *s1, const ZafIChar *s2)
{
	size_t max1 = 2*3*strlen(s1);
	size_t max2 = 2*3*strlen(s2);
	ZafIChar *cmp1 = new ZafIChar[max1];
	ZafIChar *cmp2 = new ZafIChar[max2];

#undef strxfrm
	strxfrm(cmp1, s1, max1);
	strxfrm(cmp2, s2, max2);
	int i = strcmp(cmp1, cmp2);
	delete []cmp1;
	delete []cmp2;
	return (i);
}

int ZafStrXFrm(ZafIChar *s1, const ZafIChar *s2, int n)
{
	// This algorithm is taken from CSA Z243.4.1-1992
	// Canadian Alphanumeric Ordering Standard for Character Sets of
	// CSA Standard CAN/CSA-Z243.4 (ISO 8859-1).
	static struct
	{
		ZafIChar ch;
		ZafIChar val;
	} ZAF_FARDATA table2[] = {
		{ (ZafIChar)0x20, (ZafIChar)32 },
		{ (ZafIChar)0x21, (ZafIChar)40 },
		{ (ZafIChar)0x22, (ZafIChar)56 },
		{ (ZafIChar)0x23, (ZafIChar)82 },
		{ (ZafIChar)0x24, (ZafIChar)76 },
		{ (ZafIChar)0x25, (ZafIChar)83 },
		{ (ZafIChar)0x26, (ZafIChar)87 },
		{ (ZafIChar)0x27, (ZafIChar)53 },
		{ (ZafIChar)0x28, (ZafIChar)61 },
		{ (ZafIChar)0x29, (ZafIChar)63 },
		{ (ZafIChar)0x2A, (ZafIChar)79 },
		{ (ZafIChar)0x2B, (ZafIChar)85 },
		{ (ZafIChar)0x2C, (ZafIChar)37 },
		{ (ZafIChar)0x2D, (ZafIChar)36 },
		{ (ZafIChar)0x2E, (ZafIChar)45 },
		{ (ZafIChar)0x2F, (ZafIChar)44 },
		{ (ZafIChar)0x3A, (ZafIChar)39 },
		{ (ZafIChar)0x3B, (ZafIChar)38 },
		{ (ZafIChar)0x3C, (ZafIChar)91 },
		{ (ZafIChar)0x3D, (ZafIChar)93 },
		{ (ZafIChar)0x3E, (ZafIChar)95 },
		{ (ZafIChar)0x3F, (ZafIChar)42 },
		{ (ZafIChar)0x40, (ZafIChar)73 },
		{ (ZafIChar)0x5B, (ZafIChar)65 },
		{ (ZafIChar)0x5C, (ZafIChar)80 },
		{ (ZafIChar)0x5D, (ZafIChar)66 },
		{ (ZafIChar)0x5E, (ZafIChar)48 },
		{ (ZafIChar)0x5F, (ZafIChar)33 },
		{ (ZafIChar)0x60, (ZafIChar)47 },
		{ (ZafIChar)0x7B, (ZafIChar)67 },
		{ (ZafIChar)0x7C, (ZafIChar)97 },
		{ (ZafIChar)0x7D, (ZafIChar)68 },
		{ (ZafIChar)0x7E, (ZafIChar)50 },
		{ (ZafIChar)0xA1, (ZafIChar)41 },
		{ (ZafIChar)0xA2, (ZafIChar)75 },
		{ (ZafIChar)0xA3, (ZafIChar)77 },
		{ (ZafIChar)0xA4, (ZafIChar)74 },
		{ (ZafIChar)0xA5, (ZafIChar)78 },
		{ (ZafIChar)0xA6, (ZafIChar)98 },
		{ (ZafIChar)0xA7, (ZafIChar)69 },
		{ (ZafIChar)0xA8, (ZafIChar)49 },
		{ (ZafIChar)0xA9, (ZafIChar)71 },
		{ (ZafIChar)0xAB, (ZafIChar)59 },
		{ (ZafIChar)0xAC, (ZafIChar)96 },
		{ (ZafIChar)0xAD, (ZafIChar)35 },
		{ (ZafIChar)0xAE, (ZafIChar)72 },
		{ (ZafIChar)0xAF, (ZafIChar)34 },
		{ (ZafIChar)0xB0, (ZafIChar)99 },
		{ (ZafIChar)0xB1, (ZafIChar)87 },
		{ (ZafIChar)0xB4, (ZafIChar)46 },
		{ (ZafIChar)0xB5, (ZafIChar)100 },
		{ (ZafIChar)0xB6, (ZafIChar)70 },
		{ (ZafIChar)0xB7, (ZafIChar)51 },
		{ (ZafIChar)0xB8, (ZafIChar)52 },
		{ (ZafIChar)0xBB, (ZafIChar)60 },
		{ (ZafIChar)0xBF, (ZafIChar)43 },
		{ (ZafIChar)0xD7, (ZafIChar)89 },
		{ (ZafIChar)0xF7, (ZafIChar)88 },
	};
	static struct
	{
		ZafIChar ch;
		ZafIChar col2;
		ZafIChar col3;
		ZafIChar col4;
	} ZAF_FARDATA table1[] =
	{
		{ (ZafIChar)0x30,  (ZafIChar)48, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x31,  (ZafIChar)49, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x32,  (ZafIChar)50, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x33,  (ZafIChar)51, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x34,  (ZafIChar)52, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x35,  (ZafIChar)53, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x36,  (ZafIChar)54, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x37,  (ZafIChar)55, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x38,  (ZafIChar)56, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x39,  (ZafIChar)57, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x41,  (ZafIChar)97, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x42,  (ZafIChar)98, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x43,  (ZafIChar)99, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x44, (ZafIChar)100, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x45, (ZafIChar)101, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x46, (ZafIChar)102, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x47, (ZafIChar)103, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x48, (ZafIChar)104, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x49, (ZafIChar)105, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x4A, (ZafIChar)106, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x4B, (ZafIChar)107, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x4C, (ZafIChar)108, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x4D, (ZafIChar)109, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x4E, (ZafIChar)110, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x4F, (ZafIChar)111, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x50, (ZafIChar)112, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x51, (ZafIChar)113, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x52, (ZafIChar)114, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x53, (ZafIChar)115, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x54, (ZafIChar)116, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x55, (ZafIChar)117, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x56, (ZafIChar)118, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x57, (ZafIChar)119, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x58, (ZafIChar)120, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x59, (ZafIChar)121, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x5A, (ZafIChar)122, (ZafIChar)15, (ZafIChar)10 },
		{ (ZafIChar)0x61,  (ZafIChar)97, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x62,  (ZafIChar)98, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x63,  (ZafIChar)99, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x64, (ZafIChar)100, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x65, (ZafIChar)101, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x66, (ZafIChar)102, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x67, (ZafIChar)103, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x68, (ZafIChar)104, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x69, (ZafIChar)105, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x6A, (ZafIChar)106, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x6B, (ZafIChar)107, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x6C, (ZafIChar)108, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x6D, (ZafIChar)109, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x6E, (ZafIChar)110, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x6F, (ZafIChar)111, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x70, (ZafIChar)112, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x71, (ZafIChar)113, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x72, (ZafIChar)114, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x73, (ZafIChar)115, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x74, (ZafIChar)116, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x75, (ZafIChar)117, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x76, (ZafIChar)118, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x77, (ZafIChar)119, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x78, (ZafIChar)120, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x79, (ZafIChar)121, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0x7A, (ZafIChar)122, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0xA0,  (ZafIChar)32, (ZafIChar)15,  (ZafIChar)7 },
		{ (ZafIChar)0xAA,  (ZafIChar)97, (ZafIChar)16,  (ZafIChar)9 },
		{ (ZafIChar)0xB2,  (ZafIChar)50, (ZafIChar)15,  (ZafIChar)9 },
		{ (ZafIChar)0xB3,  (ZafIChar)51, (ZafIChar)15,  (ZafIChar)9 },
		{ (ZafIChar)0xB9,  (ZafIChar)49, (ZafIChar)15,  (ZafIChar)9 },
		{ (ZafIChar)0xBA, (ZafIChar)111, (ZafIChar)16,  (ZafIChar)9 },
		{ (ZafIChar)0xBC,  (ZafIChar)48, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xBD,  (ZafIChar)48, (ZafIChar)22,  (ZafIChar)7 },
		{ (ZafIChar)0xBE,  (ZafIChar)48, (ZafIChar)24,  (ZafIChar)7 },
		{ (ZafIChar)0xC0,  (ZafIChar)97, (ZafIChar)19, (ZafIChar)10 },
		{ (ZafIChar)0xC1,  (ZafIChar)97, (ZafIChar)18, (ZafIChar)10 },
		{ (ZafIChar)0xC2,  (ZafIChar)97, (ZafIChar)20, (ZafIChar)10 },
		{ (ZafIChar)0xC3,  (ZafIChar)97, (ZafIChar)23, (ZafIChar)10 },
		{ (ZafIChar)0xC4,  (ZafIChar)97, (ZafIChar)22, (ZafIChar)10 },
		{ (ZafIChar)0xC5,  (ZafIChar)97, (ZafIChar)21, (ZafIChar)10 },
		{ (ZafIChar)0xC6,  (ZafIChar)97, (ZafIChar)17, (ZafIChar)10 },
		{ (ZafIChar)0xC7,  (ZafIChar)99, (ZafIChar)25, (ZafIChar)10 },
		{ (ZafIChar)0xC8, (ZafIChar)101, (ZafIChar)19, (ZafIChar)10 },
		{ (ZafIChar)0xC9, (ZafIChar)101, (ZafIChar)18, (ZafIChar)10 },
		{ (ZafIChar)0xCA, (ZafIChar)101, (ZafIChar)20, (ZafIChar)10 },
		{ (ZafIChar)0xCB, (ZafIChar)101, (ZafIChar)22, (ZafIChar)10 },
		{ (ZafIChar)0xCC, (ZafIChar)105, (ZafIChar)19, (ZafIChar)10 },
		{ (ZafIChar)0xCD, (ZafIChar)105, (ZafIChar)18, (ZafIChar)10 },
		{ (ZafIChar)0xCE, (ZafIChar)105, (ZafIChar)20, (ZafIChar)10 },
		{ (ZafIChar)0xCF, (ZafIChar)105, (ZafIChar)22, (ZafIChar)10 },
		{ (ZafIChar)0xD0, (ZafIChar)100, (ZafIChar)16, (ZafIChar)10 },
		{ (ZafIChar)0xD1, (ZafIChar)110, (ZafIChar)23, (ZafIChar)10 },
		{ (ZafIChar)0xD2, (ZafIChar)111, (ZafIChar)19, (ZafIChar)10 },
		{ (ZafIChar)0xD3, (ZafIChar)111, (ZafIChar)18, (ZafIChar)10 },
		{ (ZafIChar)0xD4, (ZafIChar)111, (ZafIChar)20, (ZafIChar)10 },
		{ (ZafIChar)0xD5, (ZafIChar)111, (ZafIChar)23, (ZafIChar)10 },
		{ (ZafIChar)0xD6, (ZafIChar)111, (ZafIChar)22, (ZafIChar)10 },
		{ (ZafIChar)0xD8, (ZafIChar)111, (ZafIChar)24, (ZafIChar)10 },
		{ (ZafIChar)0xD9, (ZafIChar)117, (ZafIChar)19, (ZafIChar)10 },
		{ (ZafIChar)0xDA, (ZafIChar)117, (ZafIChar)18, (ZafIChar)10 },
		{ (ZafIChar)0xDB, (ZafIChar)117, (ZafIChar)20, (ZafIChar)10 },
		{ (ZafIChar)0xDC, (ZafIChar)117, (ZafIChar)22, (ZafIChar)10 },
		{ (ZafIChar)0xDD, (ZafIChar)121, (ZafIChar)18, (ZafIChar)10 },
		{ (ZafIChar)0xDE, (ZafIChar)116, (ZafIChar)16, (ZafIChar)10 },
		{ (ZafIChar)0xDF, (ZafIChar)115, (ZafIChar)17,  (ZafIChar)7 },
		{ (ZafIChar)0xE0,  (ZafIChar)97, (ZafIChar)19,  (ZafIChar)7 },
		{ (ZafIChar)0xE1,  (ZafIChar)97, (ZafIChar)18,  (ZafIChar)7 },
		{ (ZafIChar)0xE2,  (ZafIChar)97, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xE3,  (ZafIChar)97, (ZafIChar)23,  (ZafIChar)7 },
		{ (ZafIChar)0xE4,  (ZafIChar)97, (ZafIChar)22,  (ZafIChar)7 },
		{ (ZafIChar)0xE5,  (ZafIChar)97, (ZafIChar)21,  (ZafIChar)7 },
		{ (ZafIChar)0xE6,  (ZafIChar)97, (ZafIChar)17,  (ZafIChar)7 },
		{ (ZafIChar)0xE7,  (ZafIChar)99, (ZafIChar)25,  (ZafIChar)7 },
		{ (ZafIChar)0xE8, (ZafIChar)101, (ZafIChar)19,  (ZafIChar)7 },
		{ (ZafIChar)0xE9, (ZafIChar)101, (ZafIChar)18,  (ZafIChar)7 },
		{ (ZafIChar)0xEA, (ZafIChar)101, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xEB, (ZafIChar)101, (ZafIChar)22,  (ZafIChar)7 },
		{ (ZafIChar)0xEC, (ZafIChar)105, (ZafIChar)19,  (ZafIChar)7 },
		{ (ZafIChar)0xED, (ZafIChar)105, (ZafIChar)18,  (ZafIChar)7 },
		{ (ZafIChar)0xEE, (ZafIChar)105, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xEF, (ZafIChar)105, (ZafIChar)22,  (ZafIChar)7 },
		{ (ZafIChar)0xF0, (ZafIChar)100, (ZafIChar)16,  (ZafIChar)7 },
		{ (ZafIChar)0xF1, (ZafIChar)110, (ZafIChar)23,  (ZafIChar)7 },
		{ (ZafIChar)0xF2, (ZafIChar)111, (ZafIChar)19,  (ZafIChar)7 },
		{ (ZafIChar)0xF3, (ZafIChar)111, (ZafIChar)18,  (ZafIChar)7 },
		{ (ZafIChar)0xF4, (ZafIChar)111, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xF5, (ZafIChar)111, (ZafIChar)23,  (ZafIChar)7 },
		{ (ZafIChar)0xF6, (ZafIChar)111, (ZafIChar)22,  (ZafIChar)7 },
		{ (ZafIChar)0xF8, (ZafIChar)111, (ZafIChar)24,  (ZafIChar)7 },
		{ (ZafIChar)0xF9, (ZafIChar)117, (ZafIChar)19,  (ZafIChar)7 },
		{ (ZafIChar)0xFA, (ZafIChar)117, (ZafIChar)18,  (ZafIChar)7 },
		{ (ZafIChar)0xFB, (ZafIChar)117, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xFC, (ZafIChar)117, (ZafIChar)22,  (ZafIChar)7 },
		{ (ZafIChar)0xFD, (ZafIChar)121, (ZafIChar)18,  (ZafIChar)7 },
		{ (ZafIChar)0xFE, (ZafIChar)116, (ZafIChar)20,  (ZafIChar)7 },
		{ (ZafIChar)0xFF, (ZafIChar)121, (ZafIChar)22,  (ZafIChar)7 },
	},
	ZAF_FARDATA table1b[] =
	{
		{ (ZafIChar)0xC6, (ZafIChar)101, (ZafIChar)17, (ZafIChar)10 },
		{ (ZafIChar)0xDE, (ZafIChar)104, (ZafIChar)16, (ZafIChar)10 },
		{ (ZafIChar)0xDF, (ZafIChar)115, (ZafIChar)17,  (ZafIChar)7 },
		{ (ZafIChar)0xE6, (ZafIChar)101, (ZafIChar)17,  (ZafIChar)7 },
		{ (ZafIChar)0xFE, (ZafIChar)104, (ZafIChar)16,  (ZafIChar)7 },
	};

	size_t i = strlen(s2) + 1;
	ZafIChar *cpo = new ZafIChar[2*i];
	ZafIChar *cso = new ZafIChar[2*i];
	ZafIChar *cto = new ZafIChar[2*i];
	ZafIChar *cqo = new ZafIChar[2*i];
	int cpopos = 0, csopos = (int)(2*i), ctopos = 0, cqopos = 0;

	cso[--csopos] = 0;
	for (i = 0; s2[i]; i++)
	{
		int j;
		for (j = 0; j < LENGTHOF(table2); j++)
			if (table2[j].ch == s2[i])
			{
				cqo[cqopos++] = (ZafIChar)(i + 1);
				cqo[cqopos++] = table2[j].val;
				break;
			}
		if (j == LENGTHOF(table2))
		{
			for (j=0; j < LENGTHOF(table1); j++)
				if (table1[j].ch == s2[i])
				{
					cpo[cpopos++] = table1[j].col2;
					cso[--csopos] = table1[j].col3;
					cto[ctopos++] = table1[j].col4;
					break;
				}
			for (j=0; j < LENGTHOF(table1b); j++)
				if (table1b[j].ch == s2[i])
				{
					cpo[cpopos++] = table1b[j].col2;
					cso[--csopos] = table1b[j].col3;
					cto[ctopos++] = table1b[j].col4;
					break;
				}
		}
	}
	cpo[cpopos] = cto[ctopos] = cqo[cqopos] = 0;
	size_t len = strlen(cpo)+strlen(&cso[csopos])+strlen(cto)+strlen(cqo);
	if (len < (size_t)n)
	{
		strcpy(s1, cpo);
		strcat(s1, &cso[csopos]);
		strcat(s1, cto);
		strcat(s1, cqo);
	}
	delete []cpo;
	delete []cso;
	delete []cto;
	delete []cqo;
	return ((int)len);
}

#else
	// We use the compiler's library for OEM characters
#endif
