自主协议库编译通过

This commit is contained in:
lnk
2026-06-15 15:48:16 +08:00
parent d3579a2aa7
commit 7205cb5cb9
621 changed files with 224958 additions and 48 deletions

572
mmslib/asn1/ard_flt.c Normal file
View File

@@ -0,0 +1,572 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1986 - 2001, All Rights Reserved. */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : ard_float.c */
/* PRODUCT(S) : ASN1DE */
/* */
/* MODULE DESCRIPTION : */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 10/03/08 JRB 08 Make sure elmnt_len is legal. */
/* 03/11/04 GLB 07 Remove "thisFileName" */
/* 02/19/03 JRB 06 Use SD_BYTE_ORDER. */
/* 02/19/03 JRB 05 Del VAX VMS support. For ALPHA VMS, assume */
/* compiler option /FLOAT=IEEE_FLOAT is used */
/* so it behaves like other systems. */
/* 03/05/02 JRB 04 Eliminate warnings. */
/* 12/20/01 JRB 03 Chg ASN1_CTXT to ASN1_DEC_CTXT. */
/* 09/13/99 MDE 02 Added SD_CONST modifiers */
/* 07/26/99 MDE 01 New module, derived from ad_float.c */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "asn1r.h"
#include "asn1log.h"
/************************************************************************/
/* 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
#ifdef ASN1_ARB_FLOAT
static ST_INT16 _fp_common (ASN1_DEC_CTXT *ac, ST_INT16 *sign, ST_UINT16 *exp, ST_UCHAR *lptr,
ST_INT16 *m, ST_UCHAR *next, ST_INT16 doubl_prec);
#endif
/************************************************************************/
/************************************************************************/
/* get_float */
/* Function to convert the MMS floating point type in the ASN.1 message */
/* stream to the single precision "float" type of the C programming */
/* language. This function will handle any size mantissa (which is */
/* rounded to fit into the local single precision floating point format)*/
/* and any size exponent width up to 15 bits. Exponents too large or */
/* small for the local representation translate into + or - infinity or */
/* zero, as the case may be. The return codes are: */
/* */
/* 0 - finite valid floating pt # decoded successfully */
/* 1 - invalid floating point number */
/* 2 - exponent length greater than 15 */
/* -1 - floating point value = NaN */
/* -2 - floating point value = + infinity */
/* -3 - floating point value = - infinity */
/* */
/************************************************************************/
ST_RET asn1r_get_float (ASN1_DEC_CTXT *ac, ST_FLOAT *out)
{
ST_UCHAR n; /* length of the exponent part */
ST_UCHAR *ptr; /* char ptr to output float variable out*/
ST_UCHAR *next; /* points to next data element */
ST_UCHAR *original_asn1_field_ptr;
ST_BOOLEAN float_is_zero;
#ifdef ASN1_ARB_FLOAT
ST_UINT16 exp; /* local variable to hold exponent part */
ST_INT i; /* utility variable */
ST_INT16 sign; /* sign of the floating point quantity */
ST_INT32 signexp; /* contains sign and exp parts of out */
ST_INT16 m; /* # of fract bits in 1st 2 exp octets */
ST_UINT32 *fract; /* contains fraction part of out */
#endif
#ifdef DEBUG_ASN1_DECODE
if (!out)
{
slogCallStack (sLogCtrl,
"get_float: attempt to reference through a NULL pointer");
return(SD_FAILURE);
}
#endif
/* MMS spec says FloatingPoint must be at least 2 octets */
if (ac->asn1r_elmnt_len < 2)
{
ALOG_ERR0 ("ASN.1 decode: length < 2 not allowed for FloatingPoint");
return (SD_FAILURE);
}
next = ac->asn1r_field_ptr + ac->asn1r_elmnt_len;
n = (ST_UCHAR) *(ac->asn1r_field_ptr++); /* read exponent width */
/* check to see if all the octets are 0 */
original_asn1_field_ptr = ac->asn1r_field_ptr;
float_is_zero = SD_TRUE; /* assume the float = 0 */
while(ac->asn1r_field_ptr < next)
{
if (*(ac->asn1r_field_ptr++) != 0)
{
float_is_zero = SD_FALSE;
break;
}
}
if (float_is_zero)
{
ac->asn1r_field_ptr = next;
*out = (ST_FLOAT)0; /* this float = 0 */
return(SD_SUCCESS); /* return success */
}
else
ac->asn1r_field_ptr = original_asn1_field_ptr;
ptr = (ST_UCHAR *) out;
/* Treat case where MMS floating point format coincides with IEEE 754. */
if (ac->asn1r_elmnt_len == 5 && n == 8)
{
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
#else
ac->asn1r_field_ptr += 3;
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
#endif
*ptr = (ST_UCHAR) *ac->asn1r_field_ptr;
ac->asn1r_field_ptr = next;
return (SD_SUCCESS);
}
#ifdef ASN1_ARB_FLOAT
/* Otherwise, convert arbitrary MMS floating point into local single- */
/* precision floating point. */
/* Get exponent and sign information, and read in the fraction part of */
/* the floating point number. */
m = 15 - (ST_INT16)n;
if ((i = _fp_common (ac,&sign,&exp,ptr,&m,next,SD_FALSE)) < 3)
{
*out = (ST_FLOAT)0;
return ((ST_INT16) i);
}
/* Shift fraction part to bottom 3 bytes, add 1, and then shift one */
/* more byte. This rounds fraction to local precision and places it */
/* nine bits into the floating point number, where it's supposed to go. */
fract = (ST_UINT32 *) out;
*fract = (*fract>>m) & (ST_UINT32)0x00FFFFFFL;
*fract = (*fract + (ST_UINT32)0x00000001L) >> 1; /* add 1 and then shift */
if (*fract & (ST_UINT32)0x00800000L)
{ /* rounding may cause */
exp++; /* exponent to increment*/
*fract &= (ST_UINT32)0x007FFFFFL;
}
/* OR the sign, exponent and fraction parts together to make a valid */
/* local floating point value. */
exp <<= 7; /* ready to be ORed with other parts */
signexp = ((ST_INT32) exp) << 16;
if (sign < 0)
signexp |= 0x80000000L;
*fract |= (ST_UINT32)signexp;
/* Return to calling routine with success indicated. */
return (SD_SUCCESS);
#else /* No arbitrary float format support */
return (SD_FAILURE);
#endif
}
/************************************************************************/
/* get_double */
/* Function to convert the MMS floating point type in the ASN.1 message */
/* stream to the double precision "double" type of the C programming */
/* language. This function will handle any size mantissa (which is */
/* rounded to fit into the local double precision floating point format)*/
/* and any size exponent width up to 15 bits. Exponents too large or */
/* small for the local representation translate into + or - infinity or */
/* zero, as the case may be. The return codes are: */
/* */
/* 0 - finite valid floating pt # decoded successfully */
/* 1 - invalid floating point number */
/* 2 - exponent length greater than 15 */
/* -1 - floating point value = NaN */
/* -2 - floating point value = + infinity */
/* -3 - floating point value = - infinity */
/* */
/************************************************************************/
ST_RET asn1r_get_double (ASN1_DEC_CTXT *ac, ST_DOUBLE *out)
{
ST_UCHAR n; /* length of the exponent part */
ST_UCHAR *ptr; /* char ptr to the out variable */
ST_UCHAR *next; /* points to next data element */
ST_UINT32 *h_ulong;
ST_UINT32 *l_ulong;
ST_UCHAR *original_asn1_field_ptr;
ST_BOOLEAN float_is_zero;
#ifdef ASN1_ARB_FLOAT
ST_INT garbage_bits_in_mantissa;
ST_UCHAR round; /* flag indicating rounding, not trunc. */
ST_UINT32 temp; /* utility variable */
ST_UINT16 exp; /* value of exponent (biased) */
ST_INT i; /* utility variable */
ST_UINT32 signexp; /* contains sign and exp parts of out */
ST_INT16 sign; /* sign of the floating point quantity */
ST_INT16 m; /* # of fract bits in 1st fract octet */
ST_INT16 local_double_exp_width; /* The local exp width of native double */
ST_UINT32 *fract; /* points to fraction part of out */
#endif
#ifdef DEBUG_ASN1_DECODE
if (!out)
{
slogCallStack (sLogCtrl,
"get_double: attempt to reference through a NULL pointer");
return(SD_FAILURE);
}
#endif
next = ac->asn1r_field_ptr + ac->asn1r_elmnt_len;
n = (ST_UCHAR) *(ac->asn1r_field_ptr++); /* read exponent width */
/* check to see if all the octets are 0 */
original_asn1_field_ptr = ac->asn1r_field_ptr;
float_is_zero = SD_TRUE; /* assume the float = 0 */
while(ac->asn1r_field_ptr < next)
{
if (*(ac->asn1r_field_ptr++) != 0)
{
float_is_zero = SD_FALSE;
break;
}
}
if (float_is_zero)
{
ac->asn1r_field_ptr = next;
*out = (ST_FLOAT)0; /* this float = 0 */
return(SD_SUCCESS); /* return success */
}
else
ac->asn1r_field_ptr = original_asn1_field_ptr;
ptr = (ST_UCHAR *) out;
h_ulong = (ST_UINT32 *) out;
l_ulong = h_ulong + 1;
/* Treat case where MMS floating point format coincides with IEEE 754 */
/* double precision floating point format. */
if (ac->asn1r_elmnt_len == 9 && n == 11)
{
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
#else
ac->asn1r_field_ptr += 7;
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
*(ptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
#endif
*ptr = (ST_UCHAR) *ac->asn1r_field_ptr;
ac->asn1r_field_ptr = next;
return (SD_SUCCESS);
}
#ifdef ASN1_ARB_FLOAT
/* Otherwise, convert arbitrary MMS floating point into local single- */
/* precision floating point. */
/* Get exponent and sign information, and read in the fraction part of */
/* the floating point number. */
m = 15 - (ST_INT16)n;
if ((i = _fp_common (ac,&sign,&exp,ptr,&m,next,SD_TRUE)) < 3)
{
*out = (ST_DOUBLE)0;
return ((ST_INT16) i);
}
/* The number of bits used to store the exponent of a double precision */
/* floating point number varies from machine to machine. The following */
/* piece of code sets this local exponent width. */
/* Assume all systems now use IEEE 754 format */
local_double_exp_width = 11;
/* The following piece of code calculates the number of bit positions */
/* to shift the fraction bits in the mantissa. */
/* (local_exp_width + sign width) - (non_mantisa_bits) */
garbage_bits_in_mantissa = 8 - m; /* num of garb bits in mantissa */
i = (local_double_exp_width + 1) - garbage_bits_in_mantissa;
/* was i = m + 4 */
fract = (ST_UINT32 *) out;
#if SD_BYTE_ORDER==SD_LITTLE_ENDIAN /* little-endian (like Intel) */
fract++; /* high half of f.p. */
#endif
/* save lowest i bits that will be lost when positioning the fraction */
temp =((0x00000001L << (local_double_exp_width + 1)) - 1L);
temp = *fract & (temp >> garbage_bits_in_mantissa);
*fract <<= garbage_bits_in_mantissa; /* put fract at far left*/
*fract >>= (local_double_exp_width + 1); /* shift fract in place */
/* grt rid of any sign and exponent */
*fract &= 0x000fffff; /* other ports have 12 */
/* pt at low half of fp */
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
fract++;
#else
fract--;
#endif
*fract >>= (i-1); /* low half of f.p. */
if (*fract & (ST_UINT32)0x00000001L)
round = SD_TRUE;
else
round = SD_FALSE;
temp <<= (32-i);
*fract = (*fract>>1) | temp; /* OR with bits from top half */
/* Round off the fraction part to fit into the local 8-byte double- */
/* precision floating point number. */
if (round)
{ /* if low half is all 1's, then */
if (*fract == 0xFFFFFFFF) /* rounding affects hi half too */
{
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
*(fract--) = 0;
#else
*(fract++) = 0;
#endif
*fract += 1;
if (*fract & (ST_UINT32)0xFFF00000L) /* if adding one overflows into */
{ /* exp part, increment exponent */
exp += 1;
*fract &= (ST_UINT32)0x000FFFFFL;
}
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
fract++; /* end up pointing to low half */
#else
fract--; /* end up pointing to low half */
#endif
}
else
*fract += 1;
}
/* OR the sign, exponent and (high) fraction parts together to make a */
/* valid local floating point value. */
exp <<= 4; /* ready to be ORed with other parts */
signexp = (ST_UINT32)exp << 16;
if (sign < 0)
signexp |= (ST_UINT32)0x80000000L;
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
*(--fract) |= signexp;
#else
*(++fract) |= signexp;
#endif
/* Return to calling routine with success indicated. */
return (SD_SUCCESS);
#else
return (SD_FAILURE);
#endif
}
/************************************************************************/
/* _fp_common */
/* Function to read the sign, exp, and fract parts of an MMS floating */
/* point type into the designated arguments. This function represents */
/* the common logic of the two functions: get_float and get_double. */
/* Besides sign, exp, and fract, there are three other outputs from */
/* this function: */
/* asn1_field_ptr - global variable set to next data element in msg */
/* m - modified in this function to be the number of fraction bits */
/* in the 1st octet containing any fraction bits */
/* return value - 0 - valid floating pt # with value of 0 */
/* 1 - invalid floating point number */
/* 2 - exponent length greater than 15 */
/* 3 - valid, nonzero, finite floating pt # */
/* -1 - floating point value = NaN */
/* -2 - floating point value = + infinity */
/* -3 - floating point value = - infinity */
/************************************************************************/
#ifdef ASN1_ARB_FLOAT
static ST_INT16 _fp_common (
ASN1_DEC_CTXT *ac, /* ASN1 context pointer */
ST_INT16 *sign, /* sign */
ST_UINT16 *exp, /* exponent translated to local repr'n */
ST_UCHAR *lptr, /* pointer to local f.p. # */
ST_INT16 *m, /* begins as # of fract bits in 1st two */
/* octets, modified in this function */
ST_UCHAR *next, /* pointer to next data element */
ST_INT16 doubl_prec) /* local precision - single or double */
{
ST_INT16 lbias; /* bias of local floating point type */
ST_UINT16 lmaxexp; /* max exponent of local f.p. type */
ST_INT16 lfract; /* local precision length in bytes */
ST_UINT16 bias; /* bias for MMS f.p. type being decoded */
ST_UCHAR nonzero; /* flag indicating if fract part is !=0 */
ST_INT i; /* utility variable */
ST_UINT16 temp1; /* utility variable */
ST_UCHAR temp2; /* utility variable */
/* Initialize variables dependent on the precision of the local f.p. */
/* representation (either single or double). */
if (doubl_prec)
{
lbias = 1023;
lmaxexp = 2047;
lfract = 7;
}
else
{
lbias = 127;
lmaxexp = 255;
lfract = 3;
}
/* First, check size of exponent and fraction parts based on element */
/* length and number of fraction bits in 1st two bytes. */
if (ac->asn1r_elmnt_len < 3) /* must have minimum of */
{ /* 2 bytes for f.p. # */
ac->asn1r_field_ptr = next;
return (SD_FAILURE);
}
if (*m < 0) /* exp part too big */
{
ac->asn1r_field_ptr = next;
return (2);
}
if (*m >= 15) /* exp part too small */
{
ac->asn1r_field_ptr = next;
return (SD_FAILURE);
}
/* Move exponent and sign parts into *exp variable for manipulation. */
temp1 = ((ST_UINT16) *(ac->asn1r_field_ptr++)) << 8;
*exp = temp1 | ((ST_UINT16) *(ac->asn1r_field_ptr++) & (ST_UINT16)0x00ff);
/* Determine sign, and mask out. */
if (*exp & (ST_UINT16)0x8000)
{
*sign = -1;
*exp = *exp & (ST_UINT16)0x7FFF; /* zero sign bit */
}
else
*sign = 1;
/* Reset asn1_field_ptr to point to 1st octet containing any fraction bits. */
if (*m > 8)
ac->asn1r_field_ptr -= 2;
else if (*m > 0)
ac->asn1r_field_ptr--;
/* Calculate bias of MMS floating point number before m is changed. */
bias = (ST_UINT16)0x7FFF >> (*m+1); /* bias = 2**(n-1) - 1 */
/* Determine if exponent part is all 1's. In this case, MMS float = NaN */
/* or infinity, so return with appropriate return code. */
*exp = *exp >> *m; /* get rid of fract bits on right */
temp1 = (ST_UINT16)0x7FFF >> *m; /* prepare comparison bytes */
*m = *m%8;
if (*m == 0)
*m = 8; /* m = # fract bits in current octet */
if (*exp == temp1) /* check for all 1's in exponent */
{
nonzero = SD_FALSE; /* now check for all 0's in fraction */
temp2 = (ST_UCHAR) (*(ac->asn1r_field_ptr++) & ~(0xFF<<*m));
while (ac->asn1r_field_ptr <= next) /* if all fract bits = */
{ /* 0, then we have a + */
if (temp2) /* or - infinity */
{
nonzero = SD_TRUE;
break;
}
temp2 = (ST_UCHAR) *(ac->asn1r_field_ptr++);
}
ac->asn1r_field_ptr = next;
if (nonzero)
return (-1); /* nonzero fract => NaN */
else if (*sign > 0)
return (-2); /* case of + infinity */
else
return (-3); /* case of - infinity */
}
/* Now that we know MMS float is a valid finite value, translate its */
/* exponent part into the exponent for the local representation. */
if ((i = (ST_INT16)*exp + lbias - (ST_INT16)bias) < 0)
return (SD_SUCCESS); /* Value too small to represent locally.*/
*exp = (ST_UINT16) i;
if (*exp > lmaxexp) /* biased local exp */
{ /* value too big to */
ac->asn1r_field_ptr = next; /* represent locally - */
if (*sign > 0) /* treat as + or - inf */
return (-2);
else
return (-3);
}
/* Move fraction part into local variable. */
#if SD_BYTE_ORDER==SD_BIG_ENDIAN /* big-endian (like Motorola) */
for (i=0;i<lfract;i++)
{
if (ac->asn1r_field_ptr < next)
*(lptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr++);
else
{
*(lptr++) = (ST_UCHAR) 0; /* zero fill if local precision */
}
}
#else
ac->asn1r_field_ptr += lfract;
for (i=0;i<lfract;i++)
{
if (ac->asn1r_field_ptr < next)
*(lptr++) = (ST_UCHAR) *(ac->asn1r_field_ptr--);
else
{
*(lptr++) = (ST_UCHAR) 0; /* zero fill if local precision */
ac->asn1r_field_ptr--; /* is greater than MMS f.p. */
}
}
*lptr = (ST_UCHAR) *ac->asn1r_field_ptr; /* we know last byte < next */
#endif
ac->asn1r_field_ptr = next;
return (3); /* normal case */
}
#endif /* end of ARB FLOAT support */