fis-gtm/sr_port/sorts_after.c

86 lines
2.6 KiB
C

/****************************************************************
* *
* Copyright 2001, 2012 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. *
* *
****************************************************************/
/*
* SORTS_AFTER.C
*
* Determine the relative sorting order of two mval's.
* Uses an alternate local collation sequence if present.
*
* Returns:
* > 0 : lhs ]] rhs (lhs ]] rhs is true)
* 0 : lhs = rhs (lhs ]] rhs is false)
* < 0 : lha ']] rhs (lhs ]] rhs is false)
*/
#include "mdef.h"
#include "gtm_string.h"
#include "error.h"
#include "collseq.h"
#include "mmemory.h"
#include "do_xform.h"
#include "numcmp.h"
#include "sorts_after.h"
#include "gtm_maxstr.h"
long sorts_after (mval *lhs, mval *rhs)
{
int cmp;
int length1;
int length2;
mstr tmstr1;
mstr tmstr2;
MAXSTR_BUFF_DECL(tmp)
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
if (!TREF(local_coll_nums_as_strings))
{ /* If numbers collate normally (ahead of strings), check if either of the operands is a number */
if (MV_IS_CANONICAL(lhs))
{ /* lhs is a number */
if (MV_IS_CANONICAL(rhs))
{ /* Both lhs and rhs are numbers */
return numcmp(lhs, rhs);
}
/* lhs is a number, but rhs is a string; return false unless rhs is null */
return (0 == rhs->str.len) ? 1 : -1;
}
/* lhs is a string */
if (MV_IS_CANONICAL(rhs))
{ /* lhs is a string, but rhs is a number; return true unless lhs is null */
return (0 != lhs->str.len) ? 1 : -1;
}
}
/* In case either lhs or rhs is not of type MV_STR, force them to be, as we are only doing string
* comparisons beyond this point.
*/
MV_FORCE_STR(lhs);
MV_FORCE_STR(rhs);
if (TREF(local_collseq))
{
ALLOC_XFORM_BUFF(lhs->str.len);
tmstr1.len = TREF(max_lcl_coll_xform_bufsiz);
tmstr1.addr = TREF(lcl_coll_xform_buff);
assert(NULL != TREF(lcl_coll_xform_buff));
do_xform(TREF(local_collseq), XFORM, &lhs->str, &tmstr1, &length1);
MAXSTR_BUFF_INIT_RET;
tmstr2.addr = tmp;
tmstr2.len = MAXSTR_BUFF_ALLOC(rhs->str.len, tmstr2.addr, 0);
do_xform(TREF(local_collseq), XFORM, &rhs->str, &tmstr2, &length2);
MAXSTR_BUFF_FINI;
cmp = memcmp(tmstr1.addr, tmstr2.addr, length1 <= length2 ? length1 : length2);
return cmp != 0 ? cmp : length1 - length2;
}
/* Do a regular string comparison if no collation options are specified */
return memvcmp(lhs->str.addr, lhs->str.len, rhs->str.addr, rhs->str.len);
}