fis-gtm/sr_port/op_fnascii.c

91 lines
2.4 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 "mvalconv.h"
#include "op.h"
#ifdef UNICODE_SUPPORTED
#include "gtm_utf8.h"
GBLREF boolean_t badchar_inhibit;
/* Returns the Unicode code point of a character in a string at a given index */
void op_fnascii(int4 num, mval* in, mval* out)
{
int bytelen;
unsigned int code;
char *in_ptr, *in_top;
num--; /* make it a 0-index based */
if (MV_IS_SINGLEBYTE(in))
{ /* Fast path evaluation for strings with no multi-byte characters */
assert(MV_IS_STRING(in)); /* MV_UTF_LEN must subsume MV_STR */
if ((num < in->str.len) && (num >= 0))
{
if ((code = *(unsigned char *)(in->str.addr + num)) > ASCII_MAX)
{
if (badchar_inhibit) /* Isolated bytes in the range [0x80,0xFF] must be considered illegal */
code = (unsigned int)-1;
else
UTF8_BADCHAR(1, in->str.addr + num, NULL, 0, NULL);
}
} else
code = (unsigned int)-1;
} else
{ /* Generic processing for strings with multi-byte characters */
MV_FORCE_STR(in);
in_ptr = in->str.addr;
in_top = in->str.addr + in->str.len;
if (!badchar_inhibit)
{
for (; (0 < num && in_ptr < in_top); --num)
{
if (!UTF8_VALID(in_ptr, in_top, bytelen))
UTF8_BADCHAR(0, in_ptr, in_top, 0, NULL);
in_ptr += bytelen;
}
} else
{
for (; (0 < num && in_ptr < in_top); --num)
in_ptr = (char *)UTF8_MBNEXT(in_ptr, in_top); /* Note: code for invalid character ?? */
}
if (0 == num && in_ptr < in_top)
{
UTF8_MBTOWC(in_ptr, in_top, code);
if (WEOF == code)
{
if (badchar_inhibit)
code = (unsigned int)-1;
else
UTF8_BADCHAR(0, in_ptr, in_top, 0, NULL);
}
} else
code = (unsigned int)-1; /* required character position exceeds the character length */
}
MV_FORCE_MVAL(out, (int)code);
}
#endif /* UNICODE_SUPPORTED */
void op_fnzascii(int4 num, mval* in, mval* out)
{
int k ;
MV_FORCE_STR(in);
num--;
if ( num >= in->str.len || num < 0 )
{
k = -1 ;
} else
k = *(unsigned char *)(in->str.addr + num) ;
MV_FORCE_MVAL(out,k) ;
}