2602 lines
75 KiB
C
2602 lines
75 KiB
C
/************************************************************************/
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
|
/************************************************************************/
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
|
/* 1999 - 2008, All Rights Reserved */
|
|
/* */
|
|
/* MODULE NAME : sx_data.c */
|
|
/* PRODUCT(S) : */
|
|
/* */
|
|
/* MODULE DESCRIPTION : */
|
|
/* */
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
|
/* sxd_process_arb_data */
|
|
/* */
|
|
/* MODIFICATION LOG : */
|
|
/* Date Who Rev Comments */
|
|
/* -------- --- ------ ------------------------------------------- */
|
|
/* 01/30/08 EJV 37 sprintf,sscanf: use S_FMT_* macros for ST_INT64 */
|
|
/* 01/30/06 GLB 36 Integrated porting changes for VMS */
|
|
/* 08/01/05 JRB 35 Avoid risky cast to remove const. */
|
|
/* 09/01/04 EJV 34 Added new include "sx_arb.h" */
|
|
/* 03/16/04 EJV 33 Added ST_(U)LONG typecast to sprintf,on some */
|
|
/* sys ST_(U)INT32 can be (unsigned) long or int*/
|
|
/* Use SISCO types in place of C types. */
|
|
/* 01/23/04 MDE 32 Added type ID validity checking */
|
|
/* 01/13/04 JRB 31 Add LYNX support. */
|
|
/* 01/08/04 EJV 30 Ported 64-bit funcs to sun. Corr (__hpux). */
|
|
/* 10/13/03 EJV 29 Replaced defined(QNX) with defined(__QNX__). */
|
|
/* 04/29/03 JRB 28 Use MAX_IDENT_LEN define. */
|
|
/* 04/14/03 JRB 27 Add linux support. Use #error. */
|
|
/* 04/02/03 JRB 26 Add UTF8string support (see RT_UTF8_STRING). */
|
|
/* 12/11/02 MDE 25 Now include 'mvl_defs.h' */
|
|
/* 12/02/02 MDE 24 Fixed elPres handling */
|
|
/* 04/24/02 EJV 23 Added DEBUG_SISCO for thisFileName */
|
|
/* 04/17/02 EJV 22 sxd_process_arb_data: added RT_UTC_TIME case */
|
|
/* _sxdEncArbFuns: added NULL for 'utc' fun */
|
|
/* 04/08/02 MDE 21 Added NO_MVL ifdefs to support mmslog */
|
|
/* 03/06/02 JRB 20 Add more SD_CONST. Comment out unused statics*/
|
|
/* 02/26/02 EJV 19 strStart: added SD_CONST for rt_head param. */
|
|
/* Eliminated some warnings on VXWORKS. */
|
|
/* Moved limits.h to sysincs.h and INT_MAX check*/
|
|
/* 02/25/02 EJV 18 _AIX: replace itoa, ltoa with ANSI sprintf */
|
|
/* hex_to_ascii_str: added param hex_no_spaces. */
|
|
/* 11/26/01 EJV 17 _sxdDecInt64: fixed logging. */
|
|
/* 09/13/01 JRB 16 Add limits.h so INT_MAX & LONG_MAX defined. */
|
|
/* 08/10/01 EJV 15 _sxdDecUint32: eliminated warning on QNX. */
|
|
/* 06/22/01 EJV 14 Reworked decode of arrays and releated chgs. */
|
|
/* Added rt_head param to _sxdEncStrStart. */
|
|
/* Moved globals _sxdPrefix, _sxdCurrNestLevel */
|
|
/* to SX_END_CTRL (to be thread safe). */
|
|
/* Implemented INT64 funcs: _sxdDecInt64,... */
|
|
/* 05/21/01 MDE 13 Fixed overwrite problem with bad data */
|
|
/* 05/21/01 MDE 12 Changed to work with all RUNTIME_TYPE */
|
|
/* 03/21/01 MDE 11 Fixed bitstring decode for variable len bs */
|
|
/* 03/21/01 MDE 10 Moved sx arb handling defines to sx_defs.h */
|
|
/* 02/28/01 EJV 09 _AIX: use itoa, ltoa instead of slow sprintf */
|
|
/* 02/22/01 MDE 08 Changes to support SXD style selections */
|
|
/* 02/22/01 MDE 07 Allow QNX & Win32 to use itoa, ltoa */
|
|
/* 01/24/01 EJV 06 Replaced non-ANSI itoa, ltoa with sprintf. */
|
|
/* SXD_ARB_DATA_CTRL:replaced bool with booln */
|
|
/* (bool may conflict with C++ compiler). */
|
|
/* Corrected conversion in _sxdEncDbl. */
|
|
/* 01/08/01 EJV 05 Removed unused _writePos from _sxdDecBs. */
|
|
/* 01/04/01 MDE 04 Always define MVL_DYN_ASN1_TYPES */
|
|
/* 12/28/00 KCR 03 Removed unpaired S_LOCK_COMMON_RESOURCES() */
|
|
/* 11/06/00 DWL 02 Modified sx_write_element and sx_end_element */
|
|
/* calls with added parameter */
|
|
/* 10/10/00 MDE 01 New */
|
|
/************************************************************************/
|
|
|
|
#include "glbtypes.h"
|
|
#include "sysincs.h"
|
|
#include "glbsem.h"
|
|
#include "mms_def2.h"
|
|
#include "mms_mp.h"
|
|
#include "mms_pvar.h"
|
|
#include "mms_vvar.h"
|
|
#include "time_str.h"
|
|
#include "str_util.h"
|
|
#include "mem_chk.h"
|
|
|
|
#include "sx_defs.h"
|
|
#include "sx_arb.h"
|
|
#include "sx_log.h"
|
|
|
|
#if defined(MMS_LITE) && !defined(NO_MVL)
|
|
#include "mvl_defs.h"
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* For debug version, use a static pointer to avoid duplication of */
|
|
/* __FILE__ strings. */
|
|
/************************************************************************/
|
|
|
|
#ifdef DEBUG_SISCO
|
|
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* sxd_get_runtime */
|
|
/************************************************************************/
|
|
|
|
#if defined(MMS_LITE) && !defined(NO_MVL)
|
|
|
|
ST_RET sxd_get_runtime (ST_INT type_id,
|
|
RUNTIME_TYPE **rt_out, ST_INT *num_rt_out)
|
|
{
|
|
if (type_id >= 0 && type_id < mvl_num_types &&
|
|
mvl_type_ctrl[type_id].num_rt > 0)
|
|
{
|
|
*rt_out = mvl_type_ctrl[type_id].rt;
|
|
*num_rt_out = mvl_type_ctrl[type_id].num_rt;
|
|
return (SD_SUCCESS);
|
|
}
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* sxd_process_arb_data */
|
|
/************************************************************************/
|
|
|
|
ST_RET sxd_process_arb_data (ST_CHAR *datptr, SD_CONST RUNTIME_TYPE *rt_head,
|
|
ST_INT rt_num, ST_VOID *usr,
|
|
SXD_ARB_DATA_CTRL *ac, ST_BOOLEAN *elPres)
|
|
{
|
|
RUNTIME_TYPE *rt_ptr;
|
|
RUNTIME_TYPE *rt_end;
|
|
ST_RET uDataRet;
|
|
ST_INT arr_loop_level;
|
|
ST_INT arr_loops[ASN1_MAX_LEVEL];
|
|
|
|
arr_loop_level = 0;
|
|
|
|
rt_ptr = (RUNTIME_TYPE *) rt_head; /* point to head rt_block */
|
|
rt_end = rt_ptr + rt_num; /* done when pointer is here */
|
|
|
|
uDataRet = SD_SUCCESS;
|
|
while (rt_ptr < rt_end && uDataRet == SD_SUCCESS)
|
|
{
|
|
if (rt_ptr->el_tag == RT_ARR_END) /* treat case of array ending */
|
|
{
|
|
if (--arr_loops[arr_loop_level] > 0) /* if need to do next ar elmnt */
|
|
rt_ptr -= rt_ptr->u.arr.num_rt_blks; /* mv rt_ptr to start of arr */
|
|
else
|
|
--arr_loop_level;
|
|
}
|
|
if (rt_ptr->el_tag == RT_ARR_START) /* treat case of array starting */
|
|
{
|
|
/* initialize the loop counter for the array */
|
|
++arr_loop_level;
|
|
arr_loops[arr_loop_level] = rt_ptr->u.arr.num_elmnts;
|
|
}
|
|
|
|
if (elPres != NULL)
|
|
{
|
|
if (elPres[rt_ptr - rt_head] != SD_TRUE)
|
|
{
|
|
datptr += rt_ptr->el_size; /* Adjust data pointer */
|
|
rt_ptr++; /* point to next rt element */
|
|
continue;
|
|
}
|
|
}
|
|
|
|
switch (rt_ptr->el_tag)
|
|
{
|
|
case RT_ARR_START :
|
|
if (ac->arrStart)
|
|
uDataRet = (*ac->arrStart) (usr, rt_ptr);
|
|
break;
|
|
|
|
case RT_STR_START :
|
|
if (ac->strStart)
|
|
uDataRet = (*ac->strStart) (usr, rt_ptr, rt_head);
|
|
break;
|
|
|
|
case RT_ARR_END : /* array done */
|
|
if (ac->arrEnd)
|
|
uDataRet = (*ac->arrEnd) (usr, rt_ptr);
|
|
break;
|
|
|
|
case RT_STR_END : /* structure done */
|
|
if (ac->strEnd)
|
|
uDataRet = (*ac->strEnd) (usr, rt_ptr);
|
|
break;
|
|
|
|
case RT_BOOL :
|
|
if (ac->booln)
|
|
uDataRet = (*ac->booln) (usr, (ST_BOOLEAN *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_BIT_STRING :
|
|
if (ac->bs)
|
|
uDataRet = (*ac->bs) (usr, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_INTEGER :
|
|
switch (rt_ptr->u.p.el_len) /* determine length */
|
|
{
|
|
case 1 : /* one byte int */
|
|
if (ac->int8)
|
|
uDataRet = (*ac->int8) (usr, (ST_INT8 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 2 : /* two byte int */
|
|
if (ac->int16)
|
|
uDataRet = (*ac->int16) (usr, (ST_INT16 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 4 : /* four byte integer */
|
|
if (ac->int32)
|
|
uDataRet = (*ac->int32) (usr, (ST_INT32 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
#ifdef INT64_SUPPORT
|
|
case 8 : /* eight byte integer */
|
|
if (ac->int64)
|
|
uDataRet = (*ac->int64) (usr, (ST_INT64 *) datptr, rt_ptr);
|
|
#endif
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case RT_UNSIGNED :
|
|
switch (rt_ptr->u.p.el_len) /* determine length */
|
|
{
|
|
case 1 : /* one byte int */
|
|
if (ac->uint8)
|
|
uDataRet = (*ac->uint8) (usr, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 2 : /* two byte int */
|
|
if (ac->uint16)
|
|
uDataRet = (*ac->uint16) (usr, (ST_UINT16 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 4 : /* four byte integer */
|
|
if (ac->uint32)
|
|
uDataRet = (*ac->uint32) (usr, (ST_UINT32 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
#ifdef INT64_SUPPORT
|
|
case 8 : /* eight byte integer */
|
|
if (ac->uint64)
|
|
uDataRet = (*ac->uint64) (usr, (ST_UINT64 *) datptr, rt_ptr);
|
|
break;
|
|
#endif /* INT64_SUPPORT */
|
|
}
|
|
break;
|
|
|
|
#ifdef FLOAT_DATA_SUPPORT
|
|
case RT_FLOATING_POINT :
|
|
if (rt_ptr->u.p.el_len != sizeof (ST_FLOAT))
|
|
{
|
|
if (ac->dbl)
|
|
uDataRet = (*ac->dbl) (usr, (ST_DOUBLE *) datptr, rt_ptr);
|
|
}
|
|
else
|
|
{
|
|
if (ac->flt)
|
|
uDataRet = (*ac->flt) (usr, (ST_FLOAT *) datptr, rt_ptr);
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case RT_OCTET_STRING :
|
|
if (ac->oct)
|
|
uDataRet = (*ac->oct) (usr, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_VISIBLE_STRING :
|
|
if (ac->vis)
|
|
uDataRet = (*ac->vis) (usr, (ST_CHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
#ifdef TIME_DATA_SUPPORT
|
|
case RT_GENERAL_TIME :
|
|
if (ac->gt)
|
|
uDataRet = (*ac->gt) (usr, (time_t *) datptr, rt_ptr);
|
|
break;
|
|
#endif
|
|
|
|
#ifdef BTOD_DATA_SUPPORT
|
|
case RT_BINARY_TIME :
|
|
switch (rt_ptr->u.p.el_len) /* determine length */
|
|
{
|
|
case 4:
|
|
if (ac->bt4)
|
|
uDataRet = (*ac->bt4) (usr, (ST_INT32 *) datptr, rt_ptr);
|
|
break;
|
|
case 6:
|
|
if (ac->bt6)
|
|
uDataRet = (*ac->bt6) (usr, (ST_INT32 *) datptr, rt_ptr);
|
|
break;
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case RT_BCD :
|
|
if (rt_ptr->u.p.el_len <= 2)
|
|
{
|
|
if (ac->bcd1)
|
|
uDataRet = (*ac->bcd1) (usr, (ST_INT8 *) datptr, rt_ptr);
|
|
}
|
|
else if (rt_ptr->u.p.el_len <= 4)
|
|
{
|
|
if (ac->bcd2)
|
|
uDataRet = (*ac->bcd2) (usr, (ST_INT16 *) datptr, rt_ptr);
|
|
}
|
|
else if (rt_ptr->u.p.el_len <= 8)
|
|
{
|
|
if (ac->bcd4)
|
|
uDataRet = (*ac->bcd4) (usr, (ST_INT32 *) datptr, rt_ptr);
|
|
}
|
|
break;
|
|
|
|
case RT_UTC_TIME :
|
|
if (ac->utc)
|
|
uDataRet = (*ac->utc) (usr, (MMS_UTC_TIME *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_UTF8_STRING :
|
|
if (ac->utf8)
|
|
uDataRet = (*ac->utf8) (usr, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
default : /* should not be any other tag */
|
|
SXLOG_ERR1 ("Invalid tag: %d", (int) rt_ptr->el_tag);
|
|
return (SD_FAILURE);
|
|
break;
|
|
}
|
|
|
|
datptr += rt_ptr->el_size; /* Adjust data pointer */
|
|
rt_ptr++; /* point to next rt element */
|
|
}
|
|
return (uDataRet);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdStripPrefix (ST_CHAR *prefix);
|
|
static ST_RET _sxdEncElement (SX_ENC_CTRL *ec, RUNTIME_TYPE *rt,
|
|
ST_CHAR *dtString, ST_CHAR *contents);
|
|
|
|
/************************************************************************/
|
|
|
|
/* XML data type strings */
|
|
static ST_CHAR _boolDtStr[] = "Bool";
|
|
static ST_CHAR _visStringDtStr[] = "VisString";
|
|
static ST_CHAR _bitStringDtStr[] = "BitString";
|
|
static ST_CHAR _i1DtStr[] = "I1";
|
|
static ST_CHAR _i2DtStr[] = "I2";
|
|
static ST_CHAR _i4DtStr[] = "I4";
|
|
static ST_CHAR _uI1DtStr[] = "UI1";
|
|
static ST_CHAR _uI2DtStr[] = "UI2";
|
|
static ST_CHAR _uI4DtStr[] = "UI4";
|
|
static ST_CHAR _r4DtStr[] = "R4";
|
|
static ST_CHAR _r8DtStr[] = "R8";
|
|
static ST_CHAR _dateTimeDtStr[] = "DateTime";
|
|
static ST_CHAR _binHexDtStr[] = "BinHex";
|
|
#ifdef INT64_SUPPORT /* Only if INT64 supported*/
|
|
static ST_CHAR _i8DtStr[] = "I8";
|
|
static ST_CHAR _uI8DtStr[] = "UI8";
|
|
#endif
|
|
#if 0 /* These not used yet. */
|
|
static ST_CHAR _charDtStr[] = "Char";
|
|
static ST_CHAR _octStringDtStr[] = "OctString";
|
|
static ST_CHAR _dateDtStr[] = "Date";
|
|
static ST_CHAR _dateTimeTzDtStr[] = "DateTimeTz";
|
|
static ST_CHAR _timeDtStr[] = "Time";
|
|
static ST_CHAR _timeTzDtStr[] = "TimeTz";
|
|
static ST_CHAR _binDtStr[] = "Bin";
|
|
static ST_CHAR _binBase64DtStr[] = "BinBase64";
|
|
static ST_CHAR _uriDtStr[] = "Uri";
|
|
static ST_CHAR _udtDtStr[] = "Udt";
|
|
#endif
|
|
|
|
ST_INT sxdDefXmlStyle; /* Note: 0 is style A */
|
|
|
|
/************************************************************************/
|
|
/* _sxdStripPrefix */
|
|
/************************************************************************/
|
|
static ST_RET _sxdStripPrefix (ST_CHAR *prefix)
|
|
{
|
|
ST_INT i;
|
|
|
|
if (prefix)
|
|
{
|
|
i = strlen (prefix) - 1;
|
|
while (--i > 0)
|
|
{
|
|
if (prefix[i] == '.')
|
|
{
|
|
prefix[i+1] = 0; /* keep the dot with remaining prefix */
|
|
break;
|
|
}
|
|
}
|
|
/* if i=0 then dot not found, this must be the first nest level */
|
|
if (i == 0)
|
|
prefix[0] = 0;
|
|
}
|
|
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdEncArrStart */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncArrStart (ST_VOID *usr, RUNTIME_TYPE *rt)
|
|
{
|
|
|
|
/* Nothing to do here, the function _sxdEncElement is encoding */
|
|
/* the element<=>array name. */
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncArrEnd */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncArrEnd (ST_VOID *usr, RUNTIME_TYPE *rt)
|
|
{
|
|
|
|
/* Nothing to do here. */
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncStrStart */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncStrStart (ST_VOID *usr, RUNTIME_TYPE *rt,
|
|
SD_CONST RUNTIME_TYPE *rt_head)
|
|
{
|
|
SX_ENC_CTRL *ec;
|
|
SD_CONST ST_CHAR *elName = ""; /* init to an empty string */
|
|
RUNTIME_TYPE *rt_tmp;
|
|
|
|
ec = (SX_ENC_CTRL *) usr;
|
|
if (ms_comp_name_pres(rt) == SD_TRUE)
|
|
elName = ms_comp_name_find(rt);
|
|
else
|
|
{
|
|
/* name is NULL, it must be the outer element of struct within array */
|
|
if (rt == rt_head)
|
|
{
|
|
elName = ec->outerElement;
|
|
if (elName == NULL)
|
|
return (SD_SUCCESS); /* nothing to encode */
|
|
}
|
|
else
|
|
{
|
|
/* check if array of structs (check previous RTs) */
|
|
rt_tmp = rt - 1;
|
|
while (rt_tmp->el_tag == RT_ARR_START)
|
|
{
|
|
if (ms_comp_name_pres(rt_tmp) == SD_TRUE)
|
|
{
|
|
elName = ms_comp_name_find(rt_tmp);
|
|
break;
|
|
}
|
|
--rt_tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ec->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
if (ec->sxdStructNestLevel == 0)
|
|
{
|
|
*(ec->nextWritePos++) = '<';
|
|
sx_add_string (ec, elName, &ec->nextWritePos);
|
|
}
|
|
else /* Not the outer element */
|
|
{
|
|
strcat (ec->sxdPrefix, elName);
|
|
strcat (ec->sxdPrefix, ".");
|
|
}
|
|
++ec->sxdStructNestLevel;
|
|
}
|
|
else if (ec->sxdXmlStyle == SXD_XML_STYLE_V ||
|
|
ec->sxdXmlStyle == SXD_XML_STYLE_C)
|
|
{
|
|
sx_start_element ((SX_ENC_CTRL *) usr, elName, 0, NULL);
|
|
}
|
|
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncStrEnd */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncStrEnd (ST_VOID *usr, RUNTIME_TYPE *rt)
|
|
{
|
|
SX_ENC_CTRL *ec;
|
|
|
|
ec = (SX_ENC_CTRL *) usr;
|
|
|
|
if (ec->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
if (ms_comp_name_pres(rt) == SD_FALSE && ec->outerElement == NULL)
|
|
return (SD_SUCCESS);
|
|
|
|
--ec->sxdStructNestLevel;
|
|
|
|
if (ec->sxdStructNestLevel == 0)
|
|
{
|
|
/* this is end of XML */
|
|
*(ec->nextWritePos++) = '/';
|
|
*(ec->nextWritePos++) = '>';
|
|
}
|
|
else
|
|
{
|
|
/* Not the outer element or the first level, remove the last prefix */
|
|
_sxdStripPrefix (ec->sxdPrefix);
|
|
}
|
|
}
|
|
else if (ec->sxdXmlStyle == SXD_XML_STYLE_V ||
|
|
ec->sxdXmlStyle == SXD_XML_STYLE_C)
|
|
{
|
|
/* encode struct end tag */
|
|
if (ec->currNestLevel > 0)
|
|
sx_end_element ((SX_ENC_CTRL *) usr);
|
|
}
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdEncInt8 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncInt8 (ST_VOID *usr, ST_INT8 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT intVal;
|
|
ST_CHAR buf[50];
|
|
|
|
intVal = (ST_INT) (*data_ptr);
|
|
#if defined(_WIN32) || defined(__QNX__)
|
|
itoa (intVal, buf, 10);
|
|
#else
|
|
sprintf (buf, "%d", intVal);
|
|
#endif
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _i1DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncInt16 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncInt16 (ST_VOID *usr, ST_INT16 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT intVal;
|
|
ST_CHAR buf[50];
|
|
|
|
intVal = (ST_INT) *data_ptr;
|
|
#if defined(_WIN32) || defined(__QNX__)
|
|
itoa (intVal, buf, 10);
|
|
#else
|
|
sprintf (buf, "%d", intVal);
|
|
#endif
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _i2DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncInt32 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncInt32 (ST_VOID *usr, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_LONG long_val;
|
|
ST_CHAR buf[50];
|
|
|
|
long_val = (ST_LONG) *data_ptr;
|
|
#if defined(_WIN32) || defined(__QNX__)
|
|
ltoa (long_val, buf, 10);
|
|
#else
|
|
sprintf (buf, "%ld", long_val);
|
|
#endif
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _i4DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncInt64 */
|
|
/************************************************************************/
|
|
#ifdef INT64_SUPPORT
|
|
|
|
static ST_RET _sxdEncInt64 (ST_VOID *usr, ST_INT64 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT64 i64_val;
|
|
ST_CHAR buf[80];
|
|
|
|
i64_val = (ST_INT64) *data_ptr;
|
|
#ifdef _WIN32
|
|
_i64toa (i64_val, buf, 10);
|
|
#else
|
|
sprintf (buf, S_FMT_INT64, i64_val);
|
|
#endif
|
|
return (_sxdEncElement (usr, rt, _i8DtStr, buf));
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncUint8 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncUint8 (ST_VOID *usr, ST_UINT8 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_UINT uintVal;
|
|
ST_CHAR buf[50];
|
|
|
|
uintVal = (ST_UINT) *data_ptr;
|
|
#if defined(_WIN32) || defined(__QNX__)
|
|
itoa ((int) uintVal, buf, 10);
|
|
#else
|
|
sprintf (buf, "%u", uintVal);
|
|
#endif
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _uI1DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncUint16 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncUint16(ST_VOID *usr, ST_UINT16 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_LONG long_val;
|
|
ST_CHAR buf[50];
|
|
|
|
long_val = (ST_LONG) *data_ptr;
|
|
#if defined(_WIN32) || defined(__QNX__)
|
|
ltoa (long_val, buf, 10);
|
|
#else
|
|
sprintf (buf, "%u", (ST_UINT) long_val);
|
|
#endif
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _uI2DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncUint32 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncUint32(ST_VOID *usr, ST_UINT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_ULONG ulong_val;
|
|
ST_CHAR buf[50];
|
|
|
|
ulong_val = (ST_ULONG) *data_ptr;
|
|
#if defined(_WIN32) || defined(__QNX__)
|
|
ultoa (ulong_val, buf, 10);
|
|
#else
|
|
sprintf (buf, "%lu", ulong_val);
|
|
#endif
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _uI4DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncUint64 */
|
|
/************************************************************************/
|
|
#ifdef INT64_SUPPORT
|
|
|
|
static ST_RET _sxdEncUint64(ST_VOID *usr, ST_UINT64 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_UINT64 u64_val;
|
|
ST_CHAR buf[80];
|
|
|
|
u64_val = (ST_INT64) *data_ptr;
|
|
#ifdef _WIN32
|
|
_ui64toa (u64_val, buf, 10);
|
|
#else
|
|
sprintf (buf, S_FMT_UINT64, u64_val);
|
|
#endif
|
|
return (_sxdEncElement (usr, rt, _uI8DtStr, buf));
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncFlt */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncFlt (ST_VOID *usr, ST_FLOAT *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_DOUBLE d;
|
|
ST_CHAR buf[100];
|
|
|
|
d = (ST_DOUBLE) (*(ST_FLOAT *) data_ptr);
|
|
sprintf (buf,"%.10f", d);
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _r4DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncDbl */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncDbl (ST_VOID *usr, ST_DOUBLE *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_DOUBLE d;
|
|
ST_CHAR buf[100];
|
|
|
|
d = *data_ptr;
|
|
sprintf (buf,"%.16f", d);
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _r8DtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncOct */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncOct (ST_VOID *usr, ST_UCHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT16 *sp;
|
|
ST_CHAR *buf;
|
|
ST_INT dataLen;
|
|
ST_RET rc;
|
|
|
|
if (rt->u.p.el_len < 0)
|
|
{
|
|
sp = (ST_INT16 *) data_ptr;
|
|
dataLen = (ST_INT) *sp;
|
|
data_ptr += 2;
|
|
}
|
|
else
|
|
dataLen = abs (rt->u.p.el_len);
|
|
|
|
buf = (ST_CHAR *) M_MALLOC (NULL, (3 * dataLen) + 1);
|
|
hex_to_ascii_str (buf, data_ptr, dataLen, SD_TRUE);
|
|
rc = _sxdEncElement ((SX_ENC_CTRL *) usr, rt, _binHexDtStr, buf);
|
|
M_FREE (NULL, buf);
|
|
return (rc);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBool */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBool (ST_VOID *usr, ST_BOOLEAN *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_BOOLEAN *bptr;
|
|
ST_CHAR *valStr;
|
|
|
|
bptr = (ST_BOOLEAN *) data_ptr;
|
|
if (*bptr == 0)
|
|
valStr = "0";
|
|
else
|
|
valStr = "1";
|
|
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _boolDtStr, valStr));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBcd1 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBcd1 (ST_VOID *usr, ST_INT8 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdEncInt8 (usr, data_ptr, rt));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBcd2 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBcd2 (ST_VOID *usr, ST_INT16 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdEncInt16 (usr, data_ptr, rt));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBcd4 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBcd4 (ST_VOID *usr, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdEncInt32 (usr, data_ptr, rt));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBs */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBs (ST_VOID *usr, ST_UCHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT i;
|
|
ST_INT16 *sp;
|
|
ST_CHAR *_writePos;
|
|
ST_UINT8 bitMask;
|
|
ST_UINT8 *bytePtr;
|
|
ST_INT numBits;
|
|
ST_CHAR *buf;
|
|
ST_RET rc;
|
|
|
|
if (rt->u.p.el_len < 0)
|
|
{
|
|
sp = (ST_INT16 *) data_ptr;
|
|
numBits = (ST_INT) *sp;
|
|
data_ptr += 2;
|
|
}
|
|
else
|
|
numBits = rt->u.p.el_len;
|
|
|
|
buf = (ST_CHAR *) M_MALLOC (NULL, numBits + 1);
|
|
|
|
_writePos = buf;
|
|
bitMask = 0x80;
|
|
bytePtr = data_ptr;
|
|
for (i = 0; i < numBits; ++i)
|
|
{
|
|
if (*bytePtr & bitMask)
|
|
*(_writePos++) = '1';
|
|
else
|
|
*(_writePos++) = '0';
|
|
|
|
if (bitMask == 0x01)
|
|
{
|
|
bitMask = 0x80;
|
|
++bytePtr;
|
|
}
|
|
else
|
|
bitMask = bitMask >> 1;
|
|
}
|
|
|
|
rc = _sxdEncElement ((SX_ENC_CTRL *) usr, rt, _bitStringDtStr, buf);
|
|
M_FREE (NULL, buf);
|
|
return (rc);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdEncVis */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncVis (ST_VOID *usr, ST_CHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _visStringDtStr, data_ptr));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBt4 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBt4 (ST_VOID *usr, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_CHAR buf[100];
|
|
ST_RET rc;
|
|
|
|
rc = Btime4ValsToString (buf, (ST_LONG) *data_ptr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _dateTimeDtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncBt6 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncBt6 (ST_VOID *usr, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_CHAR buf[100];
|
|
ST_RET rc;
|
|
|
|
rc = Btime6ValsToString (buf, *(data_ptr+1), (ST_LONG) *data_ptr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _dateTimeDtStr, buf));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncGt */
|
|
/************************************************************************/
|
|
|
|
#define _SXD_TIME_BUF_LEN 25
|
|
|
|
static ST_RET _sxdEncGt (ST_VOID *usr, time_t *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_CHAR timeText[_SXD_TIME_BUF_LEN];
|
|
|
|
strcpy (timeText, ctime(data_ptr));
|
|
timeText[24] = 0; /* squash the \n */
|
|
|
|
return (_sxdEncElement ((SX_ENC_CTRL *) usr, rt, _dateTimeDtStr, timeText));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdEncUTF8 */
|
|
/* Don't know how to display. Just show the hex bytes. */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncUTF8 (ST_VOID *usr, ST_UCHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_CHAR *buf;
|
|
ST_INT dataLen;
|
|
ST_RET rc;
|
|
|
|
dataLen = rt->el_size;
|
|
|
|
buf = (ST_CHAR *) M_MALLOC (NULL, (3 * dataLen) + 1);
|
|
hex_to_ascii_str (buf, data_ptr, dataLen, SD_TRUE);
|
|
rc = _sxdEncElement ((SX_ENC_CTRL *) usr, rt, _binHexDtStr, buf);
|
|
M_FREE (NULL, buf);
|
|
return (rc);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdEncElement */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdEncElement (SX_ENC_CTRL *ec, RUNTIME_TYPE *rt,
|
|
ST_CHAR *dtString, ST_CHAR *contents)
|
|
{
|
|
SD_CONST ST_CHAR *elName;
|
|
SXE_ATTR_PAIR attr[2];
|
|
ST_INT numAttr;
|
|
RUNTIME_TYPE *rt_tmp;
|
|
|
|
if (ms_comp_name_pres(rt) == SD_TRUE)
|
|
elName = ms_comp_name_find(rt);
|
|
else
|
|
{
|
|
/* must be an array element, get the name from the RT_ARR_START */
|
|
elName = "UNNAMED"; /* set, just in case name not specified */
|
|
rt_tmp = rt-1;
|
|
/* this maybe multidimentional array , only the first dim has name in RT tbl */
|
|
while (rt_tmp->el_tag == RT_ARR_START)
|
|
{
|
|
if (ms_comp_name_pres(rt_tmp) == SD_TRUE)
|
|
{
|
|
elName = ms_comp_name_find(rt_tmp);
|
|
break;
|
|
}
|
|
--rt_tmp;
|
|
}
|
|
}
|
|
|
|
if (ec->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
*(ec->nextWritePos++) = ' ';
|
|
sx_add_string (ec, ec->sxdPrefix, &ec->nextWritePos);
|
|
sx_add_string (ec, elName, &ec->nextWritePos);
|
|
*(ec->nextWritePos++) = '=';
|
|
*(ec->nextWritePos++) = '"';
|
|
sx_add_string (ec, contents, &ec->nextWritePos);
|
|
*(ec->nextWritePos++) = '"';
|
|
}
|
|
else if (ec->sxdXmlStyle == SXD_XML_STYLE_C)
|
|
{
|
|
sx_wr_string_el (ec, elName, contents);
|
|
}
|
|
else if (ec->sxdXmlStyle == SXD_XML_STYLE_V)
|
|
{
|
|
if (ec->encDt)
|
|
{
|
|
attr[0].name = "DT";
|
|
attr[0].value = dtString;
|
|
numAttr = 1;
|
|
}
|
|
else
|
|
numAttr = 0;
|
|
|
|
attr[numAttr].name = "V";
|
|
attr[numAttr].value = contents;
|
|
++numAttr;
|
|
sx_write_element (ec, elName, numAttr, attr, SD_FALSE, SD_TRUE);
|
|
}
|
|
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
|
|
SXD_ARB_DATA_CTRL _sxdEncArbFuns =
|
|
{
|
|
_sxdEncArrStart, /* arrStart */
|
|
_sxdEncArrEnd, /* arrEnd */
|
|
_sxdEncStrStart, /* strStart */
|
|
_sxdEncStrEnd, /* strEnd */
|
|
_sxdEncInt8, /* int8 */
|
|
_sxdEncInt16, /* int16 */
|
|
_sxdEncInt32, /* int32 */
|
|
#ifdef INT64_SUPPORT
|
|
_sxdEncInt64, /* int64 */
|
|
#endif
|
|
_sxdEncUint8, /* uint8 */
|
|
_sxdEncUint16, /* uint16 */
|
|
_sxdEncUint32, /* uint32 */
|
|
#ifdef INT64_SUPPORT
|
|
_sxdEncUint64, /* uint64 */
|
|
#endif
|
|
_sxdEncFlt, /* flt */
|
|
_sxdEncDbl, /* dbl */
|
|
_sxdEncOct, /* oct */
|
|
_sxdEncBool, /* booln */
|
|
_sxdEncBcd1, /* bcd1 */
|
|
_sxdEncBcd2, /* bcd2 */
|
|
_sxdEncBcd4, /* bcd4 */
|
|
_sxdEncBs, /* bs */
|
|
_sxdEncVis, /* vis */
|
|
_sxdEncBt4, /* Bin Time */
|
|
_sxdEncBt6, /* Bin Time */
|
|
_sxdEncGt, /* Gen Time */
|
|
NULL, /* UTC Time */
|
|
_sxdEncUTF8, /* UTF8string */
|
|
};
|
|
|
|
/************************************************************************/
|
|
/* _sxd_wr_data */
|
|
/************************************************************************/
|
|
|
|
#if defined(MMS_LITE) && !defined(NO_MVL)
|
|
|
|
ST_RET _sxd_wr_data (SX_ENC_CTRL *sxEncCtrl, ST_INT typeId,
|
|
ST_CHAR *elName, ST_VOID *data, ST_INT sxdXmlStyle,
|
|
ST_BOOLEAN encodeDt, ST_BOOLEAN *elPres)
|
|
{
|
|
RUNTIME_TYPE *rt;
|
|
ST_INT numRt;
|
|
ST_RET rc;
|
|
|
|
rc = sxd_get_runtime (typeId, &rt, &numRt);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
|
|
rc = sxd_wr_rtdata (sxEncCtrl, rt, numRt, elName, data, sxdXmlStyle, encodeDt, elPres);
|
|
return (rc);
|
|
}
|
|
#endif
|
|
|
|
|
|
/************************************************************************/
|
|
/* sxd_wr_rtdata */
|
|
/************************************************************************/
|
|
|
|
ST_RET sxd_wr_rtdata (SX_ENC_CTRL *sxEncCtrl, RUNTIME_TYPE *rt, ST_INT numRt,
|
|
ST_CHAR *elName, ST_VOID *data, ST_INT sxdXmlStyle,
|
|
ST_BOOLEAN encodeDt, ST_BOOLEAN *elPres)
|
|
{
|
|
ST_RET rc;
|
|
|
|
sxEncCtrl->sxdXmlStyle = sxdXmlStyle;
|
|
sxEncCtrl->encDt = encodeDt;
|
|
sxEncCtrl->outerElement = elName;
|
|
sxEncCtrl->sxdPrefix[0] = 0;
|
|
|
|
rc = sxd_process_arb_data ((ST_CHAR *) data, rt, numRt, sxEncCtrl,
|
|
&_sxdEncArbFuns, elPres);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
|
|
return (rc);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
|
|
#define _SXD_MAX_VAL_BUF 8000
|
|
#define _SXD_MAX_EL_NAME 50
|
|
#define _SXD_MAX_DT 50
|
|
|
|
typedef struct
|
|
{
|
|
ST_INT sxdXmlStyle; /* See sx_defs.h for values */
|
|
ST_CHAR *xmlDest;
|
|
ST_BOOLEAN checkDt;
|
|
ST_CHAR *xmlPos;
|
|
ST_CHAR *xmlBufEnd;
|
|
ST_RET xmlDecResult;
|
|
SD_CONST ST_CHAR *outerElement;
|
|
ST_CHAR valBuf[_SXD_MAX_VAL_BUF+1];
|
|
ST_CHAR elName[_SXD_MAX_EL_NAME+1];
|
|
ST_CHAR dtBuf[_SXD_MAX_DT+1];
|
|
ST_BOOLEAN endEl;
|
|
ST_BOOLEAN dataEl;
|
|
} SXD_DEC_CTRL;
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdCheckDt (SXD_DEC_CTRL *dc, ST_CHAR *dtString)
|
|
{
|
|
if (strcmp (dc->dtBuf, dtString) != 0)
|
|
{
|
|
SXLOG_NERR3 ("Type mismatch for elName '%s': expected '%s', got '%s'",
|
|
dc->elName, dtString, dc->dtBuf);
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdDecArrStart */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecArrStart (SXD_DEC_CTRL *dc, RUNTIME_TYPE *rt)
|
|
{
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecArrEnd */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecArrEnd (SXD_DEC_CTRL *dc, RUNTIME_TYPE *rt)
|
|
{
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecStrStart */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecStrStart (SXD_DEC_CTRL *dc, RUNTIME_TYPE *rt)
|
|
{
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecStrEnd */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecStrEnd (SXD_DEC_CTRL *dc, RUNTIME_TYPE *rt)
|
|
{
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdDecInt8 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecInt8 (SXD_DEC_CTRL *dc, ST_INT8 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _i1DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
intVal = atoi (dc->valBuf);
|
|
*data_ptr = (ST_INT8) intVal;
|
|
SXLOG_CDEC1 ("Integer8: %d",intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/***********************************************************************/
|
|
/* _sxdDecInt16 */
|
|
/***********************************************************************/
|
|
|
|
static ST_RET _sxdDecInt16 (SXD_DEC_CTRL *dc, ST_INT16 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _i2DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
intVal = atoi (dc->valBuf);
|
|
*data_ptr = (ST_INT16) intVal;
|
|
SXLOG_CDEC1 ("Integer16: %d",intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecInt32 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecInt32 (SXD_DEC_CTRL *dc, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT32 intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _i4DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
intVal = atoi (dc->valBuf);
|
|
*data_ptr = (ST_INT32) intVal;
|
|
SXLOG_CDEC1 ("Integer32: %ld", (ST_LONG) intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecInt64 */
|
|
/************************************************************************/
|
|
#ifdef INT64_SUPPORT
|
|
|
|
static ST_RET _sxdDecInt64 (SXD_DEC_CTRL *dc, ST_INT64 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT64 i64Val;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _i8DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
#if defined(_WIN32)
|
|
i64Val = _atoi64 (dc->valBuf);
|
|
#else
|
|
if (sscanf (dc->valBuf, S_FMT_INT64, &i64Val) != 1)
|
|
return (SD_FAILURE);
|
|
#endif
|
|
*data_ptr = i64Val;
|
|
SXLOG_CDEC1 ("Integer64: " S_FMT_INT64, i64Val);
|
|
return (SD_SUCCESS);
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecUint8 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecUint8 (SXD_DEC_CTRL *dc, ST_UINT8 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _uI1DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
intVal = atoi (dc->valBuf);
|
|
*data_ptr = (ST_UINT8) intVal;
|
|
SXLOG_CDEC1 ("Unsigned8: %d",intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecUint16 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecUint16 (SXD_DEC_CTRL *dc, ST_UINT16 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _uI2DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
intVal = atoi (dc->valBuf);
|
|
*data_ptr = (ST_UINT16) intVal;
|
|
SXLOG_CDEC1 ("Unsigned16: %d",intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecUint32 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecUint32(SXD_DEC_CTRL *dc, ST_UINT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_ULONG intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _uI4DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
#if (LONG_MAX > INT_MAX)
|
|
intVal = atol (dc->valBuf);
|
|
#else
|
|
if (sscanf (dc->valBuf, "%lu", &intVal) != 1)
|
|
return (SD_FAILURE);
|
|
#endif
|
|
*data_ptr = (ST_UINT32) intVal;
|
|
SXLOG_CDEC1 ("Unsigned32: %lu",intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecUint64 */
|
|
/************************************************************************/
|
|
#ifdef INT64_SUPPORT
|
|
|
|
static ST_RET _sxdDecUint64(SXD_DEC_CTRL *dc, ST_UINT64 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_UINT64 intVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _uI8DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
if (sscanf (dc->valBuf, S_FMT_UINT64, &intVal) != 1)
|
|
return (SD_FAILURE);
|
|
*data_ptr = intVal;
|
|
SXLOG_CDEC1 ("Unsigned64: " S_FMT_UINT64, intVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecFlt */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecFlt (SXD_DEC_CTRL *dc, ST_FLOAT *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_DOUBLE doubleVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _r4DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
doubleVal = atof (dc->valBuf);
|
|
*data_ptr = (ST_FLOAT) doubleVal;
|
|
SXLOG_CDEC1 ("Float: %f", doubleVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecDbl */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecDbl (SXD_DEC_CTRL *dc, ST_DOUBLE *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_DOUBLE doubleVal;
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _r8DtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
doubleVal = atof (dc->valBuf);
|
|
*data_ptr = (ST_FLOAT) doubleVal;
|
|
SXLOG_CDEC1 ("Double: %f", doubleVal);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecOct */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecOct (SXD_DEC_CTRL *dc, ST_UCHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_RET rc;
|
|
ST_INT16 *sp;
|
|
ST_UINT maxOctets;
|
|
ST_UINT hexLen;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _binHexDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
if (rt->u.p.el_len < 0)
|
|
data_ptr += 2;
|
|
|
|
maxOctets = abs (rt->u.p.el_len);
|
|
rc = ascii_to_hex_str (data_ptr, &hexLen, maxOctets, dc->valBuf);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
|
|
if (rt->u.p.el_len < 0)
|
|
{
|
|
sp = (ST_INT16 *) (data_ptr-2);
|
|
*sp = hexLen;
|
|
}
|
|
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBool */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBool (SXD_DEC_CTRL *dc, ST_BOOLEAN *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _boolDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
*data_ptr = dc->valBuf[0] == '0' ? 0 : 1;
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBcd1 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBcd1 (SXD_DEC_CTRL *dc, ST_INT8 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdDecInt8 (dc, data_ptr, rt));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBcd2 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBcd2 (SXD_DEC_CTRL *dc, ST_INT16 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdDecInt16 (dc, data_ptr, rt));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBcd4 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBcd4 (SXD_DEC_CTRL *dc, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
return (_sxdDecInt32 (dc, data_ptr, rt));
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBs */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBs (SXD_DEC_CTRL *dc, ST_UCHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_INT16 *sp;
|
|
ST_UINT8 bitMask;
|
|
ST_UINT8 *bytePtr;
|
|
ST_RET rc;
|
|
ST_CHAR *ascPtr;
|
|
ST_INT bitCount;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _bitStringDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
if (rt->u.p.el_len < 0)
|
|
bytePtr = data_ptr + 2;
|
|
else
|
|
bytePtr = data_ptr;
|
|
|
|
bitMask = 0x80;
|
|
ascPtr = dc->valBuf;
|
|
bitCount = 0;
|
|
while (*ascPtr != 0 && bitCount < abs (rt->u.p.el_len))
|
|
{
|
|
if (*ascPtr == '1')
|
|
*bytePtr |= bitMask;
|
|
else
|
|
*bytePtr &= ~bitMask;
|
|
|
|
if (bitMask == 0x01)
|
|
{
|
|
bitMask = 0x80;
|
|
++bytePtr;
|
|
}
|
|
else
|
|
bitMask = bitMask >> 1;
|
|
|
|
++bitCount;
|
|
}
|
|
|
|
if (rt->u.p.el_len < 0)
|
|
{
|
|
sp = (ST_INT16 *) (data_ptr);
|
|
*sp = bitCount;
|
|
}
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecVis */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecVis (SXD_DEC_CTRL *dc, ST_CHAR *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _visStringDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
strcpy (data_ptr, dc->valBuf);
|
|
SXLOG_CDEC1 ("Visible string: '%s'", data_ptr);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBt4 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBt4 (SXD_DEC_CTRL *dc, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _dateTimeDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
rc = Btime4StringToVals (dc->valBuf, data_ptr);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecBt6 */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecBt6 (SXD_DEC_CTRL *dc, ST_INT32 *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _dateTimeDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
rc = Btime6StringToVals (dc->valBuf, data_ptr+1, data_ptr);
|
|
return (rc);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecGt */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecGt (SXD_DEC_CTRL *dc, time_t *data_ptr, RUNTIME_TYPE *rt)
|
|
{
|
|
ST_RET rc;
|
|
|
|
/* Check data type, if requested ... */
|
|
if (dc->checkDt != SD_FALSE)
|
|
{
|
|
rc = _sxdCheckDt (dc, _dateTimeDtStr);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
}
|
|
|
|
rc = tstrStringToTime (dc->valBuf, data_ptr);
|
|
return (rc);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _sxdDecElementA */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecElementA (SXD_DEC_CTRL *dc)
|
|
{
|
|
ST_CHAR *p;
|
|
ST_CHAR c;
|
|
ST_INT i;
|
|
|
|
/* Continue decoding the element, which must be of the form */
|
|
/* <structName el1Name="yyy" el2Name="xxx"/> */
|
|
|
|
dc->endEl = SD_FALSE;
|
|
dc->dataEl = SD_FALSE;
|
|
|
|
c = *(dc->xmlPos++);
|
|
if (c == '<')
|
|
{
|
|
/* OK, get the element name */
|
|
c = *(dc->xmlPos++);
|
|
p = dc->elName;
|
|
i = 0;
|
|
while (c != ' ' && c != '>')
|
|
{
|
|
if (++i > _SXD_MAX_EL_NAME)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/* OK, not the start of an element, see if is the end of an element */
|
|
if (c == '/')
|
|
{
|
|
dc->endEl = SD_TRUE;
|
|
c = *(dc->xmlPos++); /* Eat the '>' */
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/* OK, must be the name of a structure element */
|
|
p = dc->elName;
|
|
i = 0;
|
|
while (c != '=')
|
|
{
|
|
if (c != ' ') /* Skip leading spaces before attribute name */
|
|
{
|
|
if (++i > _SXD_MAX_EL_NAME)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
*(p++) = c;
|
|
}
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find '='");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
|
|
/* Finally, we get to the value */
|
|
c = *(dc->xmlPos++); /* Eat the '"' */
|
|
p = dc->valBuf;
|
|
c = *(dc->xmlPos++);
|
|
i = 0;
|
|
while (c != '"')
|
|
{
|
|
if (++i > _SXD_MAX_VAL_BUF)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find end of value attribute");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
dc->dataEl = SD_TRUE;
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecElementC */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecElementC (SXD_DEC_CTRL *dc)
|
|
{
|
|
ST_CHAR *p;
|
|
ST_CHAR c;
|
|
|
|
ST_INT i;
|
|
/* Decode the XML element, which must be of the form */
|
|
/* <elName>xxxx</elName> */
|
|
/* <elName>< ... */
|
|
/* </elName> */
|
|
|
|
/* Find the opening '<' */
|
|
while (SD_TRUE)
|
|
{
|
|
c = *(dc->xmlPos++);
|
|
if (c == '<')
|
|
{
|
|
if (*dc->xmlPos != '!')
|
|
break;
|
|
}
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find opening '<'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
|
|
c = *(dc->xmlPos++);
|
|
if (c == '/')
|
|
{
|
|
dc->endEl = SD_TRUE;
|
|
c = *(dc->xmlPos++);
|
|
}
|
|
else
|
|
dc->endEl = SD_FALSE;
|
|
|
|
/* OK, get the element name */
|
|
p = dc->elName;
|
|
i = 0;
|
|
while (c != '>')
|
|
{
|
|
if (++i > _SXD_MAX_EL_NAME)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' '");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
|
|
/* If this is an end element, we are done */
|
|
if (dc->endEl == SD_TRUE)
|
|
return (SD_SUCCESS);
|
|
|
|
/* Now check to see if this is a nested element */
|
|
p = dc->xmlPos;
|
|
while (SD_TRUE)
|
|
{
|
|
if (*(p++) == '<') /* The end of this element or start of nest */
|
|
{
|
|
if (*p != '!') /* if this is not a comment */
|
|
{
|
|
if (*p == '/') /* The end of this element */
|
|
break;
|
|
|
|
return (SD_SUCCESS); /* Start of nested element */
|
|
}
|
|
}
|
|
if (p > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' '");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
|
|
/* OK, now we can get the value */
|
|
dc->dataEl = SD_TRUE;
|
|
|
|
p = dc->valBuf;
|
|
c = *(dc->xmlPos++);
|
|
i = 0;
|
|
while (c != '<')
|
|
{
|
|
if (++i > _SXD_MAX_VAL_BUF)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find end of value");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
|
|
/* Now we need to consume the end tag */
|
|
c = *(dc->xmlPos++);
|
|
if (c != '/')
|
|
{
|
|
SXLOG_NERR0 ("Expected end tag");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
while (c != '>')
|
|
{
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find end of end tag");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _sxdDecElementV */
|
|
/************************************************************************/
|
|
|
|
static ST_RET _sxdDecElementV (SXD_DEC_CTRL *dc)
|
|
{
|
|
ST_CHAR *p;
|
|
ST_CHAR c;
|
|
ST_INT i;
|
|
|
|
/* Decode the XML element, which must be of the form */
|
|
/* <elName DT="yyy" V="xxx"/> */
|
|
/* <elName> */
|
|
/* </elName> */
|
|
|
|
c = *(dc->xmlPos++);
|
|
if (c != '<')
|
|
{
|
|
SXLOG_NERR0 ("Could not find opening '<'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
c = *(dc->xmlPos++);
|
|
if (c == '/')
|
|
{
|
|
dc->endEl = SD_TRUE;
|
|
c = *(dc->xmlPos++);
|
|
}
|
|
else
|
|
dc->endEl = SD_FALSE;
|
|
|
|
/* OK, get the element name */
|
|
p = dc->elName;
|
|
i = 0;
|
|
while (c != ' ' && c != '>')
|
|
{
|
|
if (++i > _SXD_MAX_EL_NAME)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' '");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
|
|
if (c == ' ')
|
|
{
|
|
dc->dataEl = SD_TRUE;
|
|
|
|
/* OK, now see if the data type is included ... */
|
|
p = dc->dtBuf;
|
|
c = *(dc->xmlPos++);
|
|
if (c == 'D')
|
|
{
|
|
c = *(dc->xmlPos++); /* Eat the 'T' */
|
|
c = *(dc->xmlPos++); /* Eat the '=' */
|
|
c = *(dc->xmlPos++); /* Eat the '"' */
|
|
c = *(dc->xmlPos++);
|
|
i = 0;
|
|
while (c != '"' && dc->xmlPos <= dc->xmlBufEnd)
|
|
{
|
|
if (++i > _SXD_MAX_DT)
|
|
{
|
|
SXLOG_NERR0 ("Could not find end of DT");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' '");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
c = *(dc->xmlPos++); /* Eat the ' ' */
|
|
c = *(dc->xmlPos++); /* This should be the 'V' */
|
|
}
|
|
*p = 0;
|
|
|
|
/* Finally, we get to the value, right? */
|
|
if (c != 'V')
|
|
{
|
|
SXLOG_NERR0 ("Expected 'V'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
c = *(dc->xmlPos++); /* Eat the '=' */
|
|
c = *(dc->xmlPos++); /* Eat the '"' */
|
|
|
|
p = dc->valBuf;
|
|
c = *(dc->xmlPos++);
|
|
i = 0;
|
|
while (c != '"')
|
|
{
|
|
if (++i > _SXD_MAX_VAL_BUF)
|
|
{
|
|
SXLOG_NERR0 ("Could not find ' ' or '>'");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
*(p++) = c;
|
|
c = *(dc->xmlPos++);
|
|
if (dc->xmlPos > dc->xmlBufEnd)
|
|
{
|
|
SXLOG_NERR0 ("Could not find end of value attribute");
|
|
dc->xmlDecResult = SD_FAILURE;
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
*p = 0;
|
|
c = *(dc->xmlPos++); /* Eat the '/' */
|
|
c = *(dc->xmlPos++); /* Eat the '>' */
|
|
}
|
|
else
|
|
dc->dataEl = SD_FALSE;
|
|
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
|
|
#if defined(MMS_LITE) && !defined(NO_MVL)
|
|
|
|
ST_RET _sxd_decode_data_el (ST_CHAR *elName,
|
|
ST_CHAR *xml, ST_INT xmlLen, ST_INT *xmlUsed,
|
|
ST_VOID *vdp, ST_INT typeId,
|
|
ST_BOOLEAN *elPres, ST_INT sxdXmlStyle, ST_BOOLEAN checkDt)
|
|
{
|
|
RUNTIME_TYPE *rt;
|
|
ST_INT numRt;
|
|
ST_RET rc;
|
|
|
|
rc = sxd_get_runtime (typeId, &rt, &numRt);
|
|
if (rc != SD_SUCCESS)
|
|
return (rc);
|
|
|
|
rc = sxd_decode_rtdata_el (elName, xml, xmlLen, xmlUsed, vdp, rt, numRt,
|
|
elPres, sxdXmlStyle, checkDt);
|
|
|
|
return (rc);
|
|
}
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* sxd_decode_rtdata_el */
|
|
/************************************************************************/
|
|
|
|
ST_RET sxd_decode_rtdata_el (SD_CONST ST_CHAR *elName,
|
|
ST_CHAR *xml, ST_INT xmlLen, ST_INT *xmlUsed,
|
|
ST_VOID *vdp, SD_CONST RUNTIME_TYPE *rt_head,
|
|
ST_INT rt_num, ST_BOOLEAN *elPres,
|
|
ST_INT sxdXmlStyle, ST_BOOLEAN checkDt)
|
|
{
|
|
RUNTIME_TYPE *rt_ptr;
|
|
RUNTIME_TYPE *rt_end;
|
|
RUNTIME_TYPE *rt_tmp;
|
|
ST_RET uDataRet;
|
|
ST_INT arr_loop_level;
|
|
ST_INT arr_loops[ASN1_MAX_LEVEL];
|
|
ST_RET rc;
|
|
SXD_DEC_CTRL *dc;
|
|
ST_CHAR *datptr;
|
|
ST_CHAR nameBuf[SXD_MAX_PREFIX+MAX_IDENT_LEN+1];
|
|
ST_INT j, cnt;
|
|
ST_BOOLEAN set_arr_start;
|
|
ST_BOOLEAN set_arr_end;
|
|
ST_BOOLEAN plain_array;
|
|
ST_CHAR structPrefix[SXD_MAX_PREFIX+1]; /* used only for decoding of style A */
|
|
ST_INT structNestLevel; /* used only for decoding of style A */
|
|
|
|
/* macro to set the elPres field, update datptr, and advance to next RT */
|
|
#define _SXD_ADVANCE_PTR(rt_ptr, pres_flg) { \
|
|
if (elPres != NULL) \
|
|
elPres[(rt_ptr) - rt_head] = pres_flg; \
|
|
datptr += (rt_ptr)->el_size; \
|
|
++(rt_ptr); }
|
|
|
|
datptr = (ST_CHAR *) vdp;
|
|
dc = (SXD_DEC_CTRL *) M_CALLOC (NULL, 1, sizeof (SXD_DEC_CTRL));
|
|
if (!dc)
|
|
{
|
|
SXLOG_ERR1 ("Unable to allocate memory (bytes %u)", sizeof (SX_DEC_CTRL));
|
|
return (SD_FAILURE);
|
|
}
|
|
dc->sxdXmlStyle = sxdXmlStyle;
|
|
if (dc->sxdXmlStyle == SXD_XML_STYLE_V)
|
|
dc->checkDt = checkDt;
|
|
else
|
|
dc->checkDt = SD_FALSE;
|
|
|
|
dc->xmlDest = xml;
|
|
dc->xmlPos = xml;
|
|
dc->xmlBufEnd = xml + xmlLen;
|
|
dc->xmlDecResult = SD_SUCCESS;
|
|
dc->outerElement = elName;
|
|
|
|
arr_loop_level = 0;
|
|
memset (arr_loops, 0, sizeof (arr_loops));
|
|
|
|
rt_ptr = (RUNTIME_TYPE *) rt_head; /* point to head rt_block */
|
|
rt_end = rt_ptr + rt_num; /* done when pointer is here */
|
|
|
|
/* Here we will work our way through the XML and the runtime type */
|
|
|
|
uDataRet = SD_SUCCESS;
|
|
structPrefix[0] = 0;
|
|
structNestLevel = 0;
|
|
|
|
while ((dc->xmlPos < dc->xmlBufEnd) && (rt_ptr < rt_end) &&
|
|
uDataRet == SD_SUCCESS)
|
|
{
|
|
/* Position to the opening '<' */
|
|
if (dc->sxdXmlStyle == SXD_XML_STYLE_C ||
|
|
dc->sxdXmlStyle == SXD_XML_STYLE_V)
|
|
{
|
|
while (*dc->xmlPos != '<' && dc->xmlPos < dc->xmlBufEnd)
|
|
++dc->xmlPos;
|
|
}
|
|
if (dc->xmlPos >= dc->xmlBufEnd)
|
|
{
|
|
M_FREE (NULL, dc);
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/* Decode the next XML data element */
|
|
if (dc->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
rc = _sxdDecElementA (dc);
|
|
else if (dc->sxdXmlStyle == SXD_XML_STYLE_C)
|
|
rc = _sxdDecElementC (dc);
|
|
else if (dc->sxdXmlStyle == SXD_XML_STYLE_V)
|
|
rc = _sxdDecElementV (dc);
|
|
else
|
|
rc = SD_FAILURE; /* invalid style */
|
|
|
|
if (rc != SD_SUCCESS)
|
|
{
|
|
M_FREE (NULL, dc);
|
|
return (rc);
|
|
}
|
|
|
|
/* If we reached the end of the element for style A, we are done */
|
|
if (dc->endEl == SD_TRUE && dc->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
if (dc->outerElement && elPres != NULL)
|
|
elPres[rt_num-1] = SD_TRUE;
|
|
|
|
break;
|
|
}
|
|
|
|
/* Note1: The processing is different for plain array and different */
|
|
/* for array of structures when they are decoded. */
|
|
/* In the case of plain array the function sxdDecElementX */
|
|
/* will return the decoded array element (no start or end */
|
|
/* array element tag). */
|
|
/* In the case of array of structures the fun sxdDecElementX */
|
|
/* will return first the start of array element tag, then */
|
|
/* the decoded array element (x struct fields), and at the */
|
|
/* end we get the array element end tag. */
|
|
/* Note2: Arrays are not supported in SXD_XML_STYLE_A because the */
|
|
/* attributes must have unique names. */
|
|
|
|
plain_array = SD_FALSE;
|
|
set_arr_start = SD_FALSE;
|
|
set_arr_end = SD_FALSE;
|
|
|
|
/* OK, we need to find the RT that has the name */
|
|
while (rt_ptr < rt_end && uDataRet == SD_SUCCESS)
|
|
{
|
|
elName = NULL;
|
|
|
|
if (rt_ptr->el_tag == RT_STR_START) /* treat case of struct start */
|
|
{
|
|
/*--------------------------------------------------------------*/
|
|
if (ms_comp_name_pres(rt_ptr) == SD_TRUE)
|
|
{
|
|
elName = ms_comp_name_find(rt_ptr);
|
|
if (dc->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
strcat (structPrefix, elName);
|
|
strcat (structPrefix, ".");
|
|
if (strncmp (dc->elName, structPrefix, strlen(structPrefix)) == 0)
|
|
{
|
|
++structNestLevel;
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
/* wrong struct, need to skip this struct in rt tbl */
|
|
_sxdStripPrefix (structPrefix); /* restore the prefix */
|
|
}
|
|
}
|
|
}
|
|
if (elName != NULL)
|
|
{
|
|
/* Check to see if we found the associated RUNTIME element */
|
|
if (strcmp (dc->elName, elName) == 0)
|
|
break; /* struct name matches, process it */
|
|
else
|
|
{
|
|
/* dc->elName does not match, need to skip this struct in rt tbl */
|
|
cnt = rt_ptr->u.str.num_rt_blks + 2; /* 2 for str start, end */
|
|
for (j=0; j<cnt; ++j)
|
|
{
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_FALSE);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* elName is NULL only in the case of array of structures */
|
|
if (arr_loop_level > 0)
|
|
{
|
|
/* array of structs, advance to next rt */
|
|
uDataRet = _sxdDecStrStart (dc, rt_ptr);/* normally called from switch */
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
continue; /* continue processing of the array element */
|
|
}
|
|
else
|
|
{
|
|
/* must be the XML wrapper */
|
|
elName = dc->outerElement;
|
|
if (elName == NULL)
|
|
/* can't compare the wrapper name, assume it is OK */
|
|
break;
|
|
else
|
|
{
|
|
if (strcmp (dc->elName, elName) == 0)
|
|
break; /* process the wrapper */
|
|
else
|
|
{
|
|
/* wrong XML ? */
|
|
SXLOG_NERR2 ("Could not find XML wrapper '%s' (found '%s')", dc->elName, elName);
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (rt_ptr->el_tag == RT_STR_END) /* treat case of struct end */
|
|
{
|
|
/*--------------------------------------------------------------*/
|
|
if (dc->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
/* need to strip name of last struct level */
|
|
_sxdStripPrefix (structPrefix);
|
|
--structNestLevel;
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
/* get the struct name from the RT_STR_START rt */
|
|
rt_tmp = rt_ptr - (rt_ptr->u.str.num_rt_blks + 1);
|
|
if (ms_comp_name_pres(rt_tmp) == SD_TRUE)
|
|
elName = ms_comp_name_find(rt_tmp);
|
|
}
|
|
if (elName != NULL)
|
|
{
|
|
/* Check to see if we found the associated RUNTIME element */
|
|
if (strcmp (dc->elName, elName) == 0)
|
|
break; /* struct name matches, process end */
|
|
}
|
|
else
|
|
{
|
|
/* elName maybe NULL in the case of array of structures */
|
|
if (arr_loop_level > 0)
|
|
{
|
|
/* this is an array of structs, advance to next rt (but not to next decoded element)*/
|
|
uDataRet = _sxdDecStrEnd (dc, rt_ptr);/* normally called from switch */
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
continue; /* continue processing of the array element */
|
|
}
|
|
else
|
|
{
|
|
/* this may be the wrapper end */
|
|
elName = dc->outerElement;
|
|
if (elName == NULL)
|
|
/* can't compare the wrapper name, assume it is OK */
|
|
break;
|
|
else
|
|
{
|
|
if (strcmp (dc->elName, elName) == 0)
|
|
break; /* process the wrapper */
|
|
else
|
|
{
|
|
/* wrong XML ? */
|
|
SXLOG_NERR2 ("Could not find XML end wrapper tag '%s' (found '%s')", dc->elName, elName);
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (rt_ptr->el_tag == RT_ARR_START) /* treat case of array element starting */
|
|
{
|
|
/*--------------------------------------------------------------*/
|
|
/* check if the start tag of array element matches dc->elName */
|
|
/* before setting loop level */
|
|
if (ms_comp_name_pres(rt_ptr) == SD_TRUE)
|
|
elName = ms_comp_name_find(rt_ptr);
|
|
if (strcmp (dc->elName, elName) == 0)
|
|
{
|
|
if (arr_loop_level == 0) /* set only one time per array */
|
|
{
|
|
rt_tmp = rt_ptr;
|
|
while (rt_tmp->el_tag == RT_ARR_START)
|
|
{
|
|
++arr_loop_level;
|
|
arr_loops[arr_loop_level] = rt_tmp->u.arr.num_elmnts;
|
|
++rt_tmp;
|
|
}
|
|
}
|
|
/* array may be multidimentional, skip to the last RT_ARR_START */
|
|
while ((rt_ptr+1)->el_tag == RT_ARR_START)
|
|
{
|
|
uDataRet = _sxdDecArrStart (dc, rt_ptr); /* normally called from switch */
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
}
|
|
|
|
/* if it is array of structs, processing is different */
|
|
if ((rt_ptr+1)->el_tag == RT_STR_START)
|
|
/* array of structs */
|
|
break;
|
|
else
|
|
{
|
|
/* plain array, adjust ptrs and go to next rt */
|
|
plain_array = SD_TRUE;
|
|
uDataRet = _sxdDecArrStart (dc, rt_ptr);/* normally called from switch */
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
continue;
|
|
}
|
|
}
|
|
/* dc->elName does not match, need to skip this array in rt tbl */
|
|
cnt = rt_ptr->u.arr.num_rt_blks + 2; /* 2 for arr start, end */
|
|
for (j=0; j<cnt; ++j)
|
|
{
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_FALSE);
|
|
}
|
|
continue; /* continue searching for the dc->elName in rt tbl */
|
|
}
|
|
else if (rt_ptr->el_tag == RT_ARR_END) /* treat case of array element ending */
|
|
{
|
|
/*--------------------------------------------------------------*/
|
|
/* we get here only in the case of array of structures */
|
|
/* get the array name from the first RT_ARR_START rt (maybe nested) */
|
|
rt_tmp = rt_ptr - (rt_ptr->u.arr.num_rt_blks + 1);
|
|
while (ms_comp_name_pres(rt_tmp) != SD_TRUE && rt_tmp->el_tag == RT_ARR_START)
|
|
--rt_tmp;
|
|
elName = "UNKNOWN";
|
|
if (ms_comp_name_pres(rt_tmp) == SD_TRUE)
|
|
elName = ms_comp_name_find(rt_tmp);
|
|
|
|
/* check if the end tag of an array element is correct */
|
|
if (strcmp (dc->elName, elName) != 0)
|
|
{
|
|
/* invalid end tag for the array element, quit decoding */
|
|
SXLOG_NERR2 ("Could not find array element end tag '%s' (found '%s')", elName, dc->elName);
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
}
|
|
if (--arr_loops[arr_loop_level] > 0) /* if need next ar elmnt */
|
|
{
|
|
/* there should be more array elements to process, need to */
|
|
/* reset the rt to the beginning of the array */
|
|
set_arr_start = SD_TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* all array elements processed, decrement loop level */
|
|
--arr_loop_level;
|
|
if (arr_loops[arr_loop_level] > 0)
|
|
set_arr_start = SD_TRUE; /* more elements to process */
|
|
else
|
|
{
|
|
/* advance to last RT_ARR_END (if multidimentional array) */
|
|
while ((rt_ptr+1)->el_tag == RT_ARR_END)
|
|
{
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
/*--------------------------------------------------------------*/
|
|
/* struct field or array element */
|
|
if (ms_comp_name_pres(rt_ptr) == SD_TRUE)
|
|
{
|
|
elName = ms_comp_name_find(rt_ptr);
|
|
if (dc->sxdXmlStyle == SXD_XML_STYLE_A)
|
|
{
|
|
strcpy (nameBuf, structPrefix);
|
|
strcat (nameBuf, elName);
|
|
if (strcmp (dc->elName, nameBuf) == 0)
|
|
break; /* found element name, process it */
|
|
else
|
|
{
|
|
/* not name we search for, skip it */
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_FALSE);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (elName != NULL)
|
|
{
|
|
if (strcmp (dc->elName, elName) == 0)
|
|
break; /* found element name, process it */
|
|
else
|
|
{
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_FALSE);
|
|
continue; /* continue looking for the dc->elName */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* elName maybe NULL in the case of an array element (plain array) */
|
|
if (plain_array)
|
|
{
|
|
/* since no array element end tag will be decoded, we need */
|
|
/* to handle this case here */
|
|
if (--arr_loops[arr_loop_level] > 0) /* if need next ar elmnt */
|
|
{
|
|
/* there should be more array elements to process, need to */
|
|
/* reset the rt to the beginning of the array */
|
|
set_arr_start = SD_TRUE;
|
|
}
|
|
else
|
|
{
|
|
/* all array elements processed, decrement loop level */
|
|
--arr_loop_level;
|
|
if (arr_loops[arr_loop_level] > 0)
|
|
set_arr_start = SD_TRUE; /* more elements to process */
|
|
else
|
|
set_arr_end = SD_TRUE; /* end of array */
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
SXLOG_NERR1 ("Could not find tag '%s' (found 'NULL')", dc->elName);
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* !!! if we get here some 'if-else' is not handled! return error */
|
|
SXLOG_NERR0 ("Unhandled code, returning from function sxd_decode_rtdata_el.");
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
} /* end of inner while loop */
|
|
|
|
if (rt_ptr >= rt_end || uDataRet != SD_SUCCESS)
|
|
{
|
|
SXLOG_NERR1 ("Could not find RT for element name %s", dc->elName);
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
}
|
|
|
|
/* We found a RUNTIME element that matches the XML name */
|
|
|
|
if (1 || dc->dataEl == SD_TRUE)
|
|
{
|
|
switch (rt_ptr->el_tag)
|
|
{
|
|
case RT_ARR_START :
|
|
uDataRet = _sxdDecArrStart (dc, rt_ptr);
|
|
break;
|
|
|
|
case RT_STR_START :
|
|
uDataRet = _sxdDecStrStart (dc, rt_ptr);
|
|
break;
|
|
|
|
case RT_ARR_END : /* array done */
|
|
uDataRet = _sxdDecArrEnd (dc, rt_ptr);
|
|
break;
|
|
|
|
case RT_STR_END : /* structure done */
|
|
uDataRet = _sxdDecStrEnd (dc, rt_ptr);
|
|
break;
|
|
|
|
case RT_BOOL :
|
|
uDataRet = _sxdDecBool (dc, (ST_BOOLEAN *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_BIT_STRING :
|
|
uDataRet = _sxdDecBs (dc, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_INTEGER :
|
|
switch (rt_ptr->u.p.el_len) /* determine length */
|
|
{
|
|
case 1 : /* one byte int */
|
|
uDataRet = _sxdDecInt8 (dc, (ST_INT8 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 2 : /* two byte int */
|
|
uDataRet = _sxdDecInt16 (dc, (ST_INT16 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 4 : /* four byte integer */
|
|
uDataRet = _sxdDecInt32 (dc, (ST_INT32 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
#ifdef INT64_SUPPORT
|
|
case 8 : /* eight byte integer */
|
|
uDataRet = _sxdDecInt64 (dc, (ST_INT64 *) datptr, rt_ptr);
|
|
break;
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case RT_UNSIGNED :
|
|
switch (rt_ptr->u.p.el_len) /* determine length */
|
|
{
|
|
case 1 : /* one byte int */
|
|
uDataRet = _sxdDecUint8 (dc, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 2 : /* two byte int */
|
|
uDataRet = _sxdDecUint16 (dc, (ST_UINT16 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case 4 : /* four byte integer */
|
|
uDataRet = _sxdDecUint32 (dc, (ST_UINT32 *) datptr, rt_ptr);
|
|
break;
|
|
|
|
#ifdef INT64_SUPPORT
|
|
case 8 : /* eight byte integer */
|
|
uDataRet = _sxdDecUint64 (dc, (ST_UINT64 *) datptr, rt_ptr);
|
|
break;
|
|
#endif /* INT64_SUPPORT */
|
|
}
|
|
break;
|
|
|
|
#ifdef FLOAT_DATA_SUPPORT
|
|
case RT_FLOATING_POINT :
|
|
if (rt_ptr->u.p.el_len != sizeof (ST_FLOAT))
|
|
{
|
|
uDataRet = _sxdDecDbl (dc, (ST_DOUBLE *) datptr, rt_ptr);
|
|
}
|
|
else
|
|
{
|
|
uDataRet = _sxdDecFlt (dc, (ST_FLOAT *) datptr, rt_ptr);
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case RT_OCTET_STRING :
|
|
uDataRet = _sxdDecOct (dc, (ST_UCHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
case RT_VISIBLE_STRING :
|
|
uDataRet = _sxdDecVis (dc, (ST_CHAR *) datptr, rt_ptr);
|
|
break;
|
|
|
|
#ifdef TIME_DATA_SUPPORT
|
|
case RT_GENERAL_TIME :
|
|
uDataRet = _sxdDecGt (dc, (time_t *) datptr, rt_ptr);
|
|
break;
|
|
#endif
|
|
|
|
#ifdef BTOD_DATA_SUPPORT
|
|
case RT_BINARY_TIME :
|
|
switch (rt_ptr->u.p.el_len) /* determine length */
|
|
{
|
|
case 4:
|
|
uDataRet = _sxdDecBt4 (dc, (ST_INT32 *) datptr, rt_ptr);
|
|
break;
|
|
case 6:
|
|
uDataRet = _sxdDecBt6 (dc, (ST_INT32 *) datptr, rt_ptr);
|
|
break;
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
case RT_BCD :
|
|
if (rt_ptr->u.p.el_len <= 2)
|
|
{
|
|
uDataRet = _sxdDecBcd1 (dc, (ST_INT8 *) datptr, rt_ptr);
|
|
}
|
|
else if (rt_ptr->u.p.el_len <= 4)
|
|
{
|
|
uDataRet = _sxdDecBcd2 (dc, (ST_INT16 *) datptr, rt_ptr);
|
|
}
|
|
else if (rt_ptr->u.p.el_len <= 8)
|
|
{
|
|
uDataRet = _sxdDecBcd4 (dc, (ST_INT32 *) datptr, rt_ptr);
|
|
}
|
|
break;
|
|
|
|
default : /* should not be any other tag */
|
|
SXLOG_ERR1 ("Invalid tag: %d", (int) rt_ptr->el_tag);
|
|
M_FREE (NULL, dc);
|
|
return (SD_FAILURE);
|
|
break;
|
|
}
|
|
|
|
/* Set the element present flag for this element to TRUE */
|
|
if (elPres != NULL)
|
|
elPres[rt_ptr - rt_head] = SD_TRUE;
|
|
datptr += rt_ptr->el_size; /* Adjust data pointer */
|
|
|
|
if (set_arr_start)
|
|
{
|
|
if (plain_array)
|
|
--rt_ptr; /* rt_ptr to arr start */
|
|
else
|
|
rt_ptr -= rt_ptr->u.arr.num_rt_blks + 1; /* rt_ptr to arr start */
|
|
while ((rt_ptr-1)->el_tag == RT_ARR_START) /* if multidimensional */
|
|
--rt_ptr; /* go to first level */
|
|
}
|
|
else if (set_arr_end)
|
|
{
|
|
rt_ptr++;
|
|
/* if multidimensional array, pass the last RT_ARR_END */
|
|
while ((rt_ptr)->el_tag == RT_ARR_END)
|
|
{
|
|
_SXD_ADVANCE_PTR(rt_ptr, SD_TRUE);
|
|
}
|
|
}
|
|
else
|
|
rt_ptr++; /* point to next rt elmt*/
|
|
} /* if (1 || ...) */
|
|
} /* end of outher while loop */
|
|
*xmlUsed = dc->xmlPos - xml;
|
|
M_FREE (NULL, dc);
|
|
return (uDataRet);
|
|
}
|
|
|