File: do_xform.c

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (117 lines) | stat: -rw-r--r-- 3,907 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/****************************************************************
 *								*
 * Copyright (c) 2001-2024 Fidelity National Information	*
 * Services, Inc. and/or its subsidiaries. All rights reserved.	*
 *								*
 *	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 "gtm_string.h"

#include "mdef.h"
#include "gtm_descript.h"
#include "min_max.h"
#include "collseq.h"
#include "do_xform.h"
#include "memprot.h"

error_def(ERR_COLLARGLONG);
error_def(ERR_COLTRANSSTR2LONG);

void do_xform(collseq *csp, int fc_type, mstr *input, mstr *output, int *length)
{
	gtm32_descriptor	outbuff1, insub1;
	gtm_descriptor		outbuff, insub;
	int4			status;
	char			*ba, *addr;
	DEBUG_ONLY(static boolean_t in_do_xform;)
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(!in_do_xform);
	DO_XFORM_RETURN_IF_NULL_STRING(input, output, length);
	DEBUG_ONLY(in_do_xform = TRUE;)
	assert (0 == csp->argtype || 1 == csp->argtype);
	assert(XFORM == fc_type || XBACK == fc_type);
	if (0 == csp->argtype)
	{
		if (MAX_STRLEN_32K < input->len)
		{
			DEBUG_ONLY(in_do_xform = FALSE;)
			RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(3) ERR_COLLARGLONG, 1, csp->act);
		}
		insub.type = DSC_K_DTYPE_T;
		insub.len = input->len;
		insub.val = input->addr;

		outbuff.type = DSC_K_DTYPE_T;
		outbuff.len = MIN(output->len, MAX_STRLEN_32K);
		memprot(&(TREF(protmem_ba)), outbuff.len);
		ba = (TREF(protmem_ba)).addr;
		assert(NULL != ba);
		outbuff.val = (NULL != ba) ? ba : output->addr;

		if (XFORM == fc_type)
			status = (csp->xform)((gtm_descriptor_alt *)&insub, 1, (gtm_descriptor_alt *)&outbuff, length);
		else
			status = (csp->xback)((gtm_descriptor_alt *)&insub, 1, (gtm_descriptor_alt *)&outbuff, length);

		if (*length > output->len)
		{
			DEBUG_ONLY(in_do_xform = FALSE;)
			RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(3) ERR_COLTRANSSTR2LONG, 1, csp->act);
		}
		/* If collation routine has changed outbuff.val (which it will if it cannot store the transformed
		 * result in the buffer that is passed in), the transformed value is stored in the buffer allocated
		 * externally by the collation routine. In this case, update output->addr before returning. */
		addr = (NULL != ba) ? ba : output->addr;
		if (outbuff.val != addr)
			output->addr = outbuff.val;
		else if (NULL != ba)
		{
			assert(*length <= outbuff.len);
			memcpy(output->addr, ba, *length);
		}
	} else
	{
		insub1.type = DSC_K_DTYPE_T;
		insub1.len = input->len;
		insub1.val = input->addr;

		outbuff1.type = DSC_K_DTYPE_T;
		outbuff1.len = output->len;
		memprot(&(TREF(protmem_ba)), outbuff1.len);
		ba = (TREF(protmem_ba)).addr;
		assert(NULL != ba);
		outbuff1.val = (NULL != ba) ? ba : output->addr;

		if (XFORM == fc_type)
			status = (csp->xform)((gtm_descriptor_alt *)&insub1, 1, (gtm_descriptor_alt *)&outbuff1, length);
		else
			status = (csp->xback)((gtm_descriptor_alt *)&insub1, 1, (gtm_descriptor_alt *)&outbuff1, length);

		if (*length > output->len)
		{
			DEBUG_ONLY(in_do_xform = FALSE;)
			RTS_ERROR_CSA_ABT(NULL, VARLSTCNT(3) ERR_COLTRANSSTR2LONG, 1, csp->act);
		}
		/* If collation routine has changed outbuff1.val (which it will if it cannot store the transformed
		 * result in the buffer that is passed in), the transformed value is stored in the buffer allocated
		 * externally by the collation routine. In this case, update output->addr before returning. */
		addr = (NULL != ba) ? ba : output->addr;
		if (outbuff1.val != addr)
			output->addr = outbuff1.val;
		else if (NULL != ba)
		{
			assert(*length <= outbuff1.len);
			memcpy(output->addr, ba, *length);
		}
	}
	DEBUG_ONLY(in_do_xform = FALSE;)
	if (status)
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
}