fis-gtm/sr_port/format2zwr.c

213 lines
5.1 KiB
C

/****************************************************************
* *
* Copyright 2001, 2007 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "mlkdef.h"
#include "zshow.h"
#include "patcode.h"
#include "compiler.h" /* for CHARMAXARGS */
#ifdef UNICODE_SUPPORTED
#include "gtm_icu_api.h" /* U_ISPRINT() needs this header */
#include "gtm_utf8.h"
#endif
GBLREF uint4 *pattern_typemask;
GBLREF boolean_t gtm_utf8_mode;
/* Routine to convert a string to ZWRITE format. Used by the utiltities.
* NOTE: this routine does almost the same formatting as mval_write(). The reason
* for not using mval_write() is because it is much more complex than we need
* here. Moreover, this version is more efficient due to the availability of
* pre-allocated destination buffer */
int format2zwr(sm_uc_ptr_t src, int src_len, unsigned char *des, int *des_len)
{
sm_uc_ptr_t cp;
uint4 ch;
int fastate = 0, ncommas, dstlen, chlen;
boolean_t isctl, isill;
uchar_ptr_t srctop, strnext, tmpptr;
dstlen = *des_len = 0;
if (src_len > 0)
{
srctop = src + src_len;
fastate = 0;
/* deals with the other characters */
for (cp = src; cp < srctop; cp += chlen)
{
if (!gtm_utf8_mode)
{
ch = *cp;
isctl = ((pattern_typemask[ch] & PATM_C) != 0);
isill = FALSE;
chlen = 1;
}
#ifdef UNICODE_SUPPORTED
else {
strnext = UTF8_MBTOWC(cp, srctop, ch);
isill = (WEOF == ch) ? (ch = *cp, TRUE) : FALSE;
if (!isill)
isctl = !U_ISPRINT(ch);
chlen = (int)(strnext - cp);
}
#endif
switch(fastate)
{
case 0: /* beginning of the string */
case 1: /* beginning of a new substring followed by a graphic character */
if (isill)
{
if (dstlen > 0)
{
des[dstlen++] = '"';
des[dstlen++] = '_';
}
MEMCPY_LIT(des + dstlen, DOLLARZCH);
dstlen += STR_LIT_LEN(DOLLARZCH);
I2A(des, dstlen, ch);
fastate = 3;
ncommas = 0;
} else if (isctl)
{
if (dstlen > 0)
{ /* close previous string with quote and prepare for concatenation */
des[dstlen++] = '"';
des[dstlen++] = '_';
}
MEMCPY_LIT(des + dstlen, DOLLARCH);
dstlen += STR_LIT_LEN(DOLLARCH);
I2A(des, dstlen, ch);
fastate = 2;
ncommas = 0;
} else
{ /* graphic characters */
if (0 == fastate) /* the initial quote in the beginning */
{
des[dstlen++] = '"';
fastate = 1;
}
if ('"' == ch)
des[dstlen++] = '"';
if (!gtm_utf8_mode)
des[dstlen++] = ch;
else {
memcpy(&des[dstlen], cp, chlen);
dstlen += chlen;
}
}
break;
case 2: /* subsequent characters following a non-graphic character in the
form of $CHAR(x,) */
if (isill)
{
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARZCH);
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARZCH);
I2A(des, dstlen, ch);
fastate = 3;
} else if(isctl)
{
ncommas++;
if (CHARMAXARGS == ncommas)
{
ncommas = 0;
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARCH);
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARCH);
} else
{
MEMCPY_LIT(des + dstlen, COMMA);
dstlen += STR_LIT_LEN(COMMA);
}
I2A(des, dstlen, ch);
} else
{
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_QUOTE);
dstlen += STR_LIT_LEN(CLOSE_PAREN_QUOTE);
if (!gtm_utf8_mode)
des[dstlen++] = ch;
else {
memcpy(&des[dstlen], cp, chlen);
dstlen += chlen;
}
if ('"' == ch)
des[dstlen++] = '"';
fastate = 1;
}
break;
case 3: /* subsequent characters following an illegal character in the form of $ZCHAR(x,) */
if(isill)
{
ncommas++;
if (CHARMAXARGS == ncommas)
{
ncommas = 0;
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARZCH);
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARZCH);
} else
{
MEMCPY_LIT(des + dstlen, COMMA);
++dstlen;
}
I2A(des, dstlen, ch);
} else if (isctl)
{
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARCH);
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARCH);
I2A(des, dstlen, ch);
fastate = 2;
} else
{
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_QUOTE);
dstlen += STR_LIT_LEN(CLOSE_PAREN_QUOTE);
if (!gtm_utf8_mode)
des[dstlen++] = ch;
else {
memcpy(&des[dstlen], cp, chlen);
dstlen += chlen;
}
if ('"' == ch)
des[dstlen++] = '"';
fastate = 1;
}
break;
default:
assert(FALSE);
break;
}
}
/* close up */
switch(fastate)
{
case 1:
des[dstlen++] = '"';
break;
case 2:
case 3:
des[dstlen++] = ')';
break;
default:
assert(FALSE);
break;
}
} else
{
des[0] = des[1] = '"';
dstlen = 2;
}
*des_len = dstlen;
return 0;
}